/[anubis]/anubis/src/tunnel.c
ViewVC logotype

Diff of /anubis/src/tunnel.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.9 by polak, Tue Feb 11 21:08:56 2003 UTC revision 1.10 by gray, Mon Feb 17 20:54:04 2003 UTC
# Line 29  Line 29 
29  #define obstack_chunk_free free  #define obstack_chunk_free free
30  #include <obstack.h>  #include <obstack.h>
31    
 typedef int (*read_fn_t)(void *data, char *buf, size_t size);  
   
32  static int  transfer_command(void *, void *, char *);  static int  transfer_command(void *, void *, char *);
33  static void process_command(void *, void *, char *, int);  static void process_command(void *, void *, char *, int);
34  static void transfer_header(void *, void *, read_fn_t, void *);  static void transfer_header(void *, void *, struct list *list);
35  static void process_header_line(char *);  static void process_header_line(char *);
36  static void transfer_body(void *, void *, read_fn_t, void *);  static void transfer_body(void *, void *);
 static void static_body_transfer(void *, void *, read_fn_t, void *);  
 static void dynamic_body_transfer(void *, void *, read_fn_t, void *);  
 static void clear_body_transfer(void *, void *);  
37  static void add_remailer_commands(void *);  static void add_remailer_commands(void *);
38  static void transform_body(void *sd_server);  static void transform_body(void *sd_server);
39  static void process_data(void *sd_client, void *sd_server);  static void process_data(void *sd_client, void *sd_server);
40    
41  static void collect_body(void *sd_client, char **retptr);  
42  static void collect_headers(void *sd_client, struct list **listp);  /* Auxiliary list handling functions */
43    /* These belong to the future list.c */
44    typedef int (*list_iterator_t)(struct list *list, void *data);
45    
46  int  void
47  socket_reader(void *sd_client, char *buf, size_t size)  list_iterate(struct list *p, list_iterator_t itr, void *data)
48  {  {
49          return recvline(SERVER, sd_client, buf, size);          while (p) {
50                    struct list *q = p->next;
51                    itr(p, data);
52                    p = q;
53            };
54  }  }
55    
 enum buf_state {  
         state_init,  
         state_end,  
         state_finish  
 };  
           
 struct mem_buf {  
         char *buffer;  
         size_t pos;  
         size_t size;  
         enum buf_state state;  
 };  
   
