2
0

parse_to.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  1. /*
  2. * Copyright (C) 2001-2003 Fhg Fokus
  3. *
  4. * This file is part of ser, a free SIP server.
  5. *
  6. * ser is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version
  10. *
  11. * ser is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. *
  20. * History:
  21. * ---------
  22. * 2003-04-26 ZSW (jiri)
  23. * 2010-03-03 fix multi-token no-quotes display name (andrei)
  24. */
  25. /** Parser :: Parse To: header.
  26. * @file
  27. * @ingroup parser
  28. */
  29. #include "parse_to.h"
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include "../dprint.h"
  33. #include "msg_parser.h"
  34. #include "parse_uri.h"
  35. #include "../ut.h"
  36. #include "../mem/mem.h"
  37. enum {
  38. START_TO, DISPLAY_QUOTED, E_DISPLAY_QUOTED, DISPLAY_TOKEN,
  39. DISPLAY_TOKEN_SP, S_URI_ENCLOSED, URI_ENCLOSED, E_URI_ENCLOSED,
  40. URI_OR_TOKEN, MAYBE_URI_END, END, F_CR, F_LF, F_CRLF
  41. };
  42. enum {
  43. S_PARA_NAME=20, PARA_NAME, S_EQUAL, S_PARA_VALUE, TAG1, TAG2,
  44. TAG3, PARA_VALUE_TOKEN , PARA_VALUE_QUOTED, E_PARA_VALUE
  45. };
  46. #define add_param( _param , _body , _newparam ) \
  47. do{\
  48. DBG("DEBUG: add_param: %.*s=%.*s\n",param->name.len,ZSW(param->name.s),\
  49. param->value.len,ZSW(param->value.s));\
  50. if (!(_body)->param_lst) (_body)->param_lst=(_param);\
  51. else (_body)->last_param->next=(_param);\
  52. (_body)->last_param =(_param);\
  53. if ((_param)->type==TAG_PARAM)\
  54. memcpy(&((_body)->tag_value),&((_param)->value),sizeof(str));\
  55. _newparam = 0;\
  56. }while(0);
  57. static char* parse_to_param(char* const buffer, const char* const end,
  58. struct to_body* const to_b,
  59. int* const returned_status)
  60. {
  61. struct to_param *param;
  62. struct to_param *newparam;
  63. int status;
  64. int saved_status;
  65. char *tmp;
  66. param=0;
  67. newparam=0;
  68. status=E_PARA_VALUE;
  69. saved_status=E_PARA_VALUE;
  70. for( tmp=buffer; tmp<end; tmp++)
  71. {
  72. switch(*tmp)
  73. {
  74. case ' ':
  75. case '\t':
  76. switch (status)
  77. {
  78. case TAG3:
  79. param->type=TAG_PARAM;
  80. case PARA_NAME:
  81. case TAG1:
  82. case TAG2:
  83. param->name.len = tmp-param->name.s;
  84. status = S_EQUAL;
  85. break;
  86. case PARA_VALUE_TOKEN:
  87. param->value.len = tmp-param->value.s;
  88. status = E_PARA_VALUE;
  89. add_param(param, to_b, newparam);
  90. break;
  91. case F_CRLF:
  92. case F_LF:
  93. case F_CR:
  94. /*previous=crlf and now =' '*/
  95. status=saved_status;
  96. break;
  97. }
  98. break;
  99. case '\n':
  100. switch (status)
  101. {
  102. case S_PARA_NAME:
  103. case S_EQUAL:
  104. case S_PARA_VALUE:
  105. case E_PARA_VALUE:
  106. saved_status=status;
  107. status=F_LF;
  108. break;
  109. case TAG3:
  110. param->type=TAG_PARAM;
  111. case PARA_NAME:
  112. case TAG1:
  113. case TAG2:
  114. param->name.len = tmp-param->name.s;
  115. saved_status = S_EQUAL;
  116. status = F_LF;
  117. break;
  118. case PARA_VALUE_TOKEN:
  119. param->value.len = tmp-param->value.s;
  120. saved_status = E_PARA_VALUE;
  121. status = F_LF;
  122. add_param(param, to_b, newparam);
  123. break;
  124. case F_CR:
  125. status=F_CRLF;
  126. break;
  127. case F_CRLF:
  128. case F_LF:
  129. status=saved_status;
  130. goto endofheader;
  131. default:
  132. LOG( L_ERR , "ERROR: parse_to_param : "
  133. "unexpected char [%c] in status %d: <<%.*s>> .\n",
  134. *tmp,status, (int)(tmp-buffer), ZSW(buffer));
  135. goto error;
  136. }
  137. break;
  138. case '\r':
  139. switch (status)
  140. {
  141. case S_PARA_NAME:
  142. case S_EQUAL:
  143. case S_PARA_VALUE:
  144. case E_PARA_VALUE:
  145. saved_status=status;
  146. status=F_CR;
  147. break;
  148. case TAG3:
  149. param->type=TAG_PARAM;
  150. case PARA_NAME:
  151. case TAG1:
  152. case TAG2:
  153. param->name.len = tmp-param->name.s;
  154. saved_status = S_EQUAL;
  155. status = F_CR;
  156. break;
  157. case PARA_VALUE_TOKEN:
  158. param->value.len = tmp-param->value.s;
  159. saved_status = E_PARA_VALUE;
  160. status = F_CR;
  161. add_param(param, to_b, newparam);
  162. break;
  163. case F_CRLF:
  164. case F_CR:
  165. case F_LF:
  166. status=saved_status;
  167. goto endofheader;
  168. default:
  169. LOG( L_ERR , "ERROR: parse_to_param : "
  170. "unexpected char [%c] in status %d: <<%.*s>> .\n",
  171. *tmp,status, (int)(tmp-buffer), ZSW(buffer));
  172. goto error;
  173. }
  174. break;
  175. case 0:
  176. switch (status)
  177. {
  178. case TAG3:
  179. param->type = TAG_PARAM;
  180. case PARA_NAME:
  181. case TAG1:
  182. case TAG2:
  183. param->name.len = tmp-param->name.s;
  184. status = S_EQUAL;
  185. case S_EQUAL:
  186. case S_PARA_VALUE:
  187. saved_status=status;
  188. goto endofheader;
  189. case PARA_VALUE_TOKEN:
  190. status = E_PARA_VALUE;
  191. param->value.len = tmp-param->value.s;
  192. add_param(param , to_b, newparam);
  193. case E_PARA_VALUE:
  194. saved_status = status;
  195. goto endofheader;
  196. break;
  197. default:
  198. LOG( L_ERR , "ERROR: parse_to_param : "
  199. "unexpected char [%c] in status %d: <<%.*s>> .\n",
  200. *tmp,status, (int)(tmp-buffer), ZSW(buffer));
  201. goto error;
  202. }
  203. break;
  204. case '\\':
  205. switch (status)
  206. {
  207. case PARA_VALUE_QUOTED:
  208. switch (*(tmp+1))
  209. {
  210. case '\r':
  211. case '\n':
  212. break;
  213. default:
  214. tmp++;
  215. }
  216. default:
  217. LOG( L_ERR , "ERROR: parse_to_param : "
  218. "unexpected char [%c] in status %d: <<%.*s>> .\n",
  219. *tmp,status, (int)(tmp-buffer), ZSW(buffer));
  220. goto error;
  221. }
  222. break;
  223. case '"':
  224. switch (status)
  225. {
  226. case S_PARA_VALUE:
  227. param->value.s = tmp+1;
  228. status = PARA_VALUE_QUOTED;
  229. break;
  230. case PARA_VALUE_QUOTED:
  231. param->value.len=tmp-param->value.s;
  232. add_param(param, to_b, newparam);
  233. status = E_PARA_VALUE;
  234. break;
  235. case F_CRLF:
  236. case F_LF:
  237. case F_CR:
  238. /*previous=crlf and now !=' '*/
  239. goto endofheader;
  240. default:
  241. LOG( L_ERR , "ERROR: parse_to_param :"
  242. "unexpected char [%c] in status %d: <<%.*s>> .\n",
  243. *tmp,status,(int)(tmp-buffer), ZSW(buffer));
  244. goto error;
  245. }
  246. break;
  247. case ';' :
  248. switch (status)
  249. {
  250. case PARA_VALUE_QUOTED:
  251. break;
  252. case TAG3:
  253. param->type = TAG_PARAM;
  254. case PARA_NAME:
  255. case TAG1:
  256. case TAG2:
  257. param->name.len = tmp-param->name.s;
  258. case S_EQUAL:
  259. param->value.s = 0;
  260. param->value.len = 0;
  261. goto semicolon_add_param;
  262. case S_PARA_VALUE:
  263. param->value.s = tmp;
  264. case PARA_VALUE_TOKEN:
  265. param->value.len=tmp-param->value.s;
  266. semicolon_add_param:
  267. add_param(param, to_b, newparam);
  268. case E_PARA_VALUE:
  269. param = (struct to_param*)
  270. pkg_malloc(sizeof(struct to_param));
  271. if (!param){
  272. LOG( L_ERR , "ERROR: parse_to_param"
  273. " - out of memory\n" );
  274. goto error;
  275. }
  276. memset(param,0,sizeof(struct to_param));
  277. param->type=GENERAL_PARAM;
  278. status = S_PARA_NAME;
  279. /* link to free mem if not added in to_body list */
  280. newparam = param;
  281. break;
  282. case F_CRLF:
  283. case F_LF:
  284. case F_CR:
  285. /*previous=crlf and now !=' '*/
  286. goto endofheader;
  287. default:
  288. LOG( L_ERR , "ERROR: parse_to_param :"
  289. "unexpected char [%c] in status %d: <<%.*s>> .\n",
  290. *tmp,status, (int)(tmp-buffer), ZSW(buffer));
  291. goto error;
  292. }
  293. break;
  294. case 'T':
  295. case 't' :
  296. switch (status)
  297. {
  298. case PARA_VALUE_QUOTED:
  299. case PARA_VALUE_TOKEN:
  300. case PARA_NAME:
  301. break;
  302. case S_PARA_NAME:
  303. param->name.s = tmp;
  304. status = TAG1;
  305. break;
  306. case S_PARA_VALUE:
  307. param->value.s = tmp;
  308. status = PARA_VALUE_TOKEN;
  309. break;
  310. case TAG1:
  311. case TAG2:
  312. case TAG3:
  313. status = PARA_NAME;
  314. break;
  315. case F_CRLF:
  316. case F_LF:
  317. case F_CR:
  318. /*previous=crlf and now !=' '*/
  319. goto endofheader;
  320. default:
  321. LOG( L_ERR , "ERROR: parse_to_param :"
  322. "unexpected char [%c] in status %d: <<%.*s>> .\n",
  323. *tmp,status, (int)(tmp-buffer), ZSW(buffer));
  324. goto error;
  325. }
  326. break;
  327. case 'A':
  328. case 'a' :
  329. switch (status)
  330. {
  331. case PARA_VALUE_QUOTED:
  332. case PARA_VALUE_TOKEN:
  333. case PARA_NAME:
  334. break;
  335. case S_PARA_NAME:
  336. param->name.s = tmp;
  337. status = PARA_NAME;
  338. break;
  339. case S_PARA_VALUE:
  340. param->value.s = tmp;
  341. status = PARA_VALUE_TOKEN;
  342. break;
  343. case TAG1:
  344. status = TAG2;
  345. break;
  346. case TAG2:
  347. case TAG3:
  348. status = PARA_NAME;
  349. break;
  350. case F_CRLF:
  351. case F_LF:
  352. case F_CR:
  353. /*previous=crlf and now !=' '*/
  354. goto endofheader;
  355. default:
  356. LOG( L_ERR , "ERROR: parse_to_param : "
  357. "unexpected char [%c] in status %d: <<%.*s>> .\n",
  358. *tmp,status, (int)(tmp-buffer), ZSW(buffer));
  359. goto error;
  360. }
  361. break;
  362. case 'G':
  363. case 'g' :
  364. switch (status)
  365. {
  366. case PARA_VALUE_QUOTED:
  367. case PARA_VALUE_TOKEN:
  368. case PARA_NAME:
  369. break;
  370. case S_PARA_NAME:
  371. param->name.s = tmp;
  372. status = PARA_NAME;
  373. break;
  374. case S_PARA_VALUE:
  375. param->value.s = tmp;
  376. status = PARA_VALUE_TOKEN;
  377. break;
  378. case TAG1:
  379. case TAG3:
  380. status = PARA_NAME;
  381. break;
  382. case TAG2:
  383. status = TAG3;
  384. break;
  385. case F_CRLF:
  386. case F_LF:
  387. case F_CR:
  388. /*previous=crlf and now !=' '*/
  389. goto endofheader;
  390. default:
  391. LOG( L_ERR , "ERROR: parse_to_param : "
  392. "unexpected char [%c] in status %d: <<%.*s>> .\n",
  393. *tmp,status, (int)(tmp-buffer), ZSW(buffer));
  394. goto error;
  395. }
  396. break;
  397. case '=':
  398. switch (status)
  399. {
  400. case PARA_VALUE_QUOTED:
  401. break;
  402. case TAG3:
  403. param->type=TAG_PARAM;
  404. case PARA_NAME:
  405. case TAG1:
  406. case TAG2:
  407. param->name.len = tmp-param->name.s;
  408. status = S_PARA_VALUE;
  409. break;
  410. case S_EQUAL:
  411. status = S_PARA_VALUE;
  412. break;
  413. case F_CRLF:
  414. case F_LF:
  415. case F_CR:
  416. /*previous=crlf and now !=' '*/
  417. goto endofheader;
  418. default:
  419. LOG( L_ERR , "ERROR: parse_to_param : "
  420. "unexpected char [%c] in status %d: <<%.*s>> .\n",
  421. *tmp,status, (int)(tmp-buffer), ZSW(buffer));
  422. goto error;
  423. }
  424. break;
  425. default:
  426. switch (status)
  427. {
  428. case TAG1:
  429. case TAG2:
  430. case TAG3:
  431. status = PARA_NAME;
  432. break;
  433. case PARA_VALUE_TOKEN:
  434. case PARA_NAME:
  435. case PARA_VALUE_QUOTED:
  436. break;
  437. case S_PARA_NAME:
  438. param->name.s = tmp;
  439. status = PARA_NAME;
  440. break;
  441. case S_PARA_VALUE:
  442. param->value.s = tmp;
  443. status = PARA_VALUE_TOKEN;
  444. break;
  445. case F_CRLF:
  446. case F_LF:
  447. case F_CR:
  448. /*previous=crlf and now !=' '*/
  449. goto endofheader;
  450. default:
  451. LOG(L_ERR, "ERROR: parse_to_param: "
  452. "spitting out [%c] in status %d\n",*tmp,status );
  453. goto error;
  454. }
  455. }/*switch*/
  456. }/*for*/
  457. if (!(status==F_CR || status==F_LF || status==F_CRLF))
  458. saved_status=status;
  459. endofheader:
  460. switch(saved_status){
  461. case TAG3:
  462. param->type = TAG_PARAM; /* tag at the end */
  463. /* no break */
  464. case PARA_NAME:
  465. case TAG1:
  466. case TAG2:
  467. param->name.len = tmp-param->name.s;
  468. /* no break */
  469. case S_EQUAL:
  470. /* parameter without '=', e.g. foo */
  471. param->value.s=0;
  472. param->value.len=0;
  473. add_param(param, to_b, newparam);
  474. saved_status=E_PARA_VALUE;
  475. break;
  476. case S_PARA_VALUE:
  477. /* parameter with null value, e.g. foo= */
  478. param->value.s=tmp;
  479. param->value.len=0;
  480. add_param(param, to_b, newparam);
  481. saved_status=E_PARA_VALUE;
  482. break;
  483. case PARA_VALUE_TOKEN:
  484. param->value.len=tmp-param->value.s;
  485. add_param(param, to_b, newparam);
  486. saved_status=E_PARA_VALUE;
  487. break;
  488. case E_PARA_VALUE:
  489. break;
  490. default:
  491. LOG( L_ERR , "ERROR: parse_to_param : unexpected end of header,"
  492. " status %d: <<%.*s>> .\n",
  493. saved_status, (int)(tmp-buffer), ZSW(buffer));
  494. goto error;
  495. }
  496. *returned_status=saved_status;
  497. return tmp;
  498. error:
  499. if (newparam) pkg_free(newparam);
  500. to_b->error=PARSE_ERROR;
  501. *returned_status = status;
  502. return tmp;
  503. }
  504. char* parse_to(char* const buffer, const char* const end, struct to_body* const to_b)
  505. {
  506. int status;
  507. int saved_status;
  508. char *tmp,*foo;
  509. saved_status=START_TO; /* fixes gcc 4.x warning */
  510. status=START_TO;
  511. memset(to_b, 0, sizeof(struct to_body));
  512. to_b->error=PARSE_OK;
  513. foo=0;
  514. for( tmp=buffer; tmp<end; tmp++)
  515. {
  516. switch(*tmp)
  517. {
  518. case ' ':
  519. case '\t':
  520. switch (status)
  521. {
  522. case F_CRLF:
  523. case F_LF:
  524. case F_CR:
  525. /*previous=crlf and now =' '*/
  526. status=saved_status;
  527. break;
  528. case URI_ENCLOSED:
  529. to_b->uri.len = tmp - to_b->uri.s;
  530. status = E_URI_ENCLOSED;
  531. break;
  532. case URI_OR_TOKEN:
  533. foo = tmp;
  534. status = MAYBE_URI_END;
  535. break;
  536. case DISPLAY_TOKEN:
  537. foo = tmp;
  538. status = DISPLAY_TOKEN_SP;
  539. break;
  540. }
  541. break;
  542. case '\n':
  543. switch (status)
  544. {
  545. case URI_OR_TOKEN:
  546. foo = tmp;
  547. status = MAYBE_URI_END;
  548. case MAYBE_URI_END:
  549. case DISPLAY_TOKEN_SP:
  550. case E_DISPLAY_QUOTED:
  551. case END:
  552. saved_status=status;
  553. status=F_LF;
  554. break;
  555. case DISPLAY_TOKEN:
  556. foo=tmp;
  557. saved_status=DISPLAY_TOKEN_SP;
  558. status=F_LF;
  559. break;
  560. case F_CR:
  561. status=F_CRLF;
  562. break;
  563. case F_CRLF:
  564. case F_LF:
  565. status=saved_status;
  566. goto endofheader;
  567. default:
  568. LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
  569. "in status %d: <<%.*s>> .\n",
  570. *tmp,status, (int)(tmp-buffer), ZSW(buffer));
  571. goto error;
  572. }
  573. break;
  574. case '\r':
  575. switch (status)
  576. {
  577. case URI_OR_TOKEN:
  578. foo = tmp;
  579. status = MAYBE_URI_END;
  580. case MAYBE_URI_END:
  581. case DISPLAY_TOKEN_SP:
  582. case E_DISPLAY_QUOTED:
  583. case END:
  584. saved_status=status;
  585. status=F_CR;
  586. break;
  587. case DISPLAY_TOKEN:
  588. foo=tmp;
  589. saved_status=DISPLAY_TOKEN_SP;
  590. status=F_CR;
  591. break;
  592. case F_CRLF:
  593. case F_CR:
  594. case F_LF:
  595. status=saved_status;
  596. goto endofheader;
  597. default:
  598. LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
  599. "in status %d: <<%.*s>> .\n",
  600. *tmp,status, (int)(tmp-buffer), ZSW(buffer));
  601. goto error;
  602. }
  603. break;
  604. case 0:
  605. switch (status)
  606. {
  607. case URI_OR_TOKEN:
  608. case MAYBE_URI_END:
  609. to_b->uri.len = tmp - to_b->uri.s;
  610. case END:
  611. saved_status = status = END;
  612. goto endofheader;
  613. default:
  614. LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
  615. "in status %d: <<%.*s>> .\n",
  616. *tmp,status, (int)(tmp-buffer), ZSW(buffer));
  617. goto error;
  618. }
  619. break;
  620. case '\\':
  621. switch (status)
  622. {
  623. case DISPLAY_QUOTED:
  624. tmp++; /* jump over next char */
  625. break;
  626. default:
  627. LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
  628. "in status %d: <<%.*s>> .\n",
  629. *tmp,status, (int)(tmp-buffer), ZSW(buffer));
  630. goto error;
  631. }
  632. break;
  633. case '<':
  634. switch (status)
  635. {
  636. case START_TO:
  637. to_b->body.s=tmp;
  638. status = S_URI_ENCLOSED;
  639. break;
  640. case DISPLAY_QUOTED:
  641. break;
  642. case E_DISPLAY_QUOTED:
  643. status = S_URI_ENCLOSED;
  644. break;
  645. case URI_OR_TOKEN:
  646. case DISPLAY_TOKEN:
  647. to_b->display.len=tmp-to_b->display.s;
  648. status = S_URI_ENCLOSED;
  649. break;
  650. case DISPLAY_TOKEN_SP:
  651. case MAYBE_URI_END:
  652. to_b->display.len=foo-to_b->display.s;
  653. status = S_URI_ENCLOSED;
  654. break;
  655. case F_CRLF:
  656. case F_LF:
  657. case F_CR:
  658. /*previous=crlf and now !=' '*/
  659. goto endofheader;
  660. default:
  661. LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
  662. "in status %d: <<%.*s>> .\n",
  663. *tmp,status, (int)(tmp-buffer), ZSW(buffer));
  664. goto error;
  665. }
  666. break;
  667. case '>':
  668. switch (status)
  669. {
  670. case DISPLAY_QUOTED:
  671. break;
  672. case URI_ENCLOSED:
  673. to_b->uri.len = tmp - to_b->uri.s;
  674. case E_URI_ENCLOSED:
  675. status = END;
  676. foo = 0;
  677. break;
  678. case F_CRLF:
  679. case F_LF:
  680. case F_CR:
  681. /*previous=crlf and now !=' '*/
  682. goto endofheader;
  683. default:
  684. LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
  685. "in status %d: <<%.*s>> .\n",
  686. *tmp,status, (int)(tmp-buffer), ZSW(buffer));
  687. goto error;
  688. }
  689. break;
  690. case '"':
  691. switch (status)
  692. {
  693. case START_TO:
  694. to_b->body.s = tmp;
  695. to_b->display.s = tmp;
  696. status = DISPLAY_QUOTED;
  697. break;
  698. case DISPLAY_QUOTED:
  699. status = E_DISPLAY_QUOTED;
  700. to_b->display.len = tmp-to_b->display.s+1;
  701. break;
  702. case F_CRLF:
  703. case F_LF:
  704. case F_CR:
  705. /*previous=crlf and now !=' '*/
  706. goto endofheader;
  707. default:
  708. LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
  709. "in status %d: <<%.*s>> .\n",
  710. *tmp,status, (int)(tmp-buffer), buffer);
  711. goto error;
  712. }
  713. break;
  714. case ';' :
  715. switch (status)
  716. {
  717. case DISPLAY_QUOTED:
  718. case URI_ENCLOSED:
  719. break;
  720. case URI_OR_TOKEN:
  721. foo = tmp;
  722. case MAYBE_URI_END:
  723. to_b->uri.len = foo - to_b->uri.s;
  724. case END:
  725. to_b->body.len = tmp-to_b->body.s;
  726. tmp = parse_to_param(tmp,end,to_b,&saved_status);
  727. goto endofheader;
  728. case F_CRLF:
  729. case F_LF:
  730. case F_CR:
  731. /*previous=crlf and now !=' '*/
  732. goto endofheader;
  733. default:
  734. LOG( L_ERR , "ERROR: parse_to : unexpected char [%c] "
  735. "in status %d: <<%.*s>> .\n",
  736. *tmp,status, (int)(tmp-buffer), buffer);
  737. goto error;
  738. }
  739. break;
  740. default:
  741. switch (status)
  742. {
  743. case START_TO:
  744. to_b->uri.s = to_b->body.s = tmp;
  745. status = URI_OR_TOKEN;
  746. to_b->display.s=tmp;
  747. break;
  748. case S_URI_ENCLOSED:
  749. to_b->uri.s=tmp;
  750. status=URI_ENCLOSED;
  751. break;
  752. case MAYBE_URI_END:
  753. case DISPLAY_TOKEN_SP:
  754. status = DISPLAY_TOKEN;
  755. case DISPLAY_QUOTED:
  756. case DISPLAY_TOKEN:
  757. case URI_ENCLOSED:
  758. case URI_OR_TOKEN:
  759. break;
  760. case F_CRLF:
  761. case F_LF:
  762. case F_CR:
  763. /*previous=crlf and now !=' '*/
  764. goto endofheader;
  765. default:
  766. DBG("DEBUG:parse_to: spitting out [%c] in status %d\n",
  767. *tmp,status );
  768. goto error;
  769. }
  770. }/*char switch*/
  771. }/*for*/
  772. endofheader:
  773. if (to_b->display.len==0) to_b->display.s=0;
  774. status=saved_status;
  775. DBG("end of header reached, state=%d\n", status);
  776. /* check if error*/
  777. switch(status){
  778. case MAYBE_URI_END:
  779. to_b->uri.len = foo - to_b->uri.s;
  780. case END:
  781. to_b->body.len = tmp - to_b->body.s;
  782. case E_PARA_VALUE:
  783. break;
  784. default:
  785. LOG(L_ERR, "ERROR: parse_to: invalid To - unexpected "
  786. "end of header in state %d\n", status);
  787. goto error;
  788. }
  789. return tmp;
  790. error:
  791. to_b->error=PARSE_ERROR;
  792. return tmp;
  793. }
  794. void free_to_params(struct to_body* const tb)
  795. {
  796. struct to_param *tp=tb->param_lst;
  797. struct to_param *foo;
  798. while (tp){
  799. foo = tp->next;
  800. pkg_free(tp);
  801. tp=foo;
  802. }
  803. }
  804. void free_to(struct to_body* const tb)
  805. {
  806. free_to_params(tb);
  807. pkg_free(tb);
  808. }
  809. int parse_to_header(struct sip_msg* const msg)
  810. {
  811. if ( !msg->to && ( parse_headers(msg,HDR_TO_F,0)==-1 || !msg->to)) {
  812. ERR("bad msg or missing TO header\n");
  813. return -1;
  814. }
  815. // HDR_TO_T is automatically parsed (get_hdr_field in parser/msg_parser.c)
  816. // so check only ptr validity
  817. if (msg->to->parsed)
  818. return 0;
  819. else
  820. return -1;
  821. }
  822. sip_uri_t *parse_to_uri(sip_msg_t* const msg)
  823. {
  824. to_body_t *tb = NULL;
  825. if(msg==NULL)
  826. return NULL;
  827. if(parse_to_header(msg)<0)
  828. {
  829. LM_ERR("cannot parse TO header\n");
  830. return NULL;
  831. }
  832. if(msg->to==NULL || get_to(msg)==NULL)
  833. return NULL;
  834. tb = get_to(msg);
  835. if(tb->parsed_uri.user.s!=NULL || tb->parsed_uri.host.s!=NULL)
  836. return &tb->parsed_uri;
  837. if (parse_uri(tb->uri.s, tb->uri.len , &tb->parsed_uri)<0)
  838. {
  839. LM_ERR("failed to parse To uri\n");
  840. memset(&tb->parsed_uri, 0, sizeof(struct sip_uri));
  841. return NULL;
  842. }
  843. return &tb->parsed_uri;
  844. }