Kannel: Open Source WAP and SMS gateway  svn-r5335
wap_push_pap_mime.c File Reference

Go to the source code of this file.

Functions

static int is_cr (int c)
 
static int is_lf (int c)
 
static int islwspchar (int c)
 
static long octstr_drop_leading_blanks (Octstr **header_value)
 
static void drop_separator (Octstr **header_value, long *pos)
 
static int parse_preamble (Octstr **mime_content, Octstr *boundary)
 
static long parse_transport_padding (Octstr *mime_content, long pos)
 
static long parse_terminator (Octstr *mime_content, long pos)
 
static int parse_body_part (Octstr **multipart, Octstr *boundary, Octstr **body_part)
 
static int parse_encapsulation (Octstr **mime_content, Octstr *boundary, Octstr **push_data, List **content_headers, Octstr **rdf_content)
 
static int check_control_headers (Octstr **body_part)
 
static int check_control_content_type_header (Octstr **body_part, Octstr *boundary)
 
static int drop_optional_header (Octstr **body_part, char *name, Octstr *boundary)
 
static int drop_header_true (Octstr **body_part, long content_pos)
 
static int drop_extension_headers (Octstr **mime_content, Octstr *boundary)
 
static long parse_field_value (Octstr *pap_content, long pos)
 
static long parse_field_name (Octstr *pap_content, long pos)
 
static void octstr_split_by_pos (Octstr **mime_content, Octstr **pap_content, long boundary_pos)
 
static Octstrmake_close_delimiter (Octstr *boundary)
 
static Octstrmake_part_delimiter (Octstr *boundary)
 
static Octstrmake_start_delimiter (Octstr *dash_boundary)
 
static int pass_data_headers (Octstr **body_part, List **data_headers)
 
static int check_data_x_wap_application_id_header (Octstr **body_part, List **data_headers, Octstr *boundary)
 
static int check_data_content_type_header (Octstr **body_part, List **data_headers, Octstr *boundary)
 
static int pass_optional_header (Octstr **body_part, char *name, List **content_headers, Octstr *boundary)
 
static int pass_extension_headers (Octstr **body_part, List **data_headers, Octstr *boundary)
 
static long pass_field_name (Octstr **body_part, Octstr **content_header, long pos)
 
static long pass_field_value (Octstr **body_part, Octstr **content_header, long pos)
 
static int parse_epilogue (Octstr **mime_content)
 
static int parse_tail (Octstr **multipart, Octstr *part_delimiter, long boundary_pos, long *next_part_pos)
 
int mime_parse (Octstr *boundary, Octstr *mime_content, Octstr **pap_content, Octstr **push_data, List **content_headers, Octstr **rdf_content)
 
static long parse_close_delimiter (Octstr *close_delimiter, Octstr *mime_content, long pos)
 

Function Documentation

◆ check_control_content_type_header()

static int check_control_content_type_header ( Octstr **  body_part,
Octstr boundary 
)
static

Definition at line 445 of file wap_push_pap_mime.c.

References boundary, drop_header_true(), octstr_case_nsearch(), octstr_case_search(), octstr_imm(), and octstr_search().

Referenced by check_control_headers().

446 {
447  long content_pos;
448  long message_start_pos;
449 
450  message_start_pos = octstr_search(*body_part, boundary, 0);
451  if ((content_pos = octstr_case_nsearch(*body_part, octstr_imm("Content-Type:"), 0,
452  message_start_pos)) < 0 ||
453  octstr_case_search(*body_part, octstr_imm("application/xml"), 0) < 0) {
454  return 0;
455  }
456 
457  if (drop_header_true(body_part, content_pos) < 0)
458  return 0;
459 
460  return 1;
461 }
static char * boundary
Definition: test_ppg.c:97
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1070
long octstr_case_nsearch(const Octstr *haystack, const Octstr *needle, long pos, long n)
Definition: octstr.c:1129
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
static int drop_header_true(Octstr **body_part, long content_pos)
long octstr_case_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1102

◆ check_control_headers()

static int check_control_headers ( Octstr **  body_part)
static

Definition at line 428 of file wap_push_pap_mime.c.

References check_control_content_type_header(), drop_extension_headers(), drop_optional_header(), and octstr_imm().

Referenced by mime_parse().

429 {
430  if (check_control_content_type_header(body_part, octstr_imm("\r\n\r\n")) == 0)
431  return 0;
432  if (drop_optional_header(body_part, "Content-Transfer-Encoding:",
433  octstr_imm("\r\n\r\n")) == 0)
434  return 0;
435  if (drop_optional_header(body_part, "Content-ID:", octstr_imm("\r\n\r\n")) == 0)
436  return 0;
437  if (drop_optional_header(body_part, "Content-Description:", octstr_imm("\r\n\r\n")) == 0)
438  return 0;
439  if (drop_extension_headers(body_part, octstr_imm("\r\n\r\n")) == 0)
440  return 0;
441 
442  return 1;
443 }
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
static int drop_optional_header(Octstr **body_part, char *name, Octstr *boundary)
static int drop_extension_headers(Octstr **mime_content, Octstr *boundary)
static int check_control_content_type_header(Octstr **body_part, Octstr *boundary)