56  void  void
57  init_mem_buf(struct mem_buf *mb, char *buf)  list_append(struct list **a, struct list *b)
58  {  {
59          memset(mb, 0, sizeof(*mb));          if (!*a)
60          mb->buffer = buf;                  *a = b;
61          mb->size = strlen(buf);          else {
62          mb->pos = 0;                  struct list *p;
63          mb->state = state_init;                  
64                    for (p = *a; p->next; p = p->next)
65                            ;
66                    p->next = b;
67            }
68  }  }
69    
70  int  
71  memory_reader(void *closure, char *buf, size_t size)  /* Collect and send headers */
72    
73    /* Headers spanning multiple lines are wrapped into a single line, preserving
74       the newlines. When sending to the server they are split again at newlines
75       snd sent in multiline lines. */
76      
77    static void
78    get_boundary(char *line)
79  {  {
80          struct mem_buf *mb = closure;          char boundary_buf[LINEBUFFER+1], *p;
         int i = 0;  
         int crlf;  
           
         switch (mb->state) {  
         case state_init:  
                 crlf = 0;  
                 size--; /* make space for terminating zero */  
                 for (i = 0; i < size; i++) {  
                         if (mb->pos == mb->size) {  
                                 mb->state = state_end;  
                                 break;  
                         }  
                         *buf++ = mb->buffer[mb->pos++];  
                         if (i > 2 && buf[-2] == '\r' && buf[-1] == '\n') {  
                                 crlf = 1;  
                                 break;  
                         }  
                 }  
81    
82                  if (!crlf) {          if (strncmp(line, "Content-Type:", 13))
83                          strcpy(buf, CRLF);                  return;
84                          i += 2;          
85                          buf += 2;          safe_strcpy(boundary_buf, line);
86                  }          change_to_lower(boundary_buf);
87                  *buf = 0;          p = strstr(boundary_buf, "boundary=");
88                  break;          if (!p)
89                    return;
90          case state_end:          p += 9;
91                  if (size < 4)          if (*p == '"') {
92                          i = 0;                  char *q = strchr(++p, '"');
93                  else {                  if (*q)
94                          strcpy(buf, "." CRLF);                          *q = 0;
95                          i = 3;          }
96            message.boundary = xmalloc(strlen(p) + 3);
97            sprintf(message.boundary, "--%s", p);
98            topt |= T_BOUNDARY;
99    }
100    
101    static void
102    collect_headers(void *sd_client, struct list **listp)
103    {
104            struct list *tail;
105            char buf[LINEBUFFER+1];
106    
107            *listp = tail = NULL;
108            while (recvline(SERVER, sd_client, buf, LINEBUFFER)) {
109                    if (strncmp(buf, CRLF, 2) == 0)
110                            break;
111                    remcrlf(buf);
112                    if (isspace(buf[0])) {
113                            if (!tail)
114                                    /* Something wrong, assume we've got no
115                                       headers */
116                                    break;
117                            tail->line = xrealloc(tail->line,
118                                                  strlen(tail->line) +
119                                                  strlen(buf) + 2);
120                            strcat(tail->line, "\n");
121                            strcat(tail->line, buf);
122                    } else {
123                            if (!(topt & (T_BOUNDARY|T_ENTIRE_BODY)) && tail)
124                                get_boundary(tail->line);
125                            tail = new_element(tail, listp, buf);
126                  }                  }
                 break;  
                   
         case state_finish:  
                 i = 0;  
127          }          }
         return i;  
128  }  }
129    static void
130    write_header_line (void *sd_server, char *line)
131    {
132            char *p;
133    
134  struct list_buf {          p = strtok(line, "\n");
135          struct list *list;          do {
136          enum buf_state state;                  swrite(CLIENT, sd_server, p);
137  };                  swrite(CLIENT, sd_server, CRLF);
138            } while (p = strtok(NULL, "\n"));
139    }
140                            
141  void  void
142  init_list_buf(struct list_buf *lb, struct list *list)  send_header (void *sd_server, struct list **plist)
143  {  {
144          lb->list = list;          struct list *p;
145          lb->state = state_init;          p = *plist;
146  }          while (p) {
147                    struct list *q = p->next;
148                    write_header_line(sd_server, p->line);
149                    free(p->line);
150                    free(p);
151                    p = q;
152            }
153            *plist = NULL;
154    }
155    
156    
157    /* Collect and sent the message body */
158    
159    /* When read each CRLF is replaced by a single newline.
160       When sent, the reverse procedure is performed.
161    
162       The handling of MIME encoded messages depends on the
163       setting of T_ENTIRE_BODY bit in topt. If the bit is set, the
164       entire body is read into memory. Otherwise, only the first
165       part is read and processed, all the rest is passed to the
166       server verbatim. */
167    
168    #define ST_INIT  0
169    #define ST_HDR   1
170    #define ST_BODY  2
171    #define ST_DONE  3
172    
173  int  static void
174  list_reader(void *closure, char *buf, size_t size)  collect_body(void *sd_client, char **retptr)
175  {  {
176          struct list_buf *lb = closure;          int nread;
177            char buf[LINEBUFFER+1];
178            struct obstack stk;
179            int state = 0;
180            struct list *tail = NULL;
181            int len;
182    
183          switch (lb->state) {          if (topt & T_BOUNDARY)
184          case state_init:                  len = strlen(message.boundary);
185                  if (!lb->list) {          
186                          lb->state = state_finish;          obstack_init (&stk);
187                          strncpy(buf, CRLF, size);          while (state != ST_DONE
188                   && (nread = recvline(SERVER, sd_client, buf, LINEBUFFER))) {
189                    if (strncmp(buf, "."CRLF, 3) == 0) /* EOM */
190                            break;
191                    
192                    remcrlf(buf);
193                    
194                    if (topt & T_BOUNDARY) {
195                            switch (state) {
196                            case ST_INIT:
197                                    if (strcmp(buf, message.boundary) == 0)
198                                            state = ST_HDR;
199                                    break;
200    
201                            case ST_HDR:
202                                    if (buf[0] == 0)
203                                            state = ST_BODY;
204                                    else
205                                            tail = new_element(tail,
206                                                               &message.mime_hdr,
207                                                               buf);
208                                    break;
209    
210                            case ST_BODY:
211                                    if (strncmp(buf, message.boundary, len) == 0)
212                                            state = ST_DONE;
213                                    else {
214                                            obstack_grow(&stk, buf, strlen(buf));
215                                            obstack_1grow(&stk, '\n');
216                                    }
217                            }
218                  } else {                  } else {
219                          strncpy(buf, lb->list->line, size);                          obstack_grow(&stk, buf, strlen(buf));
220                          lb->list = lb->list->next;                          obstack_1grow(&stk, '\n');
221                  }                  }
                 return strlen(buf);  
   
         default:  
                 return 0;  
222          }          }
223            obstack_1grow(&stk, 0);
224            *retptr = strdup(obstack_finish(&stk));
225            obstack_free(&stk, NULL);
226  }  }
227    
228    void
229    send_body(void *sd_server)
230    {
231            char *p;
232    
233            if (topt & T_BOUNDARY) {
234                    swrite(CLIENT, sd_server, message.boundary);
235                    swrite(CLIENT, sd_server, CRLF);
236                    send_header(sd_server, &message.mime_hdr);
237                    swrite(CLIENT, sd_server, CRLF);
238            }
239    
240            for (p = message.body; *p; ) {
241                    char *q = strchr(p, '\n');
242                    if (q)
243                            *q++ = 0;
244                    else
245                            q = p + strlen(p);
246                    
247                    swrite(CLIENT, sd_server, p);
248                    swrite(CLIENT, sd_server, CRLF);
249                    p = q;
250            }
251    
252            if (topt & T_BOUNDARY) {
253                    swrite(CLIENT, sd_server, message.boundary);
254                    swrite(CLIENT, sd_server, CRLF);
255            }
256    }
257    
258    
259  /******************  /******************
260    The Tunnel core    The Tunnel core
261  *******************/  *******************/
# Line 491  transfer_command(void *sd_client, void * Line 591  transfer_command(void *sd_client, void *
591          return 1; /* OK */          return 1; /* OK */
592  }  }
593    
 static void  
 collect_headers(void *sd_client, struct list **listp)  
 {  
         struct list *tail;  
         char buf[LINEBUFFER+1];  
   
         *listp = tail = NULL;  
         while (recvline(SERVER, sd_client, buf, LINEBUFFER))  
         {  
                 if (strncmp(buf, CRLF, 2) == 0)  
                         break;  
   
                 tail = new_element(tail, listp, buf);  
         }  
 }  
                   
 static void  
 collect_body(void *sd_client, char **retptr)  
 {  
         int nread;  
         char body_line[LINEBUFFER+1];  
         struct obstack stk;  
   
         obstack_init (&stk);  
         while ((nread = recvline(SERVER, sd_client, body_line, LINEBUFFER))) {  
                 if (strncmp(body_line, "."CRLF, 3) == 0) /* EOM */  
                         break;  
                 obstack_grow(&stk, body_line, strlen (body_line));  
         }  
         obstack_1grow(&stk, 0);  
         *retptr = strdup(obstack_finish(&stk));  
         obstack_free(&stk, NULL);  
 }  
   
