Implemented force install
[spkg.git] / src / sys.c
blob2f20861f4eede3c0ae27684cfc9142f9b6fe9532
1 /*----------------------------------------------------------------------*\
2 |* spkg - The Unofficial Slackware Linux Package Manager *|
3 |* designed by Ondøej Jirman, 2005 *|
4 |*----------------------------------------------------------------------*|
5 |* No copy/usage restrictions are imposed on anybody. *|
6 \*----------------------------------------------------------------------*/
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <sys/file.h>
10 #include <errno.h>
11 #include <dirent.h>
12 #include <unistd.h>
13 #include <string.h>
15 #include "sys.h"
16 #include "path.h"
17 #include "misc.h"
19 #ifdef __WIN32__
20 #include <windows.h>
21 //#include <pthread.h>
22 #include "win32/flock.h"
24 #ifndef EWOULDBLOCK
25 #define EWOULDBLOCK EAGAIN
26 #endif
28 #define S_ISLNK(m) (0)
29 #define S_ISSOCK(m) 0
31 #define lstat(x,y) stat(x,y)
33 int sigfillset(sigset_t *set) { *set = ~(sigset_t)0; return 0; }
35 int usleep(unsigned int usec)
37 unsigned int dwMilliseconds = usec/1000;
38 if (dwMilliseconds > 0)
40 Sleep (dwMilliseconds);
42 return (0);
45 #endif
47 #define e_set(e, n, fmt, args...) e_add(e, "sys", __func__, n, fmt, ##args)
49 sys_ftype sys_file_type_stat(const gchar* path, gboolean deref, struct stat* s)
51 g_assert(path != 0);
52 struct stat st;
53 gint rs;
54 if (s == NULL)
55 s = &st;
56 if (deref)
57 rs = stat(path, s);
58 else
59 rs = lstat(path, s);
60 if (rs == 0)
62 if (S_ISREG(s->st_mode)) return SYS_REG;
63 if (S_ISDIR(s->st_mode)) return SYS_DIR;
64 if (S_ISLNK(s->st_mode)) return SYS_SYM;
65 if (S_ISBLK(s->st_mode)) return SYS_BLK;
66 if (S_ISCHR(s->st_mode)) return SYS_CHR;
67 if (S_ISFIFO(s->st_mode)) return SYS_FIFO;
68 if (S_ISSOCK(s->st_mode)) return SYS_SOCK;
70 if (errno == ENOENT || errno == ENOTDIR)
71 return SYS_NONE;
72 return SYS_ERR;
75 sys_ftype sys_file_type(const gchar* path, gboolean deref)
77 return sys_file_type_stat(path, deref, 0);
80 time_t sys_file_mtime(const gchar* path, gboolean deref)
82 g_assert(path != 0);
83 struct stat s;
84 gint rs;
85 if (deref)
86 rs = stat(path, &s);
87 else
88 rs = lstat(path, &s);
89 if (rs == 0)
90 return s.st_mtime;
91 return (time_t)-1;
94 /* ripped off busybox and modified */
95 gint sys_rm_rf(const gchar* path)
97 struct stat path_stat;
99 /* if dir not exist return with error */
100 if (lstat(path, &path_stat) < 0)
101 return 1;
103 /* dir */
104 if (S_ISDIR(path_stat.st_mode))
106 DIR *dp;
107 struct dirent *d;
108 int status = 0;
110 if ((dp = opendir(path)) == NULL)
111 return 1;
112 while ((d = readdir(dp)) != NULL)
114 if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
115 continue;
116 gchar *new_path = g_strdup_printf("%s/%s", path, d->d_name);
117 if (sys_rm_rf(new_path))
118 status = 1;
119 g_free(new_path);
121 if (closedir(dp) < 0)
122 return 1;
123 if (rmdir(path) < 0)
124 return 1;
125 return status;
127 else /* nondir */
129 if (unlink(path) < 0)
130 return 1;
131 return 0;
135 gint sys_mkdir_p(const gchar* path)
137 gchar* simple_path;
138 gchar** pathv;
139 guint i, j, retval = 1, pathv_len;
140 gchar* tmp, *tmp_end;
142 g_assert(path != 0);
144 simple_path = path_simplify(path);
145 pathv = path_get_elements(simple_path);
146 pathv_len = g_strv_length_compat(pathv);
147 tmp = tmp_end = (gchar*)g_malloc0(strlen(simple_path)+10);
148 g_free(simple_path);
150 for (i=0; i<pathv_len; i++)
152 /* build path */
153 if (i > 0) /* absolute path or not first element */
154 *(tmp_end++) = '/';
155 if (i == 0 && **pathv == 0)
156 continue;
157 for (j=0; j<strlen(pathv[i]); j++)
158 *(tmp_end++) = pathv[i][j];
160 /* skip backreferences */
161 if (!strcmp(pathv[i], ".."))
162 continue;
164 /* check dir */
165 sys_ftype type = sys_file_type(tmp, 1);
166 if (type == SYS_DIR)
167 continue;
168 if (type == SYS_NONE)
170 #ifdef __WIN32__
171 if (mkdir(tmp) == -1)
172 #else
173 if (mkdir(tmp, 0755) == -1)
174 #endif
175 goto out;
177 else
178 goto out;
181 retval = 0;
182 out:
183 g_free(tmp);
184 g_strfreev(pathv);
185 return retval;
188 #ifndef __WIN32__
189 void sys_sigblock(sigset_t* sigs)
191 g_assert(sigs != 0);
192 gint rs;
193 sigset_t s;
194 sigfillset(&s);
195 rs = sigprocmask(SIG_SETMASK, &s, sigs);
196 if (rs == -1)
198 printf("panic: can't block signals\n");
199 exit(1);
202 #endif
204 #ifndef __WIN32__
205 void sys_sigunblock(sigset_t* sigs)
207 g_assert(sigs != 0);
208 gint rs;
209 rs = sigprocmask(SIG_SETMASK, sigs, 0);
210 if (rs == -1)
212 printf("panic: can't unblock signals\n");
213 exit(1);
216 #endif
218 gint sys_lock_new(const gchar* path, struct error* e)
220 g_assert(path != 0);
221 g_assert(e != 0);
222 gint fd = open(path, O_CREAT, 0644);
223 if (fd < 0)
225 e_set(e, E_FATAL, "can't open lock file: %s", strerror(errno));
226 return -1;
228 return fd;
231 gint sys_lock_trywait(gint fd, gint timeout, struct error* e)
233 g_assert(e != 0);
234 gint c=0;
235 while (1)
237 gint s = flock(fd, LOCK_NB|LOCK_EX);
238 if (s == -1) /* we did not get lock */
240 if (errno != EWOULDBLOCK) /* and will not get it */
242 e_set(e, E_FATAL, "flock failed: %s", strerror(errno));
243 return 1;
245 /* ok maybe we could get it a bit later */
246 if (++c > timeout)
248 e_set(e, E_ERROR, "timed out waiting for a lock");
249 return 1;
251 usleep(100000); /* 100ms */
253 /* got it! */
254 return 0;
258 gint sys_lock_put(gint fd, struct error* e)
260 g_assert(e != 0);
261 gint s = flock(fd, LOCK_NB|LOCK_UN);
262 if (s == -1) /* error */
264 e_set(e, E_FATAL, "flock failed: %s", strerror(errno));
265 return 1;
267 return 0;
270 void sys_lock_del(gint fd)
272 close(fd);
275 gint sys_write_buffer_to_file(const gchar* file, const gchar* buf, gsize len, struct error* e)
277 g_assert(file != 0);
278 g_assert(buf != 0);
279 g_assert(e != 0);
281 FILE* f = fopen(file, "w");
282 if (f == NULL)
284 e_set(e, E_FATAL, "can't open file for writing: %s", strerror(errno));
285 return 1;
287 if (len == 0)
288 len = strlen(buf);
289 if (1 != fwrite(buf, len, 1, f))
291 e_set(e, E_FATAL, "can't write data to a file: %s", file);
292 fclose(f);
293 return 1;
295 fclose(f);
296 return 0;
299 gint sys_read_file_to_buffer(const gchar* file, gchar* buf, gsize len, struct error* e)
301 g_assert(file != NULL);
302 g_assert(buf != NULL);
303 g_assert(len > 0);
304 g_assert(e != NULL);
306 FILE* f = fopen(file, "r");
307 if (f == NULL)
309 e_set(e, E_FATAL, "Can't open file for reading: %s (%s)", file, strerror(errno));
310 return 1;
312 if (1 != fread(buf, len, 1, f))
314 e_set(e, E_FATAL, "Can't read data from the file: %s (%s)", file, strerror(errno));
315 fclose(f);
316 return 1;
318 fclose(f);
319 return 0;