/[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.11 by gray, Wed Feb 26 16:59:15 2003 UTC revision 1.12 by gray, Fri Feb 28 15:31:13 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    
32  static int  transfer_command(void *, void *, char *);  static int  transfer_command(void *, void *, MESSAGE *msg, char *);
33  static void process_command(void *, void *, char *, int);  static void process_command(void *, void *, MESSAGE *msg, char *, int);
34  static void transfer_header(void *, void *, struct list *list);  static void transfer_header(void *, void *, struct list *list);
35  static void transfer_body(void *, void *);  static void transfer_body(void *, void *, MESSAGE *msg);
36  static void process_data(void *sd_client, void *sd_server);  static void process_data(void *sd_client, void *sd_server, MESSAGE *msg);
37    
38    
39  /* Collect and send headers */  /* Collect and send headers */
# Line 43  static void process_data(void *sd_client Line 43  static void process_data(void *sd_client
43     snd sent in multiline lines. */     snd sent in multiline lines. */
44        
45  static void  static void
46  get_boundary(char *line)  get_boundary(MESSAGE *msg, char *line)
47  {  {
48          char boundary_buf[LINEBUFFER+1], *p;          char boundary_buf[LINEBUFFER+1], *p;
49    
# Line 61  get_boundary(char *line) Line 61  get_boundary(char *line)
61                  if (*q)                  if (*q)
62                          *q = 0;                          *q = 0;
63          }          }
64          message.boundary = xmalloc(strlen(p) + 3);          msg->boundary = xmalloc(strlen(p) + 3);
65          sprintf(message.boundary, "--%s", p);          sprintf(msg->boundary, "--%s", p);
         topt |= T_BOUNDARY;  
66  }  }
67    
68  static void  static void
# Line 87  add_header(struct list *list, char *line Line 86  add_header(struct list *list, char *line
86  }  }
87    
88  static void  static void
89  collect_headers(void *sd_client, struct list **listp)  collect_headers(void *sd_client, MESSAGE *msg)
90  {  {
91          char buf[LINEBUFFER+1];          char buf[LINEBUFFER+1];
92          char *line = NULL;          char *line = NULL;
93    
94          *listp = list_create();          msg->header = list_create();
95          while (recvline(SERVER, sd_client, buf, LINEBUFFER)) {          while (recvline(SERVER, sd_client, buf, LINEBUFFER)) {
96                  remcrlf(buf);                  remcrlf(buf);
97                  if (isspace(buf[0])) {                  if (isspace(buf[0])) {
# Line 106  collect_headers(void *sd_client, struct Line 105  collect_headers(void *sd_client, struct
105                          strcat(line, buf);                          strcat(line, buf);
106                  } else {                  } else {
107                          if (line) {                          if (line) {
108                                  if (!(topt & (T_BOUNDARY|T_ENTIRE_BODY)))                                  if (!(topt & T_ENTIRE_BODY)
109                                          get_boundary(line);                                      && msg->boundary == NULL)
110                                  add_header(*listp, line);                                          get_boundary(msg, line);
111                                    add_header(msg->header, line);
112                                  line = NULL;                                  line = NULL;
113                          }                          }
114                          if (buf[0] == 0)                          if (buf[0] == 0)
# Line 137  write_assoc(void *sd_server, ASSOC *entr Line 137  write_assoc(void *sd_server, ASSOC *entr
137                  if (strcmp(entry->key, X_ANUBIS_RULE_HEADER) == 0)                  if (strcmp(entry->key, X_ANUBIS_RULE_HEADER) == 0)
138                          return;                          return;
139                  swrite(CLIENT, sd_server, entry->key);                  swrite(CLIENT, sd_server, entry->key);
140                  swrite(CLIENT, sd_server, ":");                  swrite(CLIENT, sd_server, ": ");
141          }          }
142          write_header_line(sd_server, entry->value);          write_header_line(sd_server, entry->value);
143  }  }
# Line 178  send_string_list(void *sd_server, struct Line 178  send_string_list(void *sd_server, struct
178  #define ST_DONE  3  #define ST_DONE  3
179    
180  static void  static void
181  collect_body(void *sd_client, char **retptr)  collect_body(void *sd_client, MESSAGE *msg)
182  {  {
183          int nread;          int nread;
184          char buf[LINEBUFFER+1];          char buf[LINEBUFFER+1];
# Line 186  collect_body(void *sd_client, char **ret Line 186  collect_body(void *sd_client, char **ret
186          int state = 0;          int state = 0;
187          int len;          int len;
188    
189          if (topt & T_BOUNDARY) {          if (msg->boundary) {
190                  len = strlen(message.boundary);                  len = strlen(msg->boundary);
191                  message.mime_hdr = list_create();                  msg->mime_hdr = list_create();
192          }          }
193                                                    
194          obstack_init (&stk);          obstack_init (&stk);
# Line 199  collect_body(void *sd_client, char **ret Line 199  collect_body(void *sd_client, char **ret
199                                    
200                  remcrlf(buf);                  remcrlf(buf);
201                                    
202                  if (topt & T_BOUNDARY) {                  if (msg->boundary) {
203                          switch (state) {                          switch (state) {
204                          case ST_INIT:                          case ST_INIT:
205                                  if (strcmp(buf, message.boundary) == 0)                                  if (strcmp(buf, msg->boundary) == 0)
206                                          state = ST_HDR;                                          state = ST_HDR;
207                                  break;                                  break;
208    
# Line 210  collect_body(void *sd_client, char **ret Line 210  collect_body(void *sd_client, char **ret
210                                  if (buf[0] == 0)                                  if (buf[0] == 0)
211                                          state = ST_BODY;                                          state = ST_BODY;
212                                  else                                  else
213                                          list_append(message.mime_hdr,                                          list_append(msg->mime_hdr,
214                                                      strdup(buf));                                                      strdup(buf));
215                                  break;                                  break;
216    
217                          case ST_BODY:                          case ST_BODY:
218                                  if (strncmp(buf, message.boundary, len) == 0)                                  if (strncmp(buf, msg->boundary, len) == 0)
219                                          state = ST_DONE;                                          state = ST_DONE;
220                                  else {                                  else {
221                                          obstack_grow(&stk, buf, strlen(buf));                                          obstack_grow(&stk, buf, strlen(buf));
# Line 228  collect_body(void *sd_client, char **ret Line 228  collect_body(void *sd_client, char **ret
228                  }                  }
229          }          }
230          obstack_1grow(&stk, 0);          obstack_1grow(&stk, 0);
231          *retptr = strdup(obstack_finish(&stk));          msg->body = strdup(obstack_finish(&stk));
232          obstack_free(&stk, NULL);          obstack_free(&stk, NULL);
233  }  }
234    
235  void  void
236  send_body(void *sd_server)  send_body(MESSAGE *msg, void *sd_server)
237  {  {
238          char *p;          char *p;
239    
240          if (topt & T_BOUNDARY) {          if (msg->boundary) {
241                  swrite(CLIENT, sd_server, message.boundary);                  swrite(CLIENT, sd_server, msg->boundary);
242                  swrite(CLIENT, sd_server, CRLF);                  swrite(CLIENT, sd_server, CRLF);
243                  send_string_list(sd_server, message.mime_hdr);                  send_string_list(sd_server, msg->mime_hdr);
244                  swrite(CLIENT, sd_server, CRLF);                  swrite(CLIENT, sd_server, CRLF);
245          }          }
246    
247          for (p = message.body; *p; ) {          for (p = msg->body; *p; ) {
248                  char *q = strchr(p, '\n');                  char *q = strchr(p, '\n');
249                  if (q)                  if (q)
250                          *q++ = 0;                          *q++ = 0;
# Line 256  send_body(void *sd_server) Line 256  send_body(void *sd_server)
256                  p = q;                  p = q;
257          }          }
258    
259          if (topt & T_BOUNDARY) {          if (msg->boundary) {
260                  swrite(CLIENT, sd_server, message.boundary);                  swrite(CLIENT, sd_server, msg->boundary);
261                  swrite(CLIENT, sd_server, CRLF);                  swrite(CLIENT, sd_server, CRLF);
262          }          }
263  }  }
# Line 271  void Line 271  void
271  smtp_session(void *sd_client, void *sd_server)  smtp_session(void *sd_client, void *sd_server)
272  {  {
273          char command[LINEBUFFER+1];          char command[LINEBUFFER+1];
274            MESSAGE msg;
275    
276          /*          /*
277             First of all, transfer a welcome message.             First of all, transfer a welcome message.
# Line 306  smtp_session(void *sd_client, void *sd_s Line 307  smtp_session(void *sd_client, void *sd_s
307             Then process the commands...             Then process the commands...
308          */          */
309    
310            message_init(&msg);
311          while (recvline(SERVER, sd_client, command, LINEBUFFER))          while (recvline(SERVER, sd_client, command, LINEBUFFER))
312          {          {
313                  process_command(sd_client, sd_server, command, LINEBUFFER);                  process_command(sd_client, sd_server, &msg,
314                                    command, LINEBUFFER);
315                  sd_client = remote_client;                  sd_client = remote_client;
316                  sd_server = remote_server;                  sd_server = remote_server;
317    
# Line 317  smtp_session(void *sd_client, void *sd_s Line 320  smtp_session(void *sd_client, void *sd_s
320                  if (strlen(command) == 0)                  if (strlen(command) == 0)
321                          continue;                          continue;
322    
323                  if (transfer_command(sd_client, sd_server, command) == 0)                  if (transfer_command(sd_client, sd_server, &msg, command) == 0)
324                          break;                          break;
325          }          }
326          return;          return;
# Line 328  smtp_session(void *sd_client, void *sd_s Line 331  smtp_session(void *sd_client, void *sd_s
331  *********************/  *********************/
332    
333  static void  static void
334  save_command(char *line)  save_command(MESSAGE *msg, char *line)
335  {  {
336          int i;          int i;
337          ASSOC *asc = xmalloc(sizeof(*asc));          ASSOC *asc = xmalloc(sizeof(*asc));
# Line 345  save_command(char *line) Line 348  save_command(char *line)
348                  asc->value = strdup(&line[i]);                  asc->value = strdup(&line[i]);
349          else          else
350                  asc->value = NULL;                  asc->value = NULL;
351          list_append(message.commands, asc);          list_append(msg->commands, asc);
352  }  }
353    
354  static void  static void
355  process_command(void *sd_client, void *sd_server, char *command, int size)  process_command(void *sd_client, void *sd_server, MESSAGE *msg,
356                    char *command, int size)
357  {  {
358          char buf[LINEBUFFER+1];          char buf[LINEBUFFER+1];
359          safe_strcpy(buf, command); /* make a back-up */          safe_strcpy(buf, command); /* make a back-up */
360          save_command(buf);          save_command(msg, buf);
361    
362          change_to_lower(buf);          change_to_lower(buf);
363                    
# Line 468  process_command(void *sd_client, void *s Line 472  process_command(void *sd_client, void *s
472  }  }
473    
474  static int  static int
475  transfer_command(void *sd_client, void *sd_server, char *command)  transfer_command(void *sd_client, void *sd_server, MESSAGE *msg, char *command)
476  {  {
477          char reply[2 * LINEBUFFER+1];          char reply[2 * LINEBUFFER+1];
478          char buf[LINEBUFFER+1];          char buf[LINEBUFFER+1];
# Line 590  transfer_command(void *sd_client, void * Line 594  transfer_command(void *sd_client, void *
594          if (topt & T_ERROR)          if (topt & T_ERROR)
595                  return 0;                  return 0;
596    
597          if (isdigit((unsigned char)reply[0]) && (unsigned char)reply[0] < '4') {          if (isdigit((unsigned char)reply[0])
598                && (unsigned char)reply[0] < '4') {
599                  if (strncmp(buf, "quit", 4) == 0)                  if (strncmp(buf, "quit", 4) == 0)
600                          return 0; /* The QUIT command */                          return 0; /* The QUIT command */
601                  else if (strncmp(buf, "rset", 4) == 0) {                  else if (strncmp(buf, "rset", 4) == 0) {
602                          destroy_assoc_list(&message.commands);                          message_free(msg);
                         destroy_assoc_list(&message.header);  
                         destroy_string_list(&message.mime_hdr);  
                         xfree(message.body);  
                         xfree(message.boundary);  
                         topt &= ~T_BOUNDARY;  
603                          topt &= ~T_ERROR;                          topt &= ~T_ERROR;
604                  }                  }
605                  else if (strncmp(buf, "data", 4) == 0) {                  else if (strncmp(buf, "data", 4) == 0) {
606                          process_data(sd_client, sd_server);                          process_data(sd_client, sd_server, msg);
                         xfree(message.body);  
                         xfree(message.boundary);  
                         topt &= ~T_BOUNDARY;  
607                          topt &= ~T_ERROR;                          topt &= ~T_ERROR;
608                  }                  }
609          }          }
# Line 614  transfer_command(void *sd_client, void * Line 611  transfer_command(void *sd_client, void *
611  }  }
612    
613  void  void
614  process_data(void *sd_client, void *sd_server)  process_data(void *sd_client, void *sd_server, MESSAGE *msg)
615  {  {
616          char buf[LINEBUFFER+1];          char buf[LINEBUFFER+1];
617    
618          alarm(1800);          alarm(1800);
619    
620          collect_headers(sd_client, &message.header);          collect_headers(sd_client, msg);
621          collect_body(sd_client, &message.body);          collect_body(sd_client, msg);
622    
623          rcfile_process_section(CF_CLIENT, "RULE", NULL, &message);          rcfile_process_section(CF_CLIENT, "RULE", NULL, msg);
624                    
625          transfer_header(sd_client, sd_server, message.header);          transfer_header(sd_client, sd_server, msg->header);
626          transfer_body(sd_client, sd_server);          transfer_body(sd_client, sd_server, msg);
627    
628          recvline(CLIENT, sd_server, buf, LINEBUFFER);          recvline(CLIENT, sd_server, buf, LINEBUFFER);
629          swrite(SERVER, sd_client, buf);          swrite(SERVER, sd_client, buf);
630    
631          /* FIXME: xfree(message_body); */          message_free(msg);
632    
633          alarm(0);          alarm(0);
634  }  }
# Line 662  raw_transfer(void *sd_client, void *sd_s Line 659  raw_transfer(void *sd_client, void *sd_s
659  }  }
660    
661  void  void
662  transfer_body(void *sd_client, void *sd_server)  transfer_body(void *sd_client, void *sd_server, MESSAGE *msg)
663  {  {
664          if (topt & T_BOUNDARY) {          if (msg->boundary) {
665                  send_body(sd_server);                  send_body(msg, sd_server);
666                                    
667                  /* Transfer everything else */                  /* Transfer everything else */
668                  raw_transfer(sd_client, sd_server);                  raw_transfer(sd_client, sd_server);
669          } else          } else
670                  send_body(sd_server);                  send_body(msg, sd_server);
671          swrite(CLIENT, sd_server, "."CRLF);          swrite(CLIENT, sd_server, "."CRLF);
672  }  }
673    
 void  
 message_add_header(MESSAGE *msg, char *hdr)  
 {  
         list_append(msg->header, header_assoc(hdr));  
 }  
   
 void  
 message_remove_headers(MESSAGE *msg, char *arg)  
 {  
         ASSOC *asc;  
         RC_REGEX *regex = anubis_regex_compile(arg, 0);  
           
         for (asc = list_first(msg->header); asc;  
              asc = list_next(msg->header)) {  
                 char **rv;  
                 int rc;  
                 char *h = assoc_to_header(asc);  
                   
                 if (anubis_regex_match(regex, h, &rc, &rv)) {  
                         list_remove_current(msg->header);  
                         assoc_free(asc);  
                 }  
                 free(h);  
                 if (rc)  
                         free_pptr(rv);  
         }  
         anubis_regex_free(regex);  
 }  
   
 void  
 message_modify_headers(MESSAGE *msg, char *arg, char *modify)  
 {  
         ASSOC *asc;  
         RC_REGEX *regex = anubis_regex_compile(arg, 0);  
           
         for (asc = list_first(msg->header); asc;  
              asc = list_next(msg->header)) {  
                 char **rv;  
                 int rc;  
                 char *h = assoc_to_header(asc);  
                   
                 if (anubis_regex_match(regex, h, &rc, &rv)) {  
                         free(asc->value);  
                         asc->value = substitute(modify, rv);  
                         if (!asc->value)  
                                 asc->value = strdup(modify);  
                 }  
                 free(h);  
                 free_pptr(rv);  
         }  
         anubis_regex_free(regex);  
 }  
   
 void  
 message_external_proc(MESSAGE *msg, char *name)  
 {  
         int rc = 0;  
         char *extbuf = 0;  
         extbuf = external_program(&rc, name, message.body, 0, 0);  
         if (rc != -1 && extbuf) {  
                 xfree(message.body);  
                 message.body = extbuf;  
         }  
 }  
674    
675  /* EOF */  /* EOF */
676    

Legend:
Removed from v.1.11  
changed lines
  Added in v.1.12

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