594  void  void
595  process_data(void *sd_client, void *sd_server)  process_data(void *sd_client, void *sd_server)
596  {  {
597          struct list *message_hdr;          struct list *message_hdr;
598          struct mem_buf mb;          char buf[LINEBUFFER+1];
         struct list_buf lb;  
599    
600          alarm(1800);          alarm(1800);
601    
602          collect_headers(sd_client, &message_hdr);          collect_headers(sd_client, &message_hdr);
603          collect_body(sd_client, &message.body);          collect_body(sd_client, &message.body);
604    
605          init_list_buf(&lb, message_hdr);          transfer_header(sd_client, sd_server, message_hdr);
606          transfer_header(sd_client, sd_server, list_reader, &lb);          transform_body(sd_server);
607            transfer_body(sd_client, sd_server);
608    
609          init_mem_buf(&mb, message.body);          recvline(CLIENT, sd_server, buf, LINEBUFFER);
610          transfer_body(sd_client, sd_server, memory_reader, &mb);          swrite(SERVER, sd_client, buf);
611    
612          /* FIXME:          /* FIXME: xfree(message_body); */
            destroy_list(&message_hdr);  
            xfree(message_body); */  
613    
614          alarm(0);          alarm(0);
615  }  }
# Line 554  process_data(void *sd_client, void *sd_s Line 618  process_data(void *sd_client, void *sd_s
618    MESSAGE HEADER    MESSAGE HEADER
619  ******************/  ******************/
620    
621  static void  struct header_data {
622  transfer_header(void *sd_client, void *sd_server,          void *sd_client;
623                  read_fn_t readfn, void *closure)          void *sd_server;
624  {          struct list *header;
625          struct list *header_buf = NULL;  };
         struct list *header_tail = NULL;  
         struct list *p1;  
         struct list *p2;  
         char header_line[LINEBUFFER+1];  
626    
627          while (readfn(closure, header_line, LINEBUFFER)) {  struct closure {
628                  if (strncmp(header_line, CRLF, 2) == 0)          RC_REGEX *regex;
629                          break;          char *modify;
630            struct list *head, *tail;
631    };
632    
633                  process_header_line(header_line);  int
634                  header_tail = new_element(header_tail,  action_remove2(struct list *p, void *data)
635                                            &header_buf, header_line);  {
636            struct closure *clos = data;
637            int rc, stat;
638            char **rv = NULL;
639            
640            stat = anubis_regex_match(clos->regex, p->line, &rc, &rv);
641            free_pptr(rv);
642            if (stat) {
643                    free(p->line);
644                    free(p);
645            } else {
646                    p->next = NULL;
647                    if (clos->head == NULL)
648                            clos->head = p;
649                    if (clos->tail)
650                            clos->tail->next = p;
651                    clos->tail = p;
652          }          }
653            return 0;
654    }
655    
656  #ifdef WITH_GUILE  int
657          guile_process_list(&header_buf, &message.body);  action_remove(struct list *p, void *data)
658          for (header_tail = header_buf; header_tail && header_tail->next;  {
659               header_tail = header_tail->next)          struct header_data *hp = data;
660                  ;          struct closure clos;
 #endif /* WITH_GUILE */  
                   
         if (message.remlist) {  
                 struct list *h1;  
                 struct list *h2;  
                 struct list *previous;  
                 char hline[LINEBUFFER+1];  
   
                 p1 = message.remlist;  
                 do {  
                         p2 = p1->next;  
                         h1 = header_buf;  
                         previous = NULL;  
   
                         do {  
                                 h2 = h1->next;  
                                 strncpy(hline, h1->line, LINEBUFFER);  
                                 remcrlf(hline);  
                                 if (regex_match(p1->line, hline)) {  
                                         if (previous)  
                                                 previous->next = h2;  
                                         else  
                                                 header_buf = h2;  
                                         free(h1->line);  
                                         free(h1);  
                                         if (h2)  
                                                 h1 = h2;  
                                 }  
                                 else {  
                                         if (h2) {  
                                                 previous = h1;  
                                                 h1 = h2;  
                                         }  
                                 }  
                         } while (h2 != NULL);  
661    
662                          free(p1->line);          clos.regex = anubis_regex_compile(p->line, 0);
663                          free(p1);          clos.head = clos.tail = NULL;
664                          if (p2)          list_iterate(hp->header, action_remove2, &clos);
665                                  p1 = p2;          hp->header = clos.head;
666                  } while (p2 != NULL);          anubis_regex_free(clos.regex);
667                  message.remlist = NULL;          free(p->line);
668          }          free(p);
669            return 0;
670          if (message.addlist) {  }
                 p1 = message.addlist;  
                 do {  
                         p2 = p1->next;  
                         strncpy(header_line, p1->line, LINEBUFFER-2);  
                         strcat(header_line, CRLF);  
                         header_tail = new_element(header_tail, &header_buf, header_line);  
                         free(p1->line);  
                         free(p1);  
                         if (p2)  
                                 p1 = p2;  
                 } while (p2 != NULL);  
                 message.addlist = NULL;  
         }  
   
         if (message.modlist) {  
                 struct list *h1;  
                 struct list *h2;  
                 char hline[LINEBUFFER+1];  
   
                 p1 = message.modlist;  
                 do {  
                         p2 = p1->next;  
                         h1 = header_buf;  
671    
672                          do {  int
673                                  h2 = h1->next;  action_mod2(struct list *p, void *data)
674                                  strncpy(hline, h1->line, LINEBUFFER);  {
675                                  remcrlf(hline);          struct closure *clos = data;
676                                  if (regex_match(p1->line, hline)) {          int rc, stat;
677                                          char *outbuf = substitute(p1->modify,          char **rv = NULL;
678                                                                    submatch);          
679                                          free(h1->line);          stat = anubis_regex_match(clos->regex, p->line, &rc, &rv);
680                                          if (outbuf)          if (stat) {
681                                                  h1->line = outbuf;                  free(p->line);
682                                          else                  p->line = substitute(clos->modify, rv);
683                                                  h1->line = strdup(p1->modify);                  if (!p->line)
684                                  }                          p->line = strdup(clos->modify);
685                                  if (h2)                  free_pptr(rv);
                                         h1 = h2;  
                         } while (h2 != NULL);  
   
                         free(p1->line);  
                         free(p1->modify);  
                         free(p1);  
                         if (p2)  
                                 p1 = p2;  
                 } while (p2 != NULL);  
                 message.modlist = NULL;  
686          }          }
687            return 0;
688    }
689    
690  #ifdef WITH_GUILE  int
691          guile_postprocess_list(&header_buf, &message.body);  action_mod(struct list *p, void *data)
692  #endif /* WITH_GUILE */  {
693            struct header_data *hp = data;
694            struct closure clos;
695    
696          p1 = header_buf;          clos.regex = anubis_regex_compile(p->line, 0);
697          do {          clos.head = clos.tail = NULL;
698                  p2 = p1->next;          clos.modify = p->modify;
699            list_iterate(hp->header, action_mod2, &clos);
700            anubis_regex_free(clos.regex);
701            free(p->line);
702            free(p);
703            return 0;
704    }
705    
706                  /*  int
707                     If there are any attachments, find the BOUNDARY.  action_free(struct list *p, void *data)
708                  */  {
709            free(p->line);
710            free(p);
711            return 0;
712    }
713    
714                  if (strncmp(p1->line, "Content-Type:", 13) == 0) {  static void
715                          if (mopt & M_BODYCLEARAPPEND) {  transfer_header(void *sd_client, void *sd_server, struct list *header_buf)
716                                  message.remlist_tail = new_element(message.remlist_tail,  {
717                                          &message.remlist, "^Content-Type:");          struct list *p;
718                                  message.remlist_tail = new_element(message.remlist_tail,          struct header_data hd;
719                                          &message.remlist, "^Content-Transfer-Encoding:");          
720                          }          hd.sd_server = sd_server;
721                          else {          hd.sd_client = sd_client;
722                                  char *ptr1 = 0;          hd.header = header_buf;
                                 char *ptr2 = 0;  
                                 char boundary_buf[LINEBUFFER+1];  
                                 struct list *plist = p1;  
   
                                 safe_strcpy(boundary_buf, plist->line);  
                                 change_to_lower(boundary_buf);  
   
                                 ptr1 = strstr(boundary_buf, "boundary=");  
                                 if (ptr1 == 0) {  
                                         plist = plist->next;  
                                         safe_strcpy(boundary_buf, plist->line);  
                                         change_to_lower(boundary_buf);  
                                         ptr1 = strstr(boundary_buf, "boundary=");  
                                 }  
723    
724                                  if (ptr1) {          for (p = hd.header; p; p = p->next)
725                                          topt |= T_BOUNDARY;                  process_header_line(p->line);
726                                          safe_strcpy(boundary_buf, plist->line);          
727    #ifdef WITH_GUILE
728                                          ptr2 = strchr(boundary_buf, '=');          guile_process_list(&header_buf, &message.body);
729                                          if (!ptr2)  #endif /* WITH_GUILE */
730                                                  ptr2 = boundary_buf;          
731                                          else          list_iterate(message.remlist, action_remove, &hd);
732                                                  ptr2 = parse_line_option(ptr2);          message.remlist = NULL;
                                         message.boundary = (char *)xmalloc(strlen(ptr2) + 3);  
                                         if (*ptr2 == '"') {  
                                                 ptr2++;  
                                                 sprintf(message.boundary, "--%s", ptr2);  
                                                 ptr2 = strstr(message.boundary, "\"");  
                                                 *ptr2 = '\0';  
                                         }  
                                         else  
                                                 sprintf(message.boundary, "--%s", ptr2);  
                                 }  
                         }  
                 }  
733    
734                  swrite(CLIENT, sd_server, p1->line);          list_append(&hd.header, message.addlist);
735                  free(p1->line);          message.addlist = NULL;
736                  free(p1);          
737                  if (p2)          list_iterate(message.modlist, action_mod, &hd);
738                          p1 = p2;          message.modlist = NULL;
739          } while (p2 != NULL);          
740          header_buf = NULL;  #ifdef WITH_GUILE
741            guile_postprocess_list(&hd.header, &message.body);
742    #endif /* WITH_GUILE */
743    
744            send_header(sd_server, &hd.header);
745          swrite(CLIENT, sd_server, CRLF);          swrite(CLIENT, sd_server, CRLF);
746          return;          
747            list_iterate(hd.header, action_free, NULL);
748  }  }
749    
750  static void  static void
# Line 756  process_header_line(char *header_line) Line 760  process_header_line(char *header_line)
760          p = strstr(header_line, BEGIN_TRIGGER);          p = strstr(header_line, BEGIN_TRIGGER);
761          if (p) {          if (p) {
762                  safe_strcpy(backup, p);                  safe_strcpy(backup, p);
                 *p++ = '\r';  
                 *p++ = '\n';  
763                  *p = '\0';                  *p = '\0';
764                  p = backup;                  p = backup;
765                  p += sizeof(BEGIN_TRIGGER) - 1;                  p += sizeof(BEGIN_TRIGGER) - 1;
766          }          } else
         else  
