/[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 11 - (hide annotations) (download)
Tue Nov 6 23:41:58 2001 UTC (11 years, 6 months ago) by rabbi
File MIME type: text/plain
File size: 12186 byte(s)
First round of changes adding support for Mixmaster as a service under
Windows NT.
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 rabbi 11 $Id: util.c,v 1.2 2001/11/06 23:41:58 rabbi 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     #include <unistd.h>
21     #include <sys/file.h>
22     #include <termios.h>
23     #else
24     #include <io.h>
25     #endif
26     #ifdef HAVE_GETKEY
27     #include <pc.h>
28     #endif
29     #include <assert.h>
30    
31     /** string comparison functions. return 1 on match, 0 otherwise ********/
32    
33     int strileft(const char *string, const char *keyword)
34     {
35     register unsigned int i;
36    
37     for (i = 0; keyword[i] != '\0'; i++)
38     if (tolower(string[i]) != tolower(keyword[i]))
39     return 0;
40     return 1;
41     }
42    
43     int striright(const char *string, const char *keyword)
44     {
45     int l;
46     l = strlen(string) - strlen(keyword);
47     return (l >= 0 ? strieq(string + l, keyword) : -1);
48     }
49    
50     int strleft(const char *string, const char *keyword)
51     {
52     register unsigned int i;
53    
54     for (i = 0; keyword[i] != '\0'; i++)
55     if (string[i] != keyword[i])
56     return 0;
57     return 1;
58     }
59    
60     int strifind(const char *string, const char *keyword)
61     {
62     register unsigned int i, j;
63     char k;
64    
65     k = tolower(keyword[0]);
66     for (i = 0; string[i] != '\0'; i++) {
67     if (tolower(string[i]) == k) {
68     for (j = 1; keyword[j] != '\0'; j++)
69     if (tolower(string[i + j]) != tolower(keyword[j]))
70     goto next;
71     return 1;
72     }
73     next:
74     ;
75     }
76     return 0;
77     }
78    
79     int strieq(const char *s1, const char *s2)
80     {
81     register unsigned int i = 0;
82    
83     do
84     if (tolower(s1[i]) != tolower(s2[i]))
85     return 0;
86     while (s1[i++] != '\0') ;
87     return 1;
88     }
89    
90     int streq(const char *a, const char *b)
91     {
92     return (strcmp(a, b) == 0);
93     }
94    
95     int strfind(const char *a, const char *keyword)
96     {
97     return (strstr(a, keyword) != NULL);
98     }
99    
100     void strcatn(char *dest, const char *src, int n)
101     {
102     int l;
103     l = strlen(dest);
104     if (l < n)
105     strncpy(dest + l, src, n - l - 1);
106     dest[n-1] = '\0';
107     }
108    
109     /** files **************************************************************/
110    
111     int mixfile(char *path, const char *name)
112     {
113     assert(path != NULL && name != NULL);
114    
115 rabbi 11 if (name[0] == DIRSEP || (isalpha(name[0]) && name[1] == ':') || MIXDIR == NULL)
116 rabbi 1 strncpy(path, name, PATHMAX);
117     else {
118     strncpy(path, MIXDIR, PATHMAX);
119     strcatn(path, name, PATHMAX);
120     }
121     return (0);
122     }
123    
124     FILE *mix_openfile(const char *name, const char *a)
125     {
126     char path[PATHMAX];
127    
128     mixfile(path, name);
129     return (fopen(path, a));
130     }
131    
132     FILE *openpipe(const char *prog)
133     {
134     FILE *p = NULL;
135    
136     #ifdef POSIX
137     p = popen(prog, "w");
138     #endif
139 rabbi 11 #ifdef _MSC
140     p = _popen(prog, "w");
141     #endif
142 rabbi 1
143     if (p == NULL)
144     errlog(ERRORMSG, "Unable to open pipe to %s\n", prog);
145     return p;
146     }
147    
148     int
149     file_to_out(const char *filename)
150     {
151     int len;
152     FILE *fp;
153     char chunk[1024];
154    
155     if ((fp = mix_openfile(filename, "r")) == NULL)
156     return -1;
157     while ((len = fread(chunk, 1, sizeof(chunk), fp)) > 0)
158     {
159     fwrite(chunk, 1, len, stdout);
160     }
161     fclose (fp);
162     return (len == 0 ? 0 : (-1));
163     }
164    
165     int closepipe(FILE *p)
166     {
167     #ifdef POSIX
168     return (pclose(p));
169 rabbi 11 #elif defined(_MSC)
170     return (_pclose(p));
171 rabbi 1 #else
172     return -1;
173     #endif
174     }
175    
176     /** Base 64 encoding ****************************************************/
177    
178     static byte bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
179     static byte asctobin[] =
180     {
181     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
182     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
183     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
184     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
185     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
186     0x80, 0x80, 0x80, 0076, 0x80, 0x80, 0x80, 0077,
187     0064, 0065, 0066, 0067, 0070, 0071, 0072, 0073,
188     0074, 0075, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
189     0x80, 0000, 0001, 0002, 0003, 0004, 0005, 0006,
190     0007, 0010, 0011, 0012, 0013, 0014, 0015, 0016,
191     0017, 0020, 0021, 0022, 0023, 0024, 0025, 0026,
192     0027, 0030, 0031, 0x80, 0x80, 0x80, 0x80, 0x80,
193     0x80, 0032, 0033, 0034, 0035, 0036, 0037, 0040,
194     0041, 0042, 0043, 0044, 0045, 0046, 0047, 0050,
195     0051, 0052, 0053, 0054, 0055, 0056, 0057, 0060,
196     0061, 0062, 0063, 0x80, 0x80, 0x80, 0x80, 0x80,
197    
198     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
199     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
200     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
201     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
202     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
203     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
204     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
205     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
206     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
207     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
208     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
209     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
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     };
215    
216     void id_encode(byte id[], byte *s)
217     {
218     sprintf
219     (s, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
220     id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7], id[8], id[9],
221     id[10], id[11], id[12], id[13], id[14], id[15]);
222     }
223    
224     void id_decode(byte *s, byte id[])
225     {
226     int i, x[16];
227    
228     sscanf
229     (s, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
230     x, x + 1, x + 2, x + 3, x + 4, x + 5, x + 6, x + 7, x + 8,
231     x + 9, x + 10, x + 11, x + 12, x + 13, x + 14, x + 15);
232     for (i = 0; i < 16; i++)
233     id[i] = x[i];
234     }
235    
236     int encode(BUFFER *in, int linelen)
237     {
238     byte *b, *e;
239     int i, l, m;
240     unsigned long u;
241     BUFFER *out;
242    
243     out = buf_new();
244    
245     l = in->length;
246     if (l % 3 != 0)
247     l += 2;
248     l = l / 3 * 4;
249    
250     if (linelen) {
251     l += l / linelen + (l % linelen > 0 ? 1 : 0);
252     }
253     linelen /= 4; /* blocks of 4 characters */
254    
255     buf_prepare(out, l);
256    
257     b = in->data;
258     e = out->data;
259     m = in->length - 2;
260     for (i = 0, l = 0; i < m; i += 3) {
261     u = ((unsigned long) b[i] << 16) | ((unsigned long) b[i + 1] << 8) |
262     b[i + 2];
263     *e++ = bintoasc[(u >> 18) & 0x3f];
264     *e++ = bintoasc[(u >> 12) & 0x3f];
265     *e++ = bintoasc[(u >> 6) & 0x3f];
266     *e++ = bintoasc[u & 0x3f];
267     if (linelen && ++l >= linelen) {
268     l = 0;
269     *e++ = '\n';
270     }
271     }
272     if (i < in->length) {
273     *e++ = bintoasc[b[i] >> 2];
274     *e++ = bintoasc[((b[i] << 4) & 0x30) | ((b[i + 1] >> 4) & 0x0f)];
275     if (i + 1 == in->length)
276     *e++ = '=';
277     else
278     *e++ = bintoasc[((b[i + 1] << 2) & 0x3c) | ((b[i + 2] >> 6) & 0x03)];
279     *e++ = '=';
280     ++l;
281     }
282     if (linelen && l != 0)
283     *e++ = '\n';
284     *e = '\0';
285    
286     assert(out->data + out->length == e);
287     buf_move(in, out);
288     buf_free(out);
289     return (0);
290     }
291    
292     int decode(BUFFER *in, BUFFER *out)
293     {
294     int err = 0;
295     register byte c0, c1, c2, c3;
296     register byte *a, *d, *end;
297     int tempbuf = 0;
298     int i;
299    
300     if (in == out) {
301     out = buf_new();
302     tempbuf = 1;
303     }
304     buf_prepare(out, 3 * (in->length - in->ptr) / 4);
305    
306     a = in->data + in->ptr;
307     end = in->data + in->length - 3;
308     d = out->data;
309     i = 0;
310    
311     while (a < end) {
312     if ((c0 = asctobin[a[0]]) & 0x80 ||
313     (c1 = asctobin[a[1]]) & 0x80 ||
314     (c2 = asctobin[a[2]]) & 0x80 ||
315     (c3 = asctobin[a[3]]) & 0x80) {
316     if (a[0] == '\n') { /* ignore newline */
317     a++;
318     continue;
319     } else if (a[0] == '\r' && a[1] == '\n') { /* ignore crlf */
320     a += 2;
321     continue;
322     } else if (a[0] == '=' && a[1] == '4' && a[2] == '6') {
323     a += 2; /* '=46' at the left of a line really is 'F' */
324     *a = 'F'; /* fix in memory ... */
325     continue;
326     } else if (a[2] == '=' || a[3] == '=') {
327     if (a[0] & 0x80 || (c0 = asctobin[a[0]]) & 0x80 ||
328     a[1] & 0x80 || (c1 = asctobin[a[1]]) & 0x80)
329     err = -1;
330     else if (a[2] == '=')
331     c2 = 0, i += 1;
332     else if (a[2] & 0x80 || (c2 = asctobin[a[2]]) & 0x80)
333     err = -1;
334     else
335     i += 2;
336     if (err == 0) {
337     /* read the correct final block */
338     *d++ = (byte) ((c0 << 2) | (c1 >> 4));
339     *d++ = (byte) ((c1 << 4) | (c2 >> 2));
340     if (a[3] != '=')
341     *d++ = (byte) ((c2 << 6));
342     #if 1
343     if (a + 4 < in->data + in->length) {
344     a += 4;
345     continue; /* support Mixmaster 2.0.3 encoding */
346     }
347     #endif
348     break;
349     }
350     }
351     err = -1;
352     break;
353     }
354     a += 4;
355    
356     *d++ = (byte) ((c0 << 2) | (c1 >> 4));
357     *d++ = (byte) ((c1 << 4) | (c2 >> 2));
358     *d++ = (byte) ((c2 << 6) | c3);
359     i += 3;
360     }
361    
362     in->ptr = a - in->data;
363    
364     assert(i <= out->length);
365     out->length = i;
366    
367     if (tempbuf) {
368     buf_move(in, out);
369     buf_free(out);
370     }
371     return (err);
372     }
373    
374     LOCK *lockfile(char *filename)
375     {
376     LOCK *l;
377     char name[LINELEN];
378    
379     strcpy(name, "lck");
380 rabbi 11 if (strchr(filename, DIRSEP))
381     strcatn(name, strrchr(filename, DIRSEP), LINELEN);
382 rabbi 1 else
383     strcatn(name, filename, LINELEN);
384     l = malloc(sizeof(LOCK));
385    
386     l->name = malloc(PATHMAX);
387     mixfile(l->name, name);
388     l->f = mix_openfile(l->name, "w+");
389     if (l->f)
390     lock(l->f);
391     return (l);
392     }
393    
394     int unlockfile(LOCK *l)
395     {
396     if (l->f) {
397     unlock(l->f);
398     fclose(l->f);
399     }
400     unlink(l->name);
401     free(l->name);
402     free(l);
403     return (0);
404     }
405    
406     int lock(FILE *f)
407     {
408     #ifndef WIN32
409     struct flock lockstruct;
410    
411     lockstruct.l_type = F_WRLCK;
412     lockstruct.l_whence = 0;
413     lockstruct.l_start = 0;
414     lockstruct.l_len = 0;
415     return (fcntl(fileno(f), F_SETLKW, &lockstruct));
416     #else
417     return (0);
418     #endif
419     }
420    
421     int unlock(FILE *f)
422     {
423     #ifndef WIN32
424    
425     struct flock lockstruct;
426    
427     lockstruct.l_type = F_UNLCK;
428     lockstruct.l_whence = 0;
429     lockstruct.l_start = 0;
430     lockstruct.l_len = 0;
431     return (fcntl(fileno(f), F_SETLKW, &lockstruct));
432     #else
433     return (0);
434     #endif
435     }
436    
437     /* get passphrase ******************************************************/
438    
439     static int getuserpass(BUFFER *b, int mode)
440     {
441     char p[LINELEN];
442     int fd;
443     int n;
444    
445     #ifdef HAVE_TERMIOS
446     struct termios attr;
447    
448     #endif
449    
450     if (mode == 0)
451     fprintf(stderr, "enter passphrase: ");
452     else
453     fprintf(stderr, "re-enter passphrase: ");
454     fflush(stderr);
455     #ifndef UNIX
456     #ifdef HAVE_GETKEY
457     for (n = 0; p[n] != '\n' && n < LINELEN; n++) {
458     p[n] = getkey();
459     }
460     p[n] = 0;
461     #else
462     scanf("%127s", p);
463     #endif
464     #else
465     fd = open("/dev/tty", O_RDONLY);
466     if (tcgetattr(fd, &attr) != 0)
467     return (-1);
468     attr.c_lflag &= ~ECHO;
469     attr.c_lflag |= ICANON;
470     if (tcsetattr(fd, TCSAFLUSH, &attr) != 0)
471     return (-1);
472    
473     n = read(fd, p, LINELEN);
474    
475     attr.c_lflag |= ECHO;
476     if (tcsetattr(fd, TCSAFLUSH, &attr) != 0)
477     return (-1);
478    
479     close(fd);
480     fprintf(stderr, "\n");
481     p[n - 1] = 0;
482     #endif
483     if (mode == 0)
484     buf_appends(b, p);
485     else
486     return (bufeq(b, p));
487     return (0);
488     }
489    
490     static BUFFER *userpass = NULL;
491    
492     int user_pass(BUFFER *key)
493     {
494     if (userpass == NULL) {
495     userpass = buf_new();
496     userpass->sensitive = 1;
497     if (getenv("MIXPASS"))
498     buf_sets(userpass, getenv("MIXPASS"));
499     else if (menu_getuserpass(userpass, 0) == -1)
500     getuserpass(userpass, 0);
501     }
502     buf_set(key, userpass);
503     key->sensitive = 1;
504     return (0);
505     }
506    
507     int user_confirmpass(BUFFER *key)
508     {
509     int ok;
510    
511     ok = menu_getuserpass(key, 1);
512     if (ok == -1)
513     ok = getuserpass(key, 1);
514     return (ok);
515     }
516    
517     void user_delpass(void)
518     {
519     if (userpass)
520     buf_free(userpass);
521     userpass = NULL;
522     }
523    
524     /* functions missing on some systems *************************************/
525    
526     #ifdef __RSXNT__
527     int fileno(FILE *f)
528     {
529     return (f->_handle);
530     }
531    
532     #endif
533    
534     #ifdef _MSC /* Visual C lacks dirent */
535    
536     DIR *opendir(const char *name)
537     {
538     DIR *dir;
539 rabbi 11 WIN32_FIND_DATA d;
540     char path[PATHMAX];
541 rabbi 1
542     dir = malloc(sizeof(HANDLE));
543    
544 rabbi 11 sprintf(path, "%s%c*", name, DIRSEP);
545     *dir = FindFirstFile(path, &d);
546 rabbi 1 /* first file found is "." -- can be safely ignored here */
547    
548     if (*dir == INVALID_HANDLE_VALUE) {
549     free(dir);
550     return (NULL);
551     } else
552     return (dir);
553     }
554    
555     struct dirent e;
556     struct dirent *readdir(DIR *dir)
557     {
558 rabbi 11 WIN32_FIND_DATA d;
559 rabbi 1 int ok;
560    
561 rabbi 11 ok = FindNextFile(*dir, &d);
562 rabbi 1 if (ok) {
563 rabbi 11 strncpy(e.d_name, d.cFileName, PATHMAX);
564 rabbi 1 return (&e);
565     } else
566     return (NULL);
567     }
568    
569     int closedir(DIR *dir)
570     {
571     if (dir) {
572     FindClose(*dir);
573     free(dir);
574     return (0);
575     }
576     return (-1);
577     }
578    
579     #endif

  ViewVC Help
Powered by ViewVC 1.1.5