/[pkg-mixmaster]/branches/mixmaster_2_9_STABLE/Mix/Src/pool.c
ViewVC logotype

Contents of /branches/mixmaster_2_9_STABLE/Mix/Src/pool.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 327 - (hide annotations) (download)
Wed Oct 9 20:29:44 2002 UTC (10 years, 7 months ago) by weaselp
File MIME type: text/plain
File size: 17636 byte(s)
Added closing comments for all #ifdef statements.
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     Send messages from pool
9 weaselp 327 $Id: pool.c,v 1.10.2.2 2002/10/09 20:29:44 weaselp Exp $ */
10 rabbi 1
11     #include "mix3.h"
12     #include <stdlib.h>
13     #include <string.h>
14     #include <ctype.h>
15     #include <sys/types.h>
16     #include <time.h>
17     #ifdef POSIX
18     #include <unistd.h>
19 weaselp 327 #else /* end of POSIX */
20 rabbi 1 #include <io.h>
21 weaselp 327 #endif /* else if not POSIX */
22 rabbi 1 #ifndef _MSC
23     #include <dirent.h>
24 weaselp 327 #endif /* not _MSC */
25 rabbi 1 #include <assert.h>
26    
27     #ifdef USE_PCRE
28     #include "pcre.h"
29 weaselp 327 #endif /* USE_PCRE */
30 rabbi 1
31     int msg_send(char *name);
32    
33     int mix_send(void)
34     {
35     return (mix_regular(FORCE_POOL));
36     }
37    
38     /* Message pool: Unix DOS
39     * latent messages: l* *.lat
40     * pooled messages: m* *.msg
41     * messages to be sent: s* *.snd
42     * temporary files: t* *.tmp
43     * files in user editor: x*
44     * incoming mail: i* *.inf
45     * partial messages: p* p*.*
46 rabbi 18 * error messages: e* *.err
47 rabbi 74 * outgoing messages: out *.txt (to be used by external program)
48 rabbi 1 */
49    
50     static int is(char *path, char *type)
51     {
52     #ifdef SHORTNAMES
53     int s;
54    
55     s = strlen(path);
56     if (s <= 4)
57     return 0;
58     return (path[s - 4] == '.' && streq(path + s - 3, type));
59 weaselp 327 #else /* end of SHORTNAMES */
60 rabbi 1 return (path[0] == type[0]);
61 weaselp 327 #endif /* else if not SHORTNAMES */
62 rabbi 1 }
63    
64     static void mv(char *name, char *newtype)
65     {
66     char old[PATHMAX], new[PATHMAX];
67    
68 rabbi 11 sprintf(old, "%s%c%s", POOLDIR, DIRSEP, name);
69 rabbi 1 #ifdef SHORTNAMES
70     assert(strlen(name) > 4);
71     strcpy(name + strlen(name) - 3, newtype);
72 weaselp 327 #else /* end of SHORTNAMES */
73 rabbi 1 name[0] = newtype[0];
74 weaselp 327 #endif /* else if not SHORTNAMES */
75 rabbi 11 sprintf(new, "%s%c%s", POOLDIR, DIRSEP, name);
76 rabbi 1 rename(old, new);
77     }
78    
79     int latent_read(void)
80     {
81     char path[PATHMAX];
82     DIR *d;
83     FILE *f;
84     struct dirent *e;
85     int size = 0;
86     long now, then;
87    
88     now = time(NULL);
89     d = opendir(POOLDIR);
90     if (d != NULL)
91     for (;;) {
92     e = readdir(d);
93     if (e == NULL)
94     break;
95     if (is(e->d_name, "lat")) {
96 rabbi 11 sprintf(path, "%s%c%s", POOLDIR, DIRSEP, e->d_name);
97 rabbi 1 f = fopen(path, "rb");
98     if (f != NULL) {
99     fscanf(f, "%*d %ld\n", &then);
100     fclose(f);
101     if (now > then)
102     mv(e->d_name, "msg");
103     }
104     }
105     }
106     closedir(d);
107     return (size);
108     }
109    
110     int infile_read(void)
111     {
112     char path[PATHMAX];
113     BUFFER *msg;
114     DIR *d;
115     FILE *f;
116     struct dirent *e;
117     int size = 0;
118    
119     msg = buf_new();
120     d = opendir(POOLDIR);
121     if (d != NULL)
122     for (;;) {
123     e = readdir(d);
124     if (e == NULL)
125     break;
126     if (is(e->d_name, "inf")) {
127     mv(e->d_name, "tmp");
128 rabbi 11 sprintf(path, "%s%c%s", POOLDIR, DIRSEP, e->d_name);
129 rabbi 1 f = fopen(path, "rb");
130     if (f != NULL) {
131     buf_clear(msg);
132     buf_read(msg, f);
133     fclose(f);
134     unlink(path);
135     mix_decrypt(msg);
136     }
137     }
138     }
139     closedir(d);
140     buf_free(msg);
141     return (size);
142     }
143    
144     int pool_add(BUFFER *msg, char *type)
145     {
146     char path[PATHMAX], pathtmp[PATHMAX];
147     FILE *f;
148     int err = -1;
149    
150     f = pool_new(type, pathtmp, path);
151     if (f != NULL) {
152     err = buf_write(msg, f);
153     fclose(f);
154     }
155     if (err == 0) {
156     rename(pathtmp, path);
157     errlog(DEBUGINFO, "Added %s file to pool.\n", type);
158     }
159     return (err);
160    
161     }
162    
163     FILE *pool_new(char *type, char *tmpname, char *path)
164     {
165     FILE *f;
166    
167     assert(strlen(type) == 3);
168     #ifdef SHORTNAMES
169 rabbi 11 sprintf(tmpname, "%s%c%02x%02x%02x%02x.tmp", POOLDIR, DIRSEP, rnd_byte(), rnd_byte(),
170 rabbi 1 rnd_byte(), rnd_byte());
171     strcpy(path, tmpname);
172     memcpy(path + strlen(path) - 3, type, 3);
173 weaselp 327 #else /* end of SHORTNAMES */
174 rabbi 11 sprintf(tmpname, "%s%ct%02x%02x%02x%02x%02x%02x%01x", POOLDIR, DIRSEP, rnd_byte(),
175 rabbi 1 rnd_byte(), rnd_byte(), rnd_byte(), rnd_byte(),
176     rnd_byte(), rnd_byte() & 15);
177     strcpy(path, tmpname);
178 rabbi 11 strrchr(path, DIRSEP)[1] = type[0];
179 weaselp 327 #endif /* else if not SHORTNAMES */
180 rabbi 1 f = fopen(tmpname, "wb");
181     if (f == NULL)
182     errlog(ERRORMSG, "Error creating temporary file %s\n", tmpname);
183     return (f);
184     }
185    
186     int pool_read(BUFFER *pool)
187     {
188     DIR *d;
189     struct dirent *e;
190     int size = 0;
191    
192     d = opendir(POOLDIR);
193     if (d != NULL)
194     for (;;) {
195     e = readdir(d);
196     if (e == NULL)
197     break;
198     if (is(e->d_name, "msg")) {
199     if (pool != NULL) {
200     buf_appends(pool, e->d_name);
201     buf_appendc(pool, 0);
202     }
203     size++;
204     }
205     }
206     closedir(d);
207     return (size);
208     }
209    
210     void pool_dosend(void)
211     {
212     DIR *d;
213     struct dirent *e;
214     char path[PATHMAX];
215    
216     d = opendir(POOLDIR);
217     if (d != NULL) {
218     for (;;) {
219     e = readdir(d);
220     if (e == NULL)
221     break;
222     if (is(e->d_name, "snd")) {
223     sendmail_begin();
224     mv(e->d_name, "tmp");
225 rabbi 11 sprintf(path, "%s%c%s", POOLDIR, DIRSEP, e->d_name);
226 rabbi 1 if (msg_send(path) == 1)
227     mv(e->d_name, "err");
228     }
229     }
230     closedir(d);
231     }
232     sendmail_end();
233     }
234    
235     int pool_send(void)
236     {
237     int size, max, i, r;
238     BUFFER *pool;
239 weaselp 120 long int *ptr;
240 rabbi 1
241     infile_read();
242     latent_read();
243     pool = buf_new();
244     size = pool_read(pool);
245     if (size <= POOLSIZE)
246     goto end;
247    
248 weaselp 120 ptr = malloc(size * sizeof(long int));
249 rabbi 1
250     if (ptr == NULL)
251     goto end;
252     for (i = 0; i < size; i++) {
253     ptr[i] = pool->ptr;
254     buf_getline(pool, NULL);
255     }
256    
257     max = size * RATE / 100; /* send no more than RATE % of the messages */
258     if (max < 0)
259     max = 1;
260    
261     for (i = 0; i < size - POOLSIZE && i < max; i++) {
262     do
263     r = rnd_number(size); /* chose a new random message */
264     while (is(pool->data + ptr[r], "snd"));
265     mv(pool->data + ptr[r], "snd");
266     }
267     stats_out(size - --i);
268     pool_dosend();
269     free(ptr);
270    
271     end:
272     buf_free(pool);
273     return (size);
274     }
275    
276     int msg_send(char *name)
277     {
278     FILE *f;
279     int type = -1;
280     BUFFER *m, *addr;
281     int err = 0;
282     char line[LINELEN];
283     int userfrom = 0;
284    
285     m = buf_new();
286     addr = buf_new();
287     if ((f = fopen(name, "rb")) == NULL) {
288     err = -1;
289     goto end;
290     }
291     fscanf(f, "%d %*d\n", &type);
292     if (type == INTERMEDIATE) {
293     fgets(line, sizeof(line), f);
294     buf_sets(addr, line);
295     buf_chop(addr);
296     err = buf_read(m, f);
297     if (err == -1)
298     goto end;
299     err = mix_armor(m);
300     if (err == -1)
301     goto end;
302     err = sendmail(m, REMAILERADDR, addr);
303     } else if (type == MSG_MAIL || type == MSG_POST) {
304     err = buf_read(m, f);
305     if (err == -1)
306     goto end;
307     if (MIDDLEMAN && ! allowmessage(m))
308     mix2_encrypt(type, m, FORWARDTO, 1, NULL);
309     else {
310     err = filtermsg(m);
311     if (err == 1)
312     userfrom = 1, err = 0;
313     if (err != -1) {
314     /* message has recipients */
315     errlog(DEBUGINFO, "Sending message (%ld bytes)\n", m->length);
316    
317     if (type == MSG_MAIL)
318     err = sendmail(m, userfrom ? NULL : ANONNAME, NULL);
319     else if (type == MSG_POST) {
320     if (strchr(NEWS, '@') && !strchr(NEWS, ' ')) {
321     errlog(LOG, "Mailing article to %s.\n", NEWS);
322     buf_sets(addr, NEWS);
323     err = sendmail(m, userfrom ? NULL : ANONNAME, addr);
324     } else if (NEWS[0] != '\0') {
325     FILE *f;
326    
327     f = openpipe(NEWS);
328     if (f == NULL)
329     goto end;
330     errlog(LOG, "Posting article.\n");
331     if (!userfrom)
332     fprintf(f, "From: %s\n", ANONNAME);
333     if (ORGANIZATION[0] != '\0')
334     fprintf(f, "Organization: %s\n", ORGANIZATION);
335     buf_write(m, f);
336     closepipe(f);
337     } else
338     errlog(NOTICE, "Rejecting news article.\n");
339     }
340     } else
341     errlog(ERRORMSG, "Bad message file.\n");
342     }
343     }
344 rabbi 61 end:
345 rabbi 47 if (f != NULL)
346     fclose(f);
347 rabbi 1 if (err != 1) /* problem sending mail */
348     unlink(name);
349     buf_free(m);
350     buf_free(addr);
351     return (err);
352     }
353    
354     int allowmessage(BUFFER *in)
355     /* Only called if remailer is middleman. Checks whether all Recipient
356     * addresses are in dest.allow. If yes return 1; 0 otherwhise
357     */
358     {
359     BUFFER *out, *allow, *line, *line2;
360     int err=1;
361     FILE *f;
362    
363     allow = buf_new();
364     out = buf_new();
365     line = buf_new();
366     line2 = buf_new();
367    
368     f = mix_openfile(DESTALLOW, "r");
369     if (f != NULL) {
370     buf_read(allow, f);
371     fclose(f);
372     }
373    
374     /* Do header lines */
375     while (buf_getline(in, line) == 0) {
376     for (;;) {
377     buf_lookahead(in, line2);
378     if (!bufleft(line2, " ") && !bufleft(line2, "\t"))
379     break;
380     buf_getline(in, line2);
381     buf_cat(line, line2);
382     }
383    
384     if (bufileft(line, "to:") || bufileft(line, "cc:") ||
385     bufileft(line, "bcc:") || bufileft(line, "newsgroups:"))
386     if (! doallow(line, allow))
387     err = 0;
388    
389     if (line->length > 0) {
390     if (!buffind(line, ":"))
391     buf_appends(out, "X-Invalid: ");
392     buf_cat(out, line);
393     buf_nl(out);
394     }
395     }
396     buf_nl(out);
397    
398     /* Rest of the message */
399     buf_append(out, in->data + in->ptr, in->length - in->ptr);
400    
401     buf_move(in, out);
402     buf_free(out);
403     buf_free(allow);
404     buf_free(line);
405     buf_free(line2);
406     return (err);
407 weaselp 121 }
408 rabbi 1
409     int doallow(BUFFER *line, BUFFER *filter)
410     /* line is a To, CC or BCC line.
411     * problem is: there may be multiple addresses in one header
412     * line but we only want to allow if _all_ are allowed
413     *
414     * So to not send direct if we do not want, we _never_ send
415     * direct if there is more than one address: This is
416     * assumed to be the case when there is a
417     * comma in the header line.
418     *
419     * this should probably be rewritten somehwhen. therefore: FIXME
420     *
421     * returns: 1 if allowed
422     * 0 if message should be send indirectly
423     */
424     {
425     if (strchr( line->data, ',')) return 0;
426     return doblock(line, filter, 0);
427     }
428    
429     int filtermsg(BUFFER *in)
430     {
431     BUFFER *out, *line, *line2, *mboundary, *block, *filter, *mid;
432     FILE *f;
433     int from = 0, dest = 0;
434     int inbinary = 0, inpgp = 0, l = 80;
435     int err = -1;
436    
437     line = buf_new();
438     line2 = buf_new();
439     filter = buf_new();
440     mid = buf_new();
441     mboundary = buf_new();
442     out = buf_new();
443 rabbi 5 block = NULL;
444 rabbi 1
445     if (SIZELIMIT > 0 && in->length > SIZELIMIT * 1024) {
446     errlog(NOTICE, "Message rejected: %ld bytes\n", in->length);
447     goto end;
448     }
449    
450     block = readdestblk( );
451     if ( !block ) block = buf_new( );
452    
453     f = mix_openfile(HDRFILTER, "r");
454     if (f != NULL) {
455     buf_read(filter, f);
456     fclose(f);
457     }
458    
459     f = mix_openfile(DISCLAIMFILE, "r");
460     if (f != NULL) {
461     buf_read(out, f);
462     fclose(f);
463     } else {
464     if (strfind(DISCLAIMER, "%s"))
465     buf_appendf(out, DISCLAIMER, COMPLAINTS);
466     else
467     buf_appends(out, DISCLAIMER);
468     }
469    
470     while (buf_getline(in, line) == 0) {
471     for (;;) {
472     buf_lookahead(in, line2);
473     if (!bufleft(line2, " ") && !bufleft(line2, "\t"))
474     break;
475     buf_getline(in, line2);
476     buf_cat(line, line2);
477     }
478    
479     if (bufileft(line, "to:") || bufileft(line, "cc:") ||
480     bufileft(line, "bcc:") || bufileft(line, "newsgroups:"))
481     if (doblock(line, block, 1) == 0)
482     dest++;
483     if (doblock(line, filter, 1) == -1)
484     goto end;
485     if (bufileft(line, "from:"))
486     from = 1;
487    
488     if (bufileft(line, "content-type:") && bufileft(line, "multipart"))
489     get_parameter(line, "boundary", mboundary);
490    
491     if (line->length > 0) {
492     if (!buffind(line, ":"))
493     buf_appends(out, "X-Invalid: ");
494     buf_cat(out, line);
495     buf_nl(out);
496     }
497     }
498    
499     if (MID[0] != '\0' && tolower(MID[0]) != 'n') {
500     char txt[LINELEN];
501    
502     digestmem_md5(in->data + in->ptr, in->length - in->ptr, mid);
503     id_encode(mid->data, txt);
504    
505     if (MID[0] == '@')
506     strcatn(txt, MID, sizeof(txt));
507     else {
508     if (strchr(REMAILERADDR, '@'))
509     strcatn(txt, strchr(REMAILERADDR, '@'), sizeof(txt));
510     else if (strchr(COMPLAINTS, '@'))
511     strcatn(txt, strchr(COMPLAINTS, '@'), sizeof(txt));
512     }
513     buf_appendf(out, "Message-ID: <%s>\n", txt);
514     }
515     buf_nl(out);
516    
517     if (from) {
518     /* prepend Sender line to message header */
519     buf_setf(line, "Sender: %s\n", ANONNAME);
520     buf_cat(line, out);
521     buf_move(out, line);
522    
523     f = mix_openfile(FROMDSCLFILE, "r");
524     if (f != NULL) {
525     buf_read(out, f);
526     fclose(f);
527     } else
528     buf_appends(out, FROMDISCLAIMER);
529     }
530    
531     #if 0
532     buf_append(out, in->data + in->ptr, in->length - in->ptr);
533 weaselp 327 #endif /* 0 */
534 rabbi 1 while (buf_getline(in, line) != -1) {
535     if (boundary(line, mboundary)) {
536     buf_cat(out, line);
537     buf_nl(out);
538     while (buf_getline(in, line) == 0) { /* MIME body part header */
539     err = doblock(line, filter, 1);
540     if (err == -1)
541     goto end;
542     buf_cat(out, line);
543     buf_nl(out);
544     }
545     }
546     if (BINFILTER && l > 20 && line->length == l &&
547     (bufleft(line, "M") || !buffind(line, " ")))
548     inbinary++;
549     else
550     inbinary = 0, l = line->length;
551 rabbi 50 if (bufileft(line, begin_pgp) || bufileft(line, begin_key))
552 rabbi 1 inpgp = 1;
553 rabbi 50 if (bufileft(line, end_pgp) || bufileft(line, end_key))
554 rabbi 1 inpgp = 0;
555     if (inbinary < 10 || inpgp) {
556     buf_cat(out, line);
557     buf_nl(out);
558     } else if (inbinary == 10) {
559     errlog(NOTICE, "Binary message detected.\n");
560     if (BINFILTER > 1) {
561     err = -1;
562     goto end;
563     }
564     buf_appends(out, BINDISCLAIMER);
565     buf_nl(out);
566     }
567     }
568    
569 rabbi 306 f = mix_openfile(MSGFOOTERFILE, "r");
570     if (f != NULL) {
571     buf_read(out, f);
572     fclose(f);
573     } else
574     buf_appends(out, MSGFOOTER);
575    
576 rabbi 1 /* return 1 for user supplied From line */
577     err = from;
578     if (dest == 0)
579     err = -1;
580    
581     end:
582     buf_move(in, out);
583     buf_free(out);
584     buf_free(line);
585     buf_free(line2);
586 rabbi 5 if (block) buf_free(block);
587 rabbi 1 buf_free(filter);
588     buf_free(mid);
589     buf_free(mboundary);
590     return (err);
591     }
592    
593     BUFFER *readdestblk( )
594     {
595     char *destblklst = (char *)malloc( strlen( DESTBLOCK )+1 );
596     char *destblk = NULL;
597     FILE *f;
598     BUFFER *addresses;
599     BUFFER *temp;
600     int err = 1;
601    
602     addresses = buf_new( );
603     temp = buf_new( );
604    
605     strcpy( destblklst, DESTBLOCK );
606    
607     while ( (destblk = strtok( destblk ? NULL : destblklst, " " )) )
608     {
609     if ( (f = mix_openfile( destblk, "r" )) )
610     {
611     if ( !buf_read( temp, f ) )
612     {
613     buf_cat( addresses, temp );
614     err = 0;
615     }
616     fclose( f );
617     }
618     }
619    
620     free( destblklst );
621     buf_free( temp );
622    
623     if ( err ) { buf_free( addresses ); return NULL; }
624     else return addresses;
625     }
626    
627     int doblock(BUFFER *line, BUFFER *filter, int logandreset)
628     /* logandreset is usually 0
629     * it is only set to 1 when called from doallow
630     * which only checks whether messages are allowed to
631     * be sent directly
632     */
633     {
634     int block = 0;
635     BUFFER *pattern, *result;
636     char *t;
637     #ifdef USE_PCRE
638     int errptr, match;
639     const char *error;
640     pcre *compiled;
641     int ovector[21];
642     char *newstr;
643 weaselp 327 #endif /* USE_PCRE */
644 rabbi 1
645     pattern = buf_new();
646     result = buf_new();
647     assert(filter != NULL);
648    
649     buf_rewind(filter);
650     while (buf_getline(filter, pattern) != -1)
651     if (pattern->length > 0 && !bufleft(pattern, "#")) {
652     if (bufleft(pattern, "/") && (t = strchr(pattern->data + 1, '/'))
653     != NULL) {
654     #ifdef USE_PCRE
655     *t = '\0';
656     compiled = pcre_compile(pattern->data + 1, PCRE_CASELESS,
657     &error, &errptr
658     #ifndef USE_PCRE_OLD
659     ,NULL
660 weaselp 327 #endif /* not USE_PCRE_OLD */
661 rabbi 1 );
662     if (compiled) {
663     match = pcre_exec(compiled, NULL, line->data,
664     line->length,
665     #if (PCRE_MAJOR == 2 && PCRE_MINOR >= 06)
666     0,
667 weaselp 327 #endif /* (PCRE_MAJOR == 2 && PCRE_MINOR >= 06) */
668 rabbi 1 #if (PCRE_MAJOR >= 3)
669     0,
670 weaselp 327 #endif /* (PCRE_MAJOR >= 3) */
671 rabbi 1 0, ovector, sizeof(ovector) / sizeof(int));
672     free(compiled);
673    
674     if (match < -1) {
675     *t = '/';
676     errlog(ERRORMSG, "Bad regexp %b\n", pattern);
677     }
678     else if (match >= 0) {
679     /* "/pattern/q" kills the entire message */
680     if (logandreset
681     && strlen(pattern->data + 1) + 1 < pattern->length
682     && pattern->data[pattern->length - 1] == 'q') {
683     *t = '/';
684     errlog(NOTICE,
685     "Message rejected: %b matches %b.\n", line, pattern);
686     block = -1;
687     break;
688     }
689     if (strlen(pattern->data + 1) + 1 < pattern->length
690     && pattern->data[pattern->length - 1] == '/') {
691     pattern->data[pattern->length - 1] = '\0';
692     newstr = pattern->data + strlen(pattern->data) + 1;
693     buf_reset(result);
694     buf_append(result, line->data, ovector[0]);
695     while (strchr(newstr, '$')) {
696     strchr(newstr, '$')[0] = '\0';
697     buf_appends(result, newstr);
698     newstr += strlen(newstr) + 1;
699     if (*newstr >= '1' && *newstr <= '9')
700     buf_append(result, line->data +
701     ovector[2 * (*newstr - '0')],
702     ovector[2 * (*newstr - '0') + 1] -
703     ovector[2 * (*newstr - '0')]);
704     newstr++;
705     }
706     buf_appends(result, newstr);
707     buf_appends(result, line->data + ovector[1]);
708     buf_clear(line);
709     buf_appends(line, result->data);
710     } else {
711     block = 1;
712     *t = '/';
713     if (logandreset)
714     errlog(NOTICE, "Blocked header line: %b matches %b.\n",
715     line, pattern);
716     }
717     }
718     } else {
719     *t = '/';
720     errlog(ERRORMSG, "Bad regexp %b\n", pattern);
721     }
722 weaselp 327 #else /* end of USE_PCRE */
723 rabbi 1 errlog(ERRORMSG, "No regexp support! Ignoring %b\n", pattern);
724 weaselp 327 #endif /* else if not USE_PCRE */
725 rabbi 1 } else if (bufifind(line, pattern->data)) {
726     if (logandreset )
727     errlog(NOTICE, "Blocked header line: %b matches %b.\n",
728     line, pattern);
729     block = 1;
730     }
731     }
732    
733     if (logandreset && (block == 1))
734     buf_reset(line);
735    
736     buf_free(pattern);
737     buf_free(result);
738     return (block);
739     }
740    
741     int mix_armor(BUFFER *in)
742     {
743     BUFFER *out, *md;
744    
745     md = buf_new();
746     out = buf_new();
747    
748     if (in->length != 20480)
749     return (-1);
750    
751     buf_sets(out, "\n::\n");
752     buf_appends(out, remailer_type);
753     buf_appends(out, VERSION);
754     buf_nl(out);
755     buf_nl(out);
756     buf_appends(out, begin_remailer);
757     buf_nl(out);
758     buf_appends(out, "20480\n");
759     digest_md5(in, md);
760     encode(md, 0);
761     buf_cat(out, md);
762     buf_nl(out);
763     encode(in, 40);
764     buf_cat(out, in);
765     buf_appends(out, end_remailer);
766     buf_nl(out);
767    
768     buf_move(in, out);
769     buf_free(out);
770     buf_free(md);
771     return (0);
772     }

  ViewVC Help
Powered by ViewVC 1.1.5