767                  p = header_line;                  p = header_line;
768    
769          rcfile_process_cond("RULE", HEADER, p);          rcfile_process_cond("RULE", HEADER, p);
# Line 773  process_header_line(char *header_line) Line 774  process_header_line(char *header_line)
774    MESSAGE BODY    MESSAGE BODY
775  ****************/  ****************/
776    
777  #define M_OPT_STATIC (M_GPG_ENCRYPT | M_GPG_SIGN | M_RM \  
  | M_SIGNATURE | M_BODYAPPEND | M_EXTBODYPROC)  
778    
779  static void  static void
780  transfer_body(void *sd_client, void *sd_server,  raw_transfer(void *sd_client, void *sd_server)
               read_fn_t readfn, void *closure)  
781  {  {
782          if (mopt & M_BODYCLEARAPPEND)          int nread;
783                  clear_body_transfer(sd_client, sd_server);          char buf[LINEBUFFER+1];
784          else {          
785                  if (mopt & M_OPT_STATIC)          while ((nread = recvline(SERVER, sd_client, buf, LINEBUFFER)) > 0) {
786                          static_body_transfer(sd_client, sd_server,                  if (strncmp(buf, "."CRLF, 3) == 0) /* EOM */
787                                               readfn, closure);                          break;
788                  else                  swrite(CLIENT, sd_server, buf);
                         dynamic_body_transfer(sd_client, sd_server,  
                                               readfn, closure);  
789          }          }
         return;  
790  }  }
791    
792  static void  void
793  static_body_transfer(void *sd_client, void *sd_server,  transfer_body(void *sd_client, void *sd_server)
                      read_fn_t readfn, void *data)  