◆ check_data_content_type_header()

static int check_data_content_type_header ( Octstr **  body_part,
List **  data_headers,
Octstr boundary 
)
static

Definition at line 662 of file wap_push_pap_mime.c.

References boundary, content_header, error(), gwlist_append(), octstr_case_nsearch(), octstr_create, octstr_delete(), octstr_destroy(), octstr_duplicate, octstr_len(), octstr_search(), parse_terminator(), and pass_field_value().

Referenced by pass_data_headers().

664 {
665  long header_pos, next_header_pos;
667  long message_start_pos;
668 
669  header_pos = next_header_pos = -1;
670  content_header = octstr_create("Content-Type");
671  message_start_pos = octstr_search(*body_part, boundary, 0);
672 
673  if ((header_pos = octstr_case_nsearch(*body_part, content_header, 0,
674  message_start_pos)) < 0) {
675  goto error;
676  }
677  if ((next_header_pos = pass_field_value(body_part, &content_header,
678  header_pos + octstr_len(content_header))) < 0) {
679  goto error;
680  }
681  if ((next_header_pos = parse_terminator(*body_part, next_header_pos)) < 0) {
682  goto error;
683  }
684 
685  octstr_delete(*body_part, header_pos, next_header_pos - header_pos);
686  gwlist_append(*content_headers, octstr_duplicate(content_header));
688 
689  return 1;
690 
691 error:
693  return 0;
694 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void gwlist_append(List *list, void *item)
Definition: list.c:179
static char * boundary
Definition: test_ppg.c:97
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1070
long octstr_case_nsearch(const Octstr *haystack, const Octstr *needle, long pos, long n)
Definition: octstr.c:1129
static long parse_terminator(Octstr *mime_content, long pos)
static long pass_field_value(Octstr **body_part, Octstr **content_header, long pos)
static Octstr * content_header
Definition: test_ppg.c:101
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118

◆ check_data_x_wap_application_id_header()

static int check_data_x_wap_application_id_header ( Octstr **  body_part,
List **  data_headers,
Octstr boundary 
)
static

Definition at line 623 of file wap_push_pap_mime.c.

References boundary, content_header, error(), gwlist_append(), octstr_case_nsearch(), octstr_create, octstr_delete(), octstr_destroy(), octstr_duplicate, octstr_len(), octstr_search(), parse_terminator(), and pass_field_value().

Referenced by pass_data_headers().

625 {
626  long header_pos, next_header_pos;
628  long message_start_pos;
629 
630  header_pos = next_header_pos = -1;
631  content_header = octstr_create("X-Wap-Application-Id");
632  message_start_pos = octstr_search(*body_part, boundary, 0);
633 
634  if ((header_pos = octstr_case_nsearch(*body_part, content_header, 0,
635  message_start_pos)) < 0) {
636  goto error;
637  }
638  if ((next_header_pos = pass_field_value(body_part, &content_header,
639  header_pos + octstr_len(content_header))) < 0) {
640  goto error;
641  }
642  if ((next_header_pos = parse_terminator(*body_part, next_header_pos)) < 0) {
643  goto error;
644  }
645 
646  octstr_delete(*body_part, header_pos, next_header_pos - header_pos);
647  gwlist_append(*content_headers, octstr_duplicate(content_header));
649 
650  return 1;
651 
652 error:
654  return 0;
655 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void gwlist_append(List *list, void *item)
Definition: list.c:179
static char * boundary
Definition: test_ppg.c:97
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1070
long octstr_case_nsearch(const Octstr *haystack, const Octstr *needle, long pos, long n)
Definition: octstr.c:1129
static long parse_terminator(Octstr *mime_content, long pos)
static long pass_field_value(Octstr **body_part, Octstr **content_header, long pos)
static Octstr * content_header
Definition: test_ppg.c:101
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118

◆ drop_extension_headers()

static int drop_extension_headers ( Octstr **  mime_content,
Octstr boundary 
)
static

Definition at line 505 of file wap_push_pap_mime.c.

References boundary, islwspchar(), octstr_case_nsearch(), octstr_case_search(), octstr_delete(), octstr_get_char(), octstr_imm(), parse_field_name(), parse_field_value(), and parse_terminator().

Referenced by check_control_headers().

506 {
507  long content_pos,
508  next_header_pos;
509  long next_content_part_pos;
510 
511  next_content_part_pos = octstr_case_search(*body_part, boundary, 0);
512  do {
513  if ((content_pos = octstr_case_nsearch(*body_part, octstr_imm("Content"), 0,
514  next_content_part_pos)) < 0)
515  return 1;
516  if ((next_header_pos = parse_field_name(*body_part, content_pos)) < 0)
517  return 0;
518  if ((next_header_pos = parse_field_value(*body_part,
519  next_header_pos)) < 0)
520  return 0;
521  if ((next_header_pos = parse_terminator(*body_part,
522  next_header_pos)) == 0)
523  return 0;
524  } while (islwspchar(octstr_get_char(*body_part, next_header_pos)));
525 
526  octstr_delete(*body_part, content_pos, next_header_pos - content_pos);
527 
528  return 1;
529 }
static int islwspchar(int c)
static char * boundary
Definition: test_ppg.c:97
long octstr_case_nsearch(const Octstr *haystack, const Octstr *needle, long pos, long n)
Definition: octstr.c:1129
static long parse_field_name(Octstr *pap_content, long pos)
static long parse_terminator(Octstr *mime_content, long pos)
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
long octstr_case_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1102
static long parse_field_value(Octstr *pap_content, long pos)
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ drop_header_true()

static int drop_header_true ( Octstr **  body_part,
long  content_pos 
)
static

Definition at line 468 of file wap_push_pap_mime.c.

References octstr_delete(), parse_field_value(), and parse_terminator().

Referenced by check_control_content_type_header(), and drop_optional_header().

469 {
470  long next_header_pos;
471 
472  next_header_pos = -1;
473  if ((next_header_pos = parse_field_value(*body_part, content_pos)) == 0)
474  return 0;
475  if ((next_header_pos = parse_terminator(*body_part, next_header_pos)) == 0)
476  return 0;
477  octstr_delete(*body_part, 0, next_header_pos);
478 
479  return 1;
480 }
static long parse_terminator(Octstr *mime_content, long pos)
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
static long parse_field_value(Octstr *pap_content, long pos)

◆ drop_optional_header()

static int drop_optional_header ( Octstr **  body_part,
char *  name,
Octstr boundary 
)
static

Definition at line 482 of file wap_push_pap_mime.c.

References boundary, drop_header_true(), name, octstr_case_nsearch(), octstr_imm(), and octstr_search().

Referenced by check_control_headers().

483 {
484  long content_pos;
485  long message_start_pos;
486 
487  content_pos = -1;
488  message_start_pos = octstr_search(*body_part, boundary, 0);
489 
490  if ((content_pos = octstr_case_nsearch(*body_part, octstr_imm(name), 0, message_start_pos)) < 0)
491  return 1;
492 
493  if (drop_header_true(body_part, content_pos) < 0)
494  return 0;
495 
496  return 1;
497 }
static char * boundary
Definition: test_ppg.c:97
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1070
long octstr_case_nsearch(const Octstr *haystack, const Octstr *needle, long pos, long n)
Definition: octstr.c:1129
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
static int drop_header_true(Octstr **body_part, long content_pos)
char * name
Definition: smsc_cimd2.c:212

◆ drop_separator()

static void drop_separator ( Octstr **  header_value,
long *  pos 
)
static

Definition at line 743 of file wap_push_pap_mime.c.

References octstr_delete(), and octstr_drop_leading_blanks().

Referenced by pass_extension_headers(), and pass_optional_header().

744 {
745  long count;
746 
747  octstr_delete(*header_value, 0, 1); /* remove :*/
748  count = octstr_drop_leading_blanks(header_value);
749  pos = pos - 1 - count;
750 }
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
static long octstr_drop_leading_blanks(Octstr **header_value)

◆ is_cr()

static int is_cr ( int  c)
static

Definition at line 184 of file wap_push_pap_mime.c.

Referenced by parse_field_value(), parse_terminator(), and pass_field_value().

185 {
186  return c == '\r';
187 }

◆ is_lf()

static int is_lf ( int  c)
static

Definition at line 189 of file wap_push_pap_mime.c.

Referenced by parse_field_value(), and parse_terminator().

190 {
191  return c == '\n';
192 }

◆ islwspchar()

static int islwspchar ( int  c)
static

Definition at line 197 of file wap_push_pap_mime.c.

Referenced by drop_extension_headers(), parse_transport_padding(), and pass_extension_headers().

198 {
199  return c == '\t' || c == ' ';
200 }

◆ make_close_delimiter()

static Octstr * make_close_delimiter ( Octstr boundary)
static

Definition at line 390 of file wap_push_pap_mime.c.

References boundary, make_part_delimiter(), and octstr_format_append().

Referenced by parse_body_part().

391 {
392  Octstr *close_delimiter;
393 
394  close_delimiter = make_part_delimiter(boundary);
395  octstr_format_append(close_delimiter, "%s", "--");
396 
397  return close_delimiter;
398 }
static Octstr * make_part_delimiter(Octstr *boundary)
static char * boundary
Definition: test_ppg.c:97
Definition: octstr.c:118
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2507

◆ make_part_delimiter()

static Octstr * make_part_delimiter ( Octstr boundary)
static

Definition at line 400 of file wap_push_pap_mime.c.

References octstr_append(), and octstr_create.

Referenced by make_close_delimiter(), and parse_body_part().

401 {
402  Octstr *part_delimiter;
403 
404  part_delimiter = octstr_create("\r\n--");
405  octstr_append(part_delimiter, dash_boundary);
406 
407  return part_delimiter;
408 }
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
#define octstr_create(cstr)
Definition: octstr.h:125
Definition: octstr.c:118

◆ make_start_delimiter()

static Octstr * make_start_delimiter ( Octstr dash_boundary)
static

Definition at line 410 of file wap_push_pap_mime.c.

References octstr_append(), and octstr_create.

Referenced by parse_preamble().

411 {
412  Octstr *start_delimiter;
413 
414  start_delimiter = octstr_create("--");
415  octstr_append(start_delimiter, dash_boundary);
416 
417  return start_delimiter;
418 }
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
#define octstr_create(cstr)
Definition: octstr.h:125
Definition: octstr.c:118

◆ mime_parse()

int mime_parse ( Octstr boundary,
Octstr mime_content,
Octstr **  pap_content,
Octstr **  push_data,
List **  content_headers,
Octstr **  rdf_content 
)

Definition at line 131 of file wap_push_pap_mime.c.

References boundary, check_control_headers(), gw_assert(), octstr_len(), parse_body_part(), parse_encapsulation(), parse_epilogue(), parse_preamble(), push_data, and warning().

Referenced by main(), and pap_request_thread().

134 {
135  int ret;
136 
137  *pap_content = NULL;
138  *push_data = NULL;
139  *content_headers = NULL;
140  *rdf_content = NULL;
141 
142  if (parse_preamble(&mime_content, boundary) < 0) {
143  warning(0, "erroneous preamble");
144  return 0;
145  }
146  if (parse_body_part(&mime_content, boundary, pap_content) <= 0) {
147  warning(0, "erroneous control entity");
148  return 0;
149  }
150  if (check_control_headers(pap_content) == 0) {
151  warning(0, "erroneous control headers");
152  return 0;
153  }
154 
155  ret = -1;
156  if ((ret = parse_encapsulation(&mime_content, boundary, push_data,
157  content_headers, rdf_content)) < 0) {
158  warning(0, "erroneous content entity (push message)");
159  return 0;
160  } else if (ret == 0) {
161  gw_assert(*rdf_content == NULL);
162  if (octstr_len(mime_content) != 0)
163  parse_epilogue(&mime_content);
164  return 1;
165  }
166 
167  if (check_control_headers(rdf_content) == 0) {
168  warning(0, "erroneous capacity (rdf) headers");
169  return 0;
170  }
171 
172  if (octstr_len(mime_content) != 0)
173  parse_epilogue(&mime_content);
174  gw_assert(octstr_len(mime_content) == 0);
175 
176  return 1;
177 }
static int parse_epilogue(Octstr **mime_content)
static char ** push_data
Definition: test_ppg.c:96
gw_assert(wtls_machine->packet_to_send !=NULL)
static char * boundary
Definition: test_ppg.c:97
static int check_control_headers(Octstr **body_part)
static int parse_body_part(Octstr **multipart, Octstr *boundary, Octstr **body_part)
void warning(int err, const char *fmt,...)
Definition: log.c:660
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
static int parse_preamble(Octstr **mime_content, Octstr *boundary)
static int parse_encapsulation(Octstr **mime_content, Octstr *boundary, Octstr **push_data, List **content_headers, Octstr **rdf_content)

◆ octstr_drop_leading_blanks()

static long octstr_drop_leading_blanks ( Octstr **  header_value)
static

Definition at line 755 of file wap_push_pap_mime.c.

References octstr_delete(), and octstr_get_char().

Referenced by drop_separator().

756 {
757  long count;
758 
759  count = 0;
760  while (octstr_get_char(*header_value, 0) == ' ') {
761  octstr_delete(*header_value, 0, 1);
762  ++count;
763  }
764 
765  return count;
766 }
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ octstr_split_by_pos()

static void octstr_split_by_pos ( Octstr **  mime_content,
Octstr **  pap_content,
long  boundary_pos 
)
static

Definition at line 383 of file wap_push_pap_mime.c.

References octstr_copy, and octstr_delete().

Referenced by parse_body_part().

385 {
386  *os2 = octstr_copy(*os1, 0, boundary_pos);
387  octstr_delete(*os1, 0, boundary_pos);
388 }
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527

◆ parse_body_part()

static int parse_body_part ( Octstr **  multipart,
Octstr boundary,
Octstr **  body_part 
)
static

Definition at line 289 of file wap_push_pap_mime.c.

References boundary, error(), make_close_delimiter(), make_part_delimiter(), octstr_delete(), octstr_destroy(), octstr_search(), octstr_split_by_pos(), parse_close_delimiter(), parse_tail(), and parse_transport_padding().

Referenced by mime_parse(), and parse_encapsulation().

291 {
292  Octstr *part_delimiter,
293  *close_delimiter;
294  long boundary_pos, /* start of the boundary */
295  close_delimiter_pos, /* start of the close delimiter */
296  next_part_pos, /* start of the next part */
297  epilogue_pos; /* start of the epilogue */
298 
299  part_delimiter = make_part_delimiter(boundary);
300  close_delimiter = make_close_delimiter(boundary);
301 
302  if ((close_delimiter_pos = octstr_search(*multipart,
303  close_delimiter, 0)) < 0)
304  goto error;
305 
306  boundary_pos = octstr_search(*multipart, part_delimiter, 0);
307  if (boundary_pos == close_delimiter_pos) {
308  octstr_split_by_pos(multipart, body_part, close_delimiter_pos);
309  if ((epilogue_pos =
310  parse_close_delimiter(close_delimiter, *multipart, 0)) < 0)
311  goto error;
312  epilogue_pos = parse_transport_padding(*multipart, epilogue_pos);
313  octstr_delete(*multipart, 0, epilogue_pos);
314  goto last_part;
315  }
316 
317  octstr_split_by_pos(multipart, body_part, boundary_pos);
318 
319  if (parse_tail(multipart, part_delimiter, 0, &next_part_pos) < 0) {
320  goto error;
321  }
322 
323  octstr_delete(*multipart, 0, next_part_pos);
324  octstr_destroy(part_delimiter);
325  octstr_destroy(close_delimiter);
326 
327  return 1;
328 
329 error:
330  octstr_destroy(part_delimiter);
331  octstr_destroy(close_delimiter);
332  return -1;
333 
334 last_part:
335  octstr_destroy(part_delimiter);
336  octstr_destroy(close_delimiter);
337  return 0;
338 
339 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static void octstr_split_by_pos(Octstr **mime_content, Octstr **pap_content, long boundary_pos)
static Octstr * make_part_delimiter(Octstr *boundary)
static char * boundary
Definition: test_ppg.c:97
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1070
static long parse_transport_padding(Octstr *mime_content, long pos)
static Octstr * make_close_delimiter(Octstr *boundary)
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
static long parse_close_delimiter(Octstr *close_delimiter, Octstr *mime_content, long pos)
Definition: octstr.c:118
static int parse_tail(Octstr **multipart, Octstr *part_delimiter, long boundary_pos, long *next_part_pos)

◆ parse_close_delimiter()

static long parse_close_delimiter ( Octstr close_delimiter,
Octstr mime_content,
long  pos 
)
static

Definition at line 269 of file wap_push_pap_mime.c.

References octstr_len(), and octstr_ncompare().

Referenced by parse_body_part().

271 {
272  if (octstr_ncompare(close_delimiter, mime_content,
273  octstr_len(close_delimiter)) != 0)
274  return -1;
275  pos += octstr_len(close_delimiter);
276 
277  return pos;
278 }
int octstr_ncompare(const Octstr *ostr1, const Octstr *ostr2, long n)
Definition: octstr.c:952
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342

◆ parse_encapsulation()

static int parse_encapsulation ( Octstr **  mime_content,
Octstr boundary,
Octstr **  push_data,
List **  content_headers,
Octstr **  rdf_content 
)
static

Definition at line 354 of file wap_push_pap_mime.c.

References boundary, parse_body_part(), pass_data_headers(), and push_data.

Referenced by mime_parse().

357 {
358  int ret;
359 
360  ret = -1;
361  if ((ret = parse_body_part(mime_content, boundary, push_data)) < 0)
362  return -1;
363  if (pass_data_headers(push_data, content_headers) == 0)
364  return -1;
365 
366  if (ret == 0) {
367  *rdf_content = NULL;
368  return 0;
369  }
370 
371  if ((ret = parse_body_part(mime_content, boundary, rdf_content)) < 0 ||
372  ret > 0)
373  return -1;
374  else if (ret == 0)
375  return 1;
376 
377  return 1;
378 }
static char ** push_data
Definition: test_ppg.c:96
static char * boundary
Definition: test_ppg.c:97
static int parse_body_part(Octstr **multipart, Octstr *boundary, Octstr **body_part)
static int pass_data_headers(Octstr **body_part, List **data_headers)

◆ parse_epilogue()

static int parse_epilogue ( Octstr **  mime_content)
static

Definition at line 870 of file wap_push_pap_mime.c.

References octstr_delete(), octstr_len(), and parse_terminator().

Referenced by mime_parse().

871 {
872  long pos;
873 
874  if (octstr_len(*mime_content) == 0)
875  return 0;
876 
877  if ((pos = parse_terminator(*mime_content, 0)) < 0)
878  return -1;
879 
880  octstr_delete(*mime_content, 0, octstr_len(*mime_content));
881  return 0;
882 }
static long parse_terminator(Octstr *mime_content, long pos)
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342

◆ parse_field_name()

static long parse_field_name ( Octstr pap_content,
long  pos 
)
static

Definition at line 555 of file wap_push_pap_mime.c.

References octstr_get_char(), and octstr_len().

Referenced by drop_extension_headers().

556 {
557  while (octstr_get_char(content, pos) != ':' &&
558  pos < octstr_len(content))
559  ++pos;
560 
561  if (pos == octstr_len(content))
562  return -1;
563 
564  return pos;
565 }
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ parse_field_value()

static long parse_field_value ( Octstr pap_content,
long  pos 
)
static

Definition at line 531 of file wap_push_pap_mime.c.

References is_cr(), is_lf(), octstr_get_char(), and octstr_len().

Referenced by drop_extension_headers(), and drop_header_true().

532 {
533  int c;
534 
535  while (!is_cr(c = octstr_get_char(pap_content, pos)) &&
536  pos < octstr_len(pap_content)) {
537  ++pos;
538  }
539 
540  if (is_lf(c)) {
541  if (is_lf(octstr_get_char(pap_content, pos))) {
542  ++pos;
543  } else {
544  return -1;
545  }
546  }
547 
548  if (pos == octstr_len(pap_content)) {
549  return -1;
550  }
551 
552  return pos;
553 }
static int is_lf(int c)
static int is_cr(int c)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ parse_preamble()

static int parse_preamble ( Octstr **  mime_content,
Octstr boundary 
)
static

Definition at line 220 of file wap_push_pap_mime.c.

References boundary, error(), make_start_delimiter(), octstr_delete(), octstr_destroy(), octstr_search(), and parse_tail().

Referenced by mime_parse().

221 {
222  long boundary_pos,
223  next_part_pos;
224  Octstr *dash_boundary;
225 
226  boundary_pos = next_part_pos = -1;
227  dash_boundary = make_start_delimiter(boundary);
228 
229  if ((boundary_pos = octstr_search(*mime_content, dash_boundary, 0)) < 0)
230  goto error;
231 
232  if (parse_tail(mime_content, dash_boundary, boundary_pos,
233  &next_part_pos) < 0)
234  goto error;
235 
236  octstr_delete(*mime_content, 0, next_part_pos);
237  octstr_destroy(dash_boundary);
238 
239  return 0;
240 
241 error:
242  octstr_destroy(dash_boundary);
243  return -1;
244 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static Octstr * make_start_delimiter(Octstr *dash_boundary)
static char * boundary
Definition: test_ppg.c:97
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1070
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
static int parse_tail(Octstr **multipart, Octstr *part_delimiter, long boundary_pos, long *next_part_pos)

◆ parse_tail()

static int parse_tail ( Octstr **  multipart,
Octstr part_delimiter,
long  boundary_pos,
long *  next_part_pos 
)
static

Definition at line 203 of file wap_push_pap_mime.c.

References delimiter, octstr_len(), parse_terminator(), and parse_transport_padding().

Referenced by parse_body_part(), and parse_preamble().

205 {
206  *next_part_pos = parse_transport_padding(*multipart,
207  boundary_pos + octstr_len(delimiter));
208 
209  if ((*next_part_pos = parse_terminator(*multipart, *next_part_pos)) < 0)
210  return -1;
211 
212  return 0;
213 }
static Octstr * delimiter
Definition: test_ppg.c:104
static long parse_terminator(Octstr *mime_content, long pos)
static long parse_transport_padding(Octstr *mime_content, long pos)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342

◆ parse_terminator()

static long parse_terminator ( Octstr mime_content,
long  pos 
)
static

Definition at line 246 of file wap_push_pap_mime.c.

References is_cr(), is_lf(), and octstr_get_char().

Referenced by check_data_content_type_header(), check_data_x_wap_application_id_header(), drop_extension_headers(), drop_header_true(), parse_epilogue(), parse_tail(), pass_extension_headers(), and pass_optional_header().

247 {
248  if (is_cr(octstr_get_char(mime_content, pos)))
249  ++pos;
250  else
251  return -1;
252 
253  if (is_lf(octstr_get_char(mime_content, pos)))
254  ++pos;
255  else
256  return -1;
257 
258  return pos;
259 }
static int is_lf(int c)
static int is_cr(int c)
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ parse_transport_padding()

static long parse_transport_padding ( Octstr mime_content,
long  pos 
)
static

Definition at line 261 of file wap_push_pap_mime.c.

References islwspchar(), and octstr_get_char().

Referenced by parse_body_part(), and parse_tail().

262 {
263  while (islwspchar(octstr_get_char(mime_content, pos)))
264  ++pos;
265 
266  return pos;
267 }
static int islwspchar(int c)
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ pass_data_headers()

static int pass_data_headers ( Octstr **  body_part,
List **  data_headers 
)
static

Definition at line 576 of file wap_push_pap_mime.c.

References check_data_content_type_header(), check_data_x_wap_application_id_header(), gwlist_append(), http_create_empty_headers(), octstr_create, octstr_delete(), octstr_imm(), octstr_len(), pass_extension_headers(), pass_optional_header(), and warning().

Referenced by parse_encapsulation().

577 {
578  *data_headers = http_create_empty_headers();
579 
580  /* Transform X-WAP-Application headers as per PPG 6.1.2.1.
581  * Note that missing header means that wml.ua is assumed. */
582  if (check_data_x_wap_application_id_header(body_part, data_headers, octstr_imm("\r\n\r\n")) == 0) {
583  warning(0, "MIME: %s: X-Wap-Application-Id header missing, assuming 'wml.ua'", __func__);
584  gwlist_append(*data_headers, octstr_create("X-Wap-Application-Id: wml.ua"));
585  }
586 
587  if (check_data_content_type_header(body_part, data_headers, octstr_imm("\r\n\r\n")) == 0) {
588  warning(0, "MIME: %s: Content-Type header missing", __func__);
589  return 0;
590  }
591 
592  if (pass_optional_header(body_part, "Content-Transfer-Encoding", data_headers,
593  octstr_imm("\r\n\r\n")) < 0)
594  goto operror;
595  if (pass_optional_header(body_part, "Content-ID", data_headers, octstr_imm("\r\n\r\n")) < 0)
596  goto operror;
597  if (pass_optional_header(body_part, "Content-Description", data_headers,
598  octstr_imm("\r\n\r\n")) < 0)
599  goto operror;
600  if (pass_extension_headers(body_part, data_headers, octstr_imm("\r\n\r\n")) == 0)
601  goto operror;
602 
603  /*
604  * XXX: TODO: This assumes that there are no further headers prefixing
605  * the MIME body. Which MAY not be the case. We SHOULD rather move all
606  * headers to the data_headers and ensure by this that there are no
607  * left overs.
608  */
609  octstr_delete(*body_part, 0, octstr_len(octstr_imm("\r\n")));
610 
611  return 1;
612 
613 operror:
614  warning(0, "MIME: pass_data_headers: an unparseable optional header");
615  return 0;
616 }
static int check_data_content_type_header(Octstr **body_part, List **data_headers, Octstr *boundary)
void gwlist_append(List *list, void *item)
Definition: list.c:179
static int check_data_x_wap_application_id_header(Octstr **body_part, List **data_headers, Octstr *boundary)
static int pass_extension_headers(Octstr **body_part, List **data_headers, Octstr *boundary)
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
List * http_create_empty_headers(void)
Definition: http.c:2872
void warning(int err, const char *fmt,...)
Definition: log.c:660
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
static int pass_optional_header(Octstr **body_part, char *name, List **content_headers, Octstr *boundary)

◆ pass_extension_headers()

static int pass_extension_headers ( Octstr **  body_part,
List **  data_headers,
Octstr boundary 
)
static

Definition at line 774 of file wap_push_pap_mime.c.

References boundary, drop_separator(), error(), http_header_add(), islwspchar(), octstr_case_nsearch(), octstr_create, octstr_delete(), octstr_destroy(), octstr_get_char(), octstr_get_cstr, octstr_imm(), octstr_search(), parse_terminator(), pass_field_name(), and pass_field_value().

Referenced by pass_data_headers().

775 {
776  long next_field_part_pos;
777  Octstr *header_name,
778  *header_value;
779  long next_content_part_pos;
780 
781  header_name = octstr_create("");
782  header_value = octstr_create("");
783  next_field_part_pos = 0;
784  next_content_part_pos = octstr_search(*body_part, boundary, 0);
785 
786  do {
787  if ((octstr_case_nsearch(*body_part, octstr_imm("Content"), 0,
788  next_content_part_pos)) < 0)
789  goto end;
790  if ((next_field_part_pos = pass_field_name(body_part, &header_name,
791  next_field_part_pos)) < 0)
792  goto error;
793  if ((next_field_part_pos = pass_field_value(body_part, &header_value,
794  next_field_part_pos)) < 0)
795  goto error;
796  if ((next_field_part_pos = parse_terminator(*body_part,
797  next_field_part_pos)) == 0)
798  goto error;
799  drop_separator(&header_value, &next_field_part_pos);
800  http_header_add(*content_headers, octstr_get_cstr(header_name),
801  octstr_get_cstr(header_value));
802  } while (islwspchar(octstr_get_char(*body_part, next_field_part_pos)));
803 
804  octstr_delete(*body_part, 0, next_field_part_pos);
805 
806 /*
807  * An intentional fall-through. We must eventually use a function for memory
808  * cleaning.
809  */
810 end:
811  octstr_destroy(header_name);
812  octstr_destroy(header_value);
813  return 1;
814 
815 error:
816  octstr_destroy(header_name);
817  octstr_destroy(header_value);
818  return 0;
819 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2886
static int islwspchar(int c)
static char * boundary
Definition: test_ppg.c:97
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1070
long octstr_case_nsearch(const Octstr *haystack, const Octstr *needle, long pos, long n)
Definition: octstr.c:1129
static void drop_separator(Octstr **header_value, long *pos)
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static long parse_terminator(Octstr *mime_content, long pos)
static long pass_field_value(Octstr **body_part, Octstr **content_header, long pos)
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
static long pass_field_name(Octstr **body_part, Octstr **content_header, long pos)
Definition: octstr.c:118
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ pass_field_name()

static long pass_field_name ( Octstr **  body_part,
Octstr **  content_header,
long  pos 
)
static

Definition at line 845 of file wap_push_pap_mime.c.

References name, octstr_append(), octstr_copy, octstr_destroy(), octstr_get_char(), octstr_len(), and start.

Referenced by pass_extension_headers().

847 {
848  int c;
849  long start;
850  Octstr *name = NULL;
851 
852  start = pos;
853  while (((c = octstr_get_char(*body_part, pos)) != ':') &&
854  pos < octstr_len(*body_part)) {
855  ++pos;
856  }
857 
858  if (pos == octstr_len(*body_part)) {
859  return -1;
860  }
861 
862  name = octstr_copy(*body_part, start, pos - start);
863  octstr_append(*field_part, name);
864 
866  return pos;
867 }
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
char * name
Definition: smsc_cimd2.c:212
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
static int start

◆ pass_field_value()

static long pass_field_value ( Octstr **  body_part,
Octstr **  content_header,
long  pos 
)
static

Definition at line 821 of file wap_push_pap_mime.c.

References is_cr(), octstr_append(), octstr_copy, octstr_destroy(), octstr_get_char(), octstr_len(), and start.

Referenced by check_data_content_type_header(), check_data_x_wap_application_id_header(), pass_extension_headers(), and pass_optional_header().

823 {
824  int c;
825  long start;
826  Octstr *field = NULL;
827 
828  start = pos;
829  while (!is_cr(c = octstr_get_char(*body_part, pos)) &&
830  pos < octstr_len(*body_part)) {
831  ++pos;
832  }
833 
834  if (pos == octstr_len(*body_part)) {
835  return -1;
836  }
837 
838  field = octstr_copy(*body_part, start, pos - start);
839  octstr_append(*header, field);
840 
841  octstr_destroy(field);
842  return pos;
843 }
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
static int is_cr(int c)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
static int start

◆ pass_optional_header()

static int pass_optional_header ( Octstr **  body_part,
char *  name,
List **  content_headers,
Octstr boundary 
)
static

Definition at line 701 of file wap_push_pap_mime.c.

References boundary, drop_separator(), error(), http_header_add(), name, octstr_case_nsearch(), octstr_create, octstr_delete(), octstr_destroy(), octstr_get_cstr, octstr_len(), octstr_search(), parse_terminator(), and pass_field_value().

Referenced by pass_data_headers().

703 {
704  long content_pos, next_header_pos;
705  Octstr *osname, *osvalue;
706  long message_start_pos;
707 
708  content_pos = next_header_pos = -1;
709  osname = octstr_create(name);
710  osvalue = octstr_create("");
711  message_start_pos = octstr_search(*body_part, boundary, 0);
712 
713  if ((content_pos = octstr_case_nsearch(*body_part, osname, 0, message_start_pos)) < 0)
714  goto noheader;
715  if ((next_header_pos = pass_field_value(body_part, &osvalue,
716  content_pos + octstr_len(osname))) < 0)
717  goto error;
718  if ((next_header_pos = parse_terminator(*body_part, next_header_pos)) == 0)
719  goto error;
720 
721  drop_separator(&osvalue, &next_header_pos);
722  http_header_add(*content_headers, name, octstr_get_cstr(osvalue));
723  octstr_delete(*body_part, content_pos, next_header_pos - content_pos);
724 
725  octstr_destroy(osname);
726  octstr_destroy(osvalue);
727  return 1;
728 
729 error:
730  octstr_destroy(osvalue);
731  octstr_destroy(osname);
732  return -1;
733 
734 noheader:
735  octstr_destroy(osvalue);
736  octstr_destroy(osname);
737  return 0;
738 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2886
static char * boundary
Definition: test_ppg.c:97
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1070
long octstr_case_nsearch(const Octstr *haystack, const Octstr *needle, long pos, long n)
Definition: octstr.c:1129
static void drop_separator(Octstr **header_value, long *pos)
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static long parse_terminator(Octstr *mime_content, long pos)
static long pass_field_value(Octstr **body_part, Octstr **content_header, long pos)
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
char * name
Definition: smsc_cimd2.c:212
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.