/[pkg-mixmaster]/trunk/Mix/Src/util.c
ViewVC logotype

Contents of /trunk/Mix/Src/util.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 357 - (hide annotations) (download)
Thu Oct 10 22:07:48 2002 UTC (10 years, 7 months ago) by weaselp
File MIME type: text/plain
File size: 15583 byte(s)
make sure to unlink mix.pid in the right directory and reword a warning message
1 rabbi 1 /* Mixmaster version 3 -- (C) 1999 Anonymizer Inc.
2    
3     Mixmaster may be redistributed and modified under certain conditions.
4     This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
5     ANY KIND, either express or implied. See the file COPYRIGHT for
6     details.
7    
8     Utility functions
9 weaselp 357 $Id: util.c,v 1.13 2002/10/10 22:07:48 weaselp Exp $ */
10 rabbi 1
11    
12     #include "mix3.h"
13     #include <stdlib.h>
14     #include <string.h>
15     #include <ctype.h>
16     #include <fcntl.h>
17     #include <sys/types.h>
18     #include <sys/stat.h>
19     #ifdef POSIX
20 weaselp 197 #include <signal.h>
21     #include <errno.h>
22 rabbi 1 #include <unistd.h>
23     #include <sys/file.h>
24     #include <termios.h>
25 rabbi 262 #else /* end of POSIX */
26 rabbi 1 #include <io.h>
27 rabbi 262 #endif /* else if not POSIX */
28 rabbi 1 #ifdef HAVE_GETKEY
29     #include <pc.h>
30 rabbi 262 #endif /* HAVE_GETKEY */
31 rabbi 1 #include <assert.h>
32    
33     /** string comparison functions. return 1 on match, 0 otherwise ********/
34    
35     int strileft(const char *string, const char *keyword)
36     {
37     register unsigned int i;
38    
39     for (i = 0; keyword[i] != '\0'; i++)
40     if (tolower(string[i]) != tolower(keyword[i]))
41     return 0;
42     return 1;
43     }
44    
45     int striright(const char *string, const char *keyword)
46     {
47     int l;
48     l = strlen(string) - strlen(keyword);
49     return (l >= 0 ? strieq(string + l, keyword) : -1);
50     }
51    
52     int strleft(const char *string, const char *keyword)
53     {
54     register unsigned int i;
55    
56     for (i = 0; keyword[i] != '\0'; i++)
57     if (string[i] != keyword[i])
58     return 0;
59     return 1;
60     }
61    
62     int strifind(const char *string, const char *keyword)
63     {
64     register unsigned int i, j;
65     char k;
66    
67     k = tolower(keyword[0]);
68     for (i = 0; string[i] != '\0'; i++) {
69     if (tolower(string[i]) == k) {
70     for (j = 1; keyword[j] != '\0'; j++)
71     if (tolower(string[i + j]) != tolower(keyword[j]))
72     goto next;
73     return 1;
74     }
75     next:
76     ;
77     }
78     return 0;
79     }
80    
81     int strieq(const char *s1, const char *s2)
82     {
83     register unsigned int i = 0;
84    
85     do
86     if (tolower(s1[i]) != tolower(s2[i]))
87     return 0;
88     while (s1[i++] != '\0') ;
89     return 1;
90     }
91    
92     int streq(const char *a, const char *b)
93     {
94     return (strcmp(a, b) == 0);
95     }
96    
97     int strfind(const char *a, const char *keyword)
98     {
99     return (strstr(a, keyword) != NULL);
100     }
101    
102     void strcatn(char *dest, const char *src, int n)
103     {
104     int l;
105     l = strlen(dest);
106     if (l < n)
107     strncpy(dest + l, src, n - l - 1);
108     dest[n-1] = '\0';
109     }
110    
111     /** files **************************************************************/
112    
113     int mixfile(char *path, const char *name)
114     {
115 weaselp 163 char *h;
116 rabbi 1 assert(path != NULL && name != NULL);
117    
118 weaselp 163 #ifdef POSIX
119     if (name[0] == '~' && name[1] == DIRSEP && (h = getenv("HOME")) != NULL) {
120     strncpy(path, h, PATHMAX);
121     path[PATHMAX-1] = '\0';
122     strcatn(path, name + 1, PATHMAX);
123     } else
124 rabbi 262 #endif /* POSIX */
125 weaselp 163 if (name[0] == DIRSEP || (isalpha(name[0]) && name[1] == ':') || MIXDIR == NULL) {
126 rabbi 1 strncpy(path, name, PATHMAX);
127 weaselp 163 path[PATHMAX-1] = '\0';
128     } else {
129 rabbi 1 strncpy(path, MIXDIR, PATHMAX);
130 weaselp 163 path[PATHMAX-1] = '\0';
131 rabbi 1 strcatn(path, name, PATHMAX);
132     }
133     return (0);
134     }
135    
136     FILE *mix_openfile(const char *name, const char *a)
137     {
138     char path[PATHMAX];
139    
140     mixfile(path, name);
141     return (fopen(path, a));
142     }
143    
144     FILE *openpipe(const char *prog)
145     {
146     FILE *p = NULL;
147    
148     #ifdef POSIX
149     p = popen(prog, "w");
150 rabbi 262 #endif /* POSIX */
151 rabbi 11 #ifdef _MSC
152     p = _popen(prog, "w");
153 rabbi 262 #endif /* _MSC */
154 rabbi 1
155     if (p == NULL)
156     errlog(ERRORMSG, "Unable to open pipe to %s\n", prog);
157     return p;
158     }
159    
160     int
161     file_to_out(const char *filename)
162     {
163     int len;
164     FILE *fp;
165     char chunk[1024];
166    
167     if ((fp = mix_openfile(filename, "r")) == NULL)
168     return -1;
169     while ((len = fread(chunk, 1, sizeof(chunk), fp)) > 0)
170     {
171     fwrite(chunk, 1, len, stdout);
172     }
173     fclose (fp);
174     return (len == 0 ? 0 : (-1));
175     }
176    
177     int closepipe(FILE *p)
178     {
179     #ifdef POSIX
180     return (pclose(p));
181 rabbi 262 #elif defined(_MSC) /* end of POSIX */
182 rabbi 11 return (_pclose(p));
183 rabbi 262 #else /* end of defined(_MSC) */
184 rabbi 1 return -1;
185 rabbi 262 #endif /* else if not defined(_MSC), POSIX */
186 rabbi 1 }
187    
188     /** Base 64 encoding ****************************************************/
189    
190     static byte bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
191     static byte asctobin[] =
192     {
193     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
194     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
195     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
196     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
197     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
198     0x80, 0x80, 0x80, 0076, 0x80, 0x80, 0x80, 0077,
199     0064, 0065, 0066, 0067, 0070, 0071, 0072, 0073,
200     0074, 0075, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
201     0x80, 0000, 0001, 0002, 0003, 0004, 0005, 0006,
202     0007, 0010, 0011, 0012, 0013, 0014, 0015, 0016,
203     0017, 0020, 0021, 0022, 0023, 0024, 0025, 0026,
204     0027, 0030, 0031, 0x80, 0x80, 0x80, 0x80, 0x80,
205     0x80, 0032, 0033, 0034, 0035, 0036, 0037, 0040,
206     0041, 0042, 0043, 0044, 0045, 0046, 0047, 0050,
207     0051, 0052, 0053, 0054, 0055, 0056, 0057, 0060,
208     0061, 0062, 0063, 0x80, 0x80, 0x80, 0x80, 0x80,
209    
210     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
211     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
212     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
213     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
214     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
215     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
216     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
217     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
218     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
219     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
220     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
221     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
222     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
223     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
224     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
225     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
226     };
227    
228     void id_encode(byte id[], byte *s)
229     {
230     sprintf
231     (s, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
232     id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7], id[8], id[9],
233     id[10], id[11], id[12], id[13], id[14], id[15]);
234     }
235    
236     void id_decode(byte *s, byte id[])
237     {
238     int i, x[16];
239    
240     sscanf
241     (s, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
242     x, x + 1, x + 2, x + 3, x + 4, x + 5, x + 6, x + 7, x + 8,
243     x + 9, x + 10, x + 11, x + 12, x + 13, x + 14, x + 15);
244     for (i = 0; i < 16; i++)
245     id[i] = x[i];
246     }
247    
248     int encode(BUFFER *in, int linelen)
249     {
250     byte *b, *e;
251     int i, l, m;
252     unsigned long u;
253     BUFFER *out;
254    
255     out = buf_new();
256    
257     l = in->length;
258     if (l % 3 != 0)
259     l += 2;
260     l = l / 3 * 4;
261    
262     if (linelen) {
263     l += l / linelen + (l % linelen > 0 ? 1 : 0);
264     }
265     linelen /= 4; /* blocks of 4 characters */
266    
267     buf_prepare(out, l);
268    
269     b = in->data;
270     e = out->data;
271     m = in->length - 2;
272     for (i = 0, l = 0; i < m; i += 3) {
273 weaselp 332 u = ((unsigned long) b[i] << 16) | ((unsigned long) b[i + 1] << 8) |
274 rabbi 1 b[i + 2];
275     *e++ = bintoasc[(u >> 18) & 0x3f];
276     *e++ = bintoasc[(u >> 12) & 0x3f];
277     *e++ = bintoasc[(u >> 6) & 0x3f];
278     *e++ = bintoasc[u & 0x3f];
279     if (linelen && ++l >= linelen) {
280     l = 0;
281     *e++ = '\n';
282     }
283     }
284     if (i < in->length) {
285     *e++ = bintoasc[b[i] >> 2];
286     *e++ = bintoasc[((b[i] << 4) & 0x30) | ((b[i + 1] >> 4) & 0x0f)];
287     if (i + 1 == in->length)
288     *e++ = '=';
289     else
290     *e++ = bintoasc[((b[i + 1] << 2) & 0x3c) | ((b[i + 2] >> 6) & 0x03)];
291     *e++ = '=';
292     ++l;
293     }
294     if (linelen && l != 0)
295     *e++ = '\n';
296     *e = '\0';
297    
298     assert(out->data + out->length == e);
299     buf_move(in, out);
300     buf_free(out);
301     return (0);
302     }
303    
304     int decode(BUFFER *in, BUFFER *out)
305     {
306     int err = 0;
307 weaselp 253 register byte c0 = 0, c1 = 0, c2 = 0, c3 = 0;
308 rabbi 1 register byte *a, *d, *end;
309     int tempbuf = 0;
310     int i;
311    
312     if (in == out) {
313     out = buf_new();
314     tempbuf = 1;
315     }
316     buf_prepare(out, 3 * (in->length - in->ptr) / 4);
317    
318     a = in->data + in->ptr;
319     end = in->data + in->length - 3;
320     d = out->data;
321     i = 0;
322    
323     while (a < end) {
324     if ((c0 = asctobin[a[0]]) & 0x80 ||
325     (c1 = asctobin[a[1]]) & 0x80 ||
326     (c2 = asctobin[a[2]]) & 0x80 ||
327     (c3 = asctobin[a[3]]) & 0x80) {
328     if (a[0] == '\n') { /* ignore newline */
329     a++;
330     continue;
331     } else if (a[0] == '\r' && a[1] == '\n') { /* ignore crlf */
332     a += 2;
333     continue;
334 disastry 267 } else if (a[0] == '=' && a[1] == '4' && a[2] == '6' && !(asctobin[a[5]] & 0x80) ) {
335 rabbi 1 a += 2; /* '=46' at the left of a line really is 'F' */
336     *a = 'F'; /* fix in memory ... */
337     continue;
338     } else if (a[2] == '=' || a[3] == '=') {
339     if (a[0] & 0x80 || (c0 = asctobin[a[0]]) & 0x80 ||
340     a[1] & 0x80 || (c1 = asctobin[a[1]]) & 0x80)
341     err = -1;
342     else if (a[2] == '=')
343     c2 = 0, i += 1;
344     else if (a[2] & 0x80 || (c2 = asctobin[a[2]]) & 0x80)
345     err = -1;
346     else
347     i += 2;
348     if (err == 0) {
349     /* read the correct final block */
350     *d++ = (byte) ((c0 << 2) | (c1 >> 4));
351     *d++ = (byte) ((c1 << 4) | (c2 >> 2));
352     if (a[3] != '=')
353     *d++ = (byte) ((c2 << 6));
354     #if 1
355     if (a + 4 < in->data + in->length) {
356     a += 4;
357     continue; /* support Mixmaster 2.0.3 encoding */
358     }
359 rabbi 262 #endif /* 1 */
360 rabbi 1 break;
361     }
362     }
363     err = -1;
364     break;
365     }
366     a += 4;
367    
368     *d++ = (byte) ((c0 << 2) | (c1 >> 4));
369     *d++ = (byte) ((c1 << 4) | (c2 >> 2));
370     *d++ = (byte) ((c2 << 6) | c3);
371     i += 3;
372     }
373    
374     in->ptr = a - in->data;
375    
376     assert(i <= out->length);
377     out->length = i;
378    
379     if (tempbuf) {
380     buf_move(in, out);
381     buf_free(out);
382     }
383     return (err);
384     }
385    
386     LOCK *lockfile(char *filename)
387     {
388     LOCK *l;
389     char name[LINELEN];
390    
391     strcpy(name, "lck");
392 rabbi 11 if (strchr(filename, DIRSEP))
393     strcatn(name, strrchr(filename, DIRSEP), LINELEN);
394 rabbi 1 else
395     strcatn(name, filename, LINELEN);
396     l = malloc(sizeof(LOCK));
397    
398     l->name = malloc(PATHMAX);
399     mixfile(l->name, name);
400     l->f = mix_openfile(l->name, "w+");
401     if (l->f)
402     lock(l->f);
403     return (l);
404     }
405    
406     int unlockfile(LOCK *l)
407     {
408     if (l->f) {
409     unlock(l->f);
410     fclose(l->f);
411     }
412     unlink(l->name);
413     free(l->name);
414     free(l);
415     return (0);
416     }
417    
418     int lock(FILE *f)
419     {
420     #ifndef WIN32
421     struct flock lockstruct;
422    
423     lockstruct.l_type = F_WRLCK;
424     lockstruct.l_whence = 0;
425     lockstruct.l_start = 0;
426     lockstruct.l_len = 0;
427     return (fcntl(fileno(f), F_SETLKW, &lockstruct));
428 rabbi 262 #else /* end of WIN32 */
429 rabbi 1 return (0);
430 rabbi 262 #endif /* else if not WIN32 */
431 rabbi 1 }
432    
433     int unlock(FILE *f)
434     {
435     #ifndef WIN32
436    
437     struct flock lockstruct;
438    
439     lockstruct.l_type = F_UNLCK;
440     lockstruct.l_whence = 0;
441     lockstruct.l_start = 0;
442     lockstruct.l_len = 0;
443     return (fcntl(fileno(f), F_SETLKW, &lockstruct));
444 rabbi 262 #else /* end of not WIN32 */
445 rabbi 1 return (0);
446 rabbi 262 #endif /* else if WIN32 */
447 rabbi 1 }
448    
449     /* get passphrase ******************************************************/
450    
451     static int getuserpass(BUFFER *b, int mode)
452     {
453     char p[LINELEN];
454     int fd;
455     int n;
456    
457     #ifdef HAVE_TERMIOS
458     struct termios attr;
459    
460 rabbi 262 #endif /* HAVE_TERMIOS */
461 rabbi 1
462     if (mode == 0)
463     fprintf(stderr, "enter passphrase: ");
464     else
465     fprintf(stderr, "re-enter passphrase: ");
466     fflush(stderr);
467     #ifndef UNIX
468     #ifdef HAVE_GETKEY
469     for (n = 0; p[n] != '\n' && n < LINELEN; n++) {
470     p[n] = getkey();
471     }
472     p[n] = 0;
473 rabbi 262 #else /* end of HAVE_GETKEY */
474 rabbi 1 scanf("%127s", p);
475 rabbi 262 #endif /* else if not HAVE_GETKEY */
476     #else /* end of not UNIX */
477 rabbi 1 fd = open("/dev/tty", O_RDONLY);
478     if (tcgetattr(fd, &attr) != 0)
479     return (-1);
480     attr.c_lflag &= ~ECHO;
481     attr.c_lflag |= ICANON;
482     if (tcsetattr(fd, TCSAFLUSH, &attr) != 0)
483     return (-1);
484    
485     n = read(fd, p, LINELEN);
486    
487     attr.c_lflag |= ECHO;
488     if (tcsetattr(fd, TCSAFLUSH, &attr) != 0)
489     return (-1);
490    
491     close(fd);
492     fprintf(stderr, "\n");
493     p[n - 1] = 0;
494 rabbi 262 #endif /* else if UNIX */
495 rabbi 1 if (mode == 0)
496     buf_appends(b, p);
497     else
498     return (bufeq(b, p));
499     return (0);
500     }
501    
502     static BUFFER *userpass = NULL;
503    
504     int user_pass(BUFFER *key)
505     {
506     if (userpass == NULL) {
507     userpass = buf_new();
508     userpass->sensitive = 1;
509     if (getenv("MIXPASS"))
510     buf_sets(userpass, getenv("MIXPASS"));
511     else if (menu_getuserpass(userpass, 0) == -1)
512     getuserpass(userpass, 0);
513     }
514     buf_set(key, userpass);
515     key->sensitive = 1;
516     return (0);
517     }
518    
519     int user_confirmpass(BUFFER *key)
520     {
521     int ok;
522    
523     ok = menu_getuserpass(key, 1);
524     if (ok == -1)
525     ok = getuserpass(key, 1);
526     return (ok);
527     }
528    
529     void user_delpass(void)
530     {
531     if (userpass)
532     buf_free(userpass);
533     userpass = NULL;
534     }
535    
536 weaselp 197 int write_pidfile(char *pidfile)
537     {
538     int err = 0;
539     #ifdef POSIX
540     FILE *f;
541     char host[LINELEN], myhostname[LINELEN];
542     int pid, mypid;
543     int assigned;
544    
545     mypid = getpid();
546     gethostname(myhostname, LINELEN);
547     myhostname[LINELEN-1] = '\0';
548    
549     f = mix_openfile(pidfile, "r+");
550     if (f != NULL) {
551     assert(LINELEN > 71);
552     assigned = fscanf(f, "%d %70s", &pid, host);
553     if (assigned == 2) {
554     if (strcmp(host, myhostname) == 0) {
555     if (kill (pid, 0) == -1) {
556 weaselp 332 if (errno == ESRCH) {
557 weaselp 357 fprintf(stderr, "Rewriting stale pid file.\n");
558 weaselp 197 rewind(f);
559     ftruncate(fileno(f), 0);
560     fprintf(f, "%d %s\n", mypid, myhostname);
561     } else {
562     fprintf(stderr, "Pid file exists and process still running.\n");
563     err = -1;
564     }
565     } else {
566     fprintf(stderr, "Pid file exists and process still running.\n");
567     err = -1;
568     }
569     } else {
570     /* Pid file was written on another host, fail */
571     fprintf(stderr, "Pid file exists and was created on another host (%s).\n", host);
572     err = -1;
573     }
574     } else {
575     fprintf(stderr, "Pid file exists and and could not be parsed.\n");
576     err = -1;
577     }
578 weaselp 332 } else {
579 weaselp 197 if (errno == ENOENT) {
580     f = mix_openfile(pidfile, "w+");
581     if (f != NULL) {
582     fprintf(f, "%d %s\n", mypid, myhostname);
583     } else {
584     fprintf(stderr, "Could not open pidfile for writing: %s\n", strerror(errno));
585     err = -1;
586     }
587     } else {
588     fprintf(stderr, "Could not open pidfile for readwrite: %s\n", strerror(errno));
589     err = -1;
590     };
591     }
592     if(f)
593     fclose(f);
594 rabbi 262 #endif /* POSIX */
595 weaselp 197 return (err);
596     }
597    
598     int clear_pidfile(char *pidfile)
599     {
600     #ifdef POSIX
601 weaselp 357 char path[PATHMAX];
602    
603     mixfile(path, pidfile);
604     return (unlink(path));
605 rabbi 262 #else /* end of POSIX */
606 weaselp 197 return (0);
607 rabbi 262 #endif /* else if not POSIX */
608 weaselp 197 }
609 weaselp 214
610     time_t parse_yearmonthday(char* str)
611     {
612     time_t date;
613     int day, month, year;
614    
615     if (sscanf( str, "%d-%d-%d", &year, &month, &day) == 3 ) {
616     struct tm timestruct;
617     char *tz;
618     tz = getenv("TZ");
619 rabbi 305 #ifdef NO_SETENV
620 disastry 225 putenv("TZ=");
621 rabbi 305 #else /* end of NO_SETENV */
622 weaselp 214 setenv("TZ", "", 1);
623 rabbi 305 #endif /* else if not NO_SETENV */
624 weaselp 214 tzset();
625     memset(&timestruct, 0, sizeof(timestruct));
626     timestruct.tm_mday = day;
627     timestruct.tm_mon = month - 1;
628     timestruct.tm_year = year - 1900;
629     date = mktime(&timestruct);
630 rabbi 305 #ifdef NO_SETENV
631 disastry 225 if (tz) {
632     char envstr[LINELEN];
633     snprintf(envstr, LINELEN, "TZ=%s", tz);
634     putenv(envstr);
635     } else
636     putenv("TZ=");
637 rabbi 305 #else /* end of NO_SETENV */
638 weaselp 214 if (tz)
639     setenv("TZ", tz, 1);
640     else
641     unsetenv("TZ");
642 rabbi 305 #endif /* else if not NO_SETENV */
643 weaselp 214 tzset();
644     return date;
645     } else
646     return -1;
647     }
648    
649 rabbi 1 /* functions missing on some systems *************************************/
650    
651     #ifdef __RSXNT__
652     int fileno(FILE *f)
653     {
654     return (f->_handle);
655     }
656    
657 rabbi 262 #endif /* __RSXNT__ */
658 rabbi 1
659     #ifdef _MSC /* Visual C lacks dirent */
660    
661     DIR *opendir(const char *name)
662     {
663     DIR *dir;
664 rabbi 11 WIN32_FIND_DATA d;
665     char path[PATHMAX];
666 rabbi 1
667     dir = malloc(sizeof(HANDLE));
668    
669 rabbi 11 sprintf(path, "%s%c*", name, DIRSEP);
670     *dir = FindFirstFile(path, &d);
671 rabbi 1 /* first file found is "." -- can be safely ignored here */
672    
673     if (*dir == INVALID_HANDLE_VALUE) {
674     free(dir);
675     return (NULL);
676     } else
677     return (dir);
678     }
679    
680     struct dirent e;
681     struct dirent *readdir(DIR *dir)
682     {
683 rabbi 11 WIN32_FIND_DATA d;
684 rabbi 1 int ok;
685    
686 rabbi 11 ok = FindNextFile(*dir, &d);
687 rabbi 1 if (ok) {
688 rabbi 11 strncpy(e.d_name, d.cFileName, PATHMAX);
689 rabbi 1 return (&e);
690     } else
691     return (NULL);
692     }
693    
694     int closedir(DIR *dir)
695     {
696     if (dir) {
697     FindClose(*dir);
698     free(dir);
699     return (0);
700     }
701     return (-1);
702     }
703    
704 rabbi 262 #endif /* _MSC */

  ViewVC Help
Powered by ViewVC 1.1.5