794  {  {
         int nb = 0;  
         int nread;  
         int capacity = DATABUFFER;  
         char body_line[LINEBUFFER+1];  
   
         message.body = (char *)xmalloc(DATABUFFER);  
   
         /*  
            If there are some attachments...  
         */  
   
795          if (topt & T_BOUNDARY) {          if (topt & T_BOUNDARY) {
796                  nb = strlen(message.boundary);                  send_body(sd_server);
                 while (readfn(data, body_line, LINEBUFFER)) {  
                         swrite(CLIENT, sd_server, body_line);  
                         if (strncmp(body_line, message.boundary, nb) == 0) {  
                                 while (recvline(SERVER, sd_client, body_line, LINEBUFFER))  
                                 {  
                                         swrite(CLIENT, sd_server, body_line);  
                                         if (strncmp(body_line, CRLF, 2) == 0)  
                                                 break;  
                                 }  
                                 break;  
                         }  
                 }  
   
                 /*  
                    Now we have reached the message body...  
                 */  
   
                 while ((nread = readfn(data, body_line, LINEBUFFER)))  
                 {  
                         if (strncmp(body_line, message.boundary, nb) == 0)  
                                 break;  
   
                         capacity -= nread;  
                         if (capacity >= nread)  
                                 strcat(message.body, body_line);  
                         else {  
                                 message.body = (char *)xrealloc((char *)message.body,  
                                 strlen(message.body) + DATABUFFER + 1);  
                                 strcat(message.body, body_line);  
                                 capacity = DATABUFFER - nread;  
                         }  
                 }  
   
                 remcrlf(message.body);  
                 transform_body(sd_server);  
                 swrite(CLIENT, sd_server, message.body);  
797  #ifdef HAVE_GPG  #ifdef HAVE_GPG
798                  if ((mopt & M_GPG_ENCRYPT) || (mopt & M_GPG_SIGN))                  if ((mopt & M_GPG_ENCRYPT) || (mopt & M_GPG_SIGN))
799                          swrite(CLIENT, sd_server, CRLF);                          swrite(CLIENT, sd_server, CRLF);
800  #endif /* HAVE_GPG */  #endif /* HAVE_GPG */
801                  swrite(CLIENT, sd_server, body_line);                  
802                    /* Transfer everything else */
803                  /*                  raw_transfer(sd_client, sd_server);
804                     Transfer everything else...          } else
805                  */                  send_body(sd_server);
806            swrite(CLIENT, sd_server, "."CRLF);
                 dynamic_body_transfer(sd_client, sd_server, readfn, data);  
         }  
   
         /*  
            else... No attachments.  
         */  
   
         else {  
                 while ((nread = readfn(data, body_line, LINEBUFFER))) {  
                         if (strncmp(body_line, "."CRLF, 3) == 0) /* EOM */  
                                 break;  
   
                         capacity -= nread;  
                         if (capacity < nread) {  
                                 message.body = (char *)xrealloc((char *)message.body,  
                                 strlen(message.body) + DATABUFFER + 1);  
                                 capacity = DATABUFFER - nread;  
                         }  
                         strcat(message.body, body_line);  
                 }  
                 remcrlf(message.body);  
                 transform_body(sd_server);  
                 swrite(CLIENT, sd_server, message.body);  
                 swrite(CLIENT, sd_server, CRLF"."CRLF);  
   
                 recvline(CLIENT, sd_server, body_line, LINEBUFFER);  
                 swrite(SERVER, sd_client, body_line);  
         }  
         return;  
 }  
   
 static void  
 dynamic_body_transfer(void *sd_client, void *sd_server,  
                       read_fn_t readfn, void *data)  
 {  
         char body_line[LINEBUFFER+1];  
   
         while (readfn(data, body_line, LINEBUFFER))  
         {  
                 swrite(CLIENT, sd_server, body_line);  
                 if (strncmp(body_line, "."CRLF, 3) == 0) /* EOM */  
                         break;  
         }  
   
         recvline(CLIENT, sd_server, body_line, LINEBUFFER);  
         swrite(SERVER, sd_client, body_line);  
   
         return;  
807  }  }
808    
 static void  
 clear_body_transfer(void *sd_client, void *sd_server)  
 {  
         char body_line[LINEBUFFER+1];  
         message.body = (char *)xmalloc(1);  
   
         while (recvline(SERVER, sd_client, body_line, LINEBUFFER))  
         {  
                 if (strncmp(body_line, "."CRLF, 3) == 0) /* EOM */  
                         break;  
         }  
   
         transform_body(sd_server);  
         swrite(CLIENT, sd_server, message.body);  
         swrite(CLIENT, sd_server, body_line);  
         recvline(CLIENT, sd_server, body_line, LINEBUFFER);  
         swrite(SERVER, sd_client, body_line);  
   
         return;  
 }  
809    
810  static void  static void
811  add_remailer_commands(void *sd_server)  add_remailer_commands(void *sd_server)
# Line 978  transform_body(void *sd_server) Line 858  transform_body(void *sd_server)
858    
859  #ifdef HAVE_GPG  #ifdef HAVE_GPG
860          if (!(topt & T_ERROR) && ((mopt & M_GPG_ENCRYPT)          if (!(topt & T_ERROR) && ((mopt & M_GPG_ENCRYPT)
861          || (mopt & M_GPG_SIGN) || (mopt & M_RMGPG)))                                    || (mopt & M_GPG_SIGN) || (mopt & M_RMGPG)))
862                  check_gpg();                  check_gpg();
863  #endif /* HAVE_GPG */  #endif /* HAVE_GPG */
864    

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26