home *** CD-ROM | disk | FTP | other *** search
/ PDA Software Library / pdasoftwarelib.iso / PSION / COMMS / PSIONMAI / PMFULLSO / SUNMAIL / SCCS / S6.C < prev    next >
Encoding:
Text File  |  1995-07-13  |  11.3 KB  |  535 lines

  1. h25139
  2. s 00002/00000/00384
  3. d D 1.4 95/07/13 09:51:09 tim 4 3
  4. c on the shorten line routine ensure that the space is clobbered otherwise if str[PSIONHDR] isspace the line will not get truncated
  5. e
  6. s 00054/00014/00330
  7. d D 1.3 95/07/12 20:18:42 tim 3 2
  8. c fixed some argument processing errors, made it truncate lines if a header line is 100 or more characters
  9. e
  10. s 00071/00012/00273
  11. d D 1.2 95/07/12 19:44:37 tim 2 1
  12. c added a -d flag which deletes all header lines appart from the ones we are interested in 
  13. e
  14. s 00285/00000/00000
  15. d D 1.1 95/07/04 22:47:12 tim 1 0
  16. c 
  17. e
  18. u
  19. U
  20. f e 0
  21. t
  22. T
  23. I 1
  24. /* this file extracts the to, from, subject cc list and bcc lists from a file
  25.    in argv[1]. If if discovers a line just containing \n it stops processing
  26.    as we may be inside the body of the message. on discovering a from line
  27.    it reads the first word and discards the reas (many mailers generate
  28.    from lines like 
  29.       From: tim.graves@uk.sun.com (Tim Graves Principal Sales Support Specialist)
  30.    and the address is all we are interested in.
  31.    To, cc and bcc (should we ever see a bcc list!) can be multi line
  32.    to handle these we just join the lines together untill we see a line
  33.    containing a : in the future we should remove whitespace as well
  34.  
  35.    After extracting the information it is written to a file based on the
  36.    input file as defined by the define HDRSKELETON. Ths information
  37.    is in a format ready for the meta routines appart from the header and
  38.    trailer strings 
  39.  
  40.    NOTE this is based around the way the sun mailer works. I dont have
  41.    information about other mail delivery systems */
  42. #include <stdio.h>
  43. #include <string.h>
  44. I 3
  45. #include <ctype.h>
  46. E 3
  47. #define TOSTR "To: "
  48. #define FROMSTR "From: "
  49. #define CCSTR "Cc: "
  50. #define BCCSTR "Bcc: "
  51. #define SUBJECTSTR "Subject: "
  52.  
  53. #define HDRSKELETON "%s.hdr"
  54. /* the maximum size used in a headr, note the psion currently uses 100 as this value */
  55. /* we should be OK with this as I think SMTP limits header stuff to 80 chars */
  56. #define MAXHDR 1024
  57. I 3
  58. /* DO not change this without changing the HDRLEN #define in the mail.c program for the psion */
  59. #define PSIONHDR 100
  60. E 3
  61. /* return values from getline */
  62. #define COLON 3
  63. #define NOCOLON 2
  64. #define TRUE 1
  65. #define FALSE 0
  66. I 2
  67. /* temp location to hold the headerless message */
  68. #define TMPNAME "/tmp/nohdr.msg"
  69. E 2
  70. /* globals, makes life easier in this case */
  71. char to[MAXHDR], from[MAXHDR], cc[MAXHDR], bcc[MAXHDR], subject[MAXHDR] ;
  72. char inpline[MAXHDR] ;
  73. FILE * fd ;
  74. I 2
  75. FILE * outfd ;
  76. E 2
  77. int dontfgets = FALSE ;
  78. I 2
  79. int delflag = FALSE ;
  80. I 3
  81. int truncflag = FALSE ;
  82. E 3
  83. E 2
  84.  
  85.  
  86. main(argc, argv)
  87. int argc ;
  88. char * argv[] ;
  89. {
  90.     char fname[MAXHDR] ;
  91. D 2
  92.     if (argc != 2)
  93. E 2
  94. I 2
  95.     char cmd[1024] ;
  96.     int ret ;
  97. D 3
  98.     if ((argc != 2) && (argc != 3))
  99. E 3
  100. I 3
  101.     if ((argc < 2) || (argc > 3))
  102. E 3
  103. E 2
  104.     {
  105. D 2
  106.         printf("Usage: extractheadr mailfile\n") ;
  107. E 2
  108. I 2
  109.         printf("Usage: extractheadr mailfile [-d]\n") ;
  110. E 2
  111.         exit(1) ;
  112.     }
  113. I 2
  114. D 3
  115.     if ((argc == 3) && (strcmp("-d", argv[2]) == 0))
  116.         delflag = TRUE ;
  117.     else
  118. E 3
  119. I 3
  120.     if (argc == 3) 
  121. E 3
  122.     {
  123. D 3
  124.         printf("Usage: extractheadr mailfile [-d]\n") ;
  125.         delflag = FALSE ;
  126. E 3
  127. I 3
  128.         if (strcmp("-d", argv[2]) == 0)
  129.             delflag = TRUE ;
  130.         else
  131.         {
  132.             printf("Usage:  extractheadr mailfile [-d]\n") ;
  133.             delflag = FALSE ;
  134.         }
  135. E 3
  136.     }
  137. E 2
  138.     if ((fd = fopen(argv[1], "r"))== NULL)
  139.     {
  140.         printf("extractheadr, cant open input %s\n", argv[1]) ;
  141.         exit(2) ;
  142.     }
  143.     init() ;
  144. D 2
  145.     process(fd) ;
  146. E 2
  147. I 2
  148.     ret = process(fd) ;
  149.     if (ret == EOF)
  150.     {
  151.         printf("Error found EOF in headers\n") ;
  152.     }
  153.     if ((delflag == TRUE) && (ret == FALSE))
  154.     {
  155. I 3
  156.         /* if truncflag is TRUE one or more header lines will have been truncated */
  157.         if (truncflag == TRUE)
  158.             fprintf(outfd, "WARNING - One or more header lines have been truncated\n") ;
  159. E 3
  160.         /* if we are deleting the headers */
  161.         copyremaining() ;
  162.         fclose(outfd) ;
  163.         sprintf(cmd, "mv %s %s", TMPNAME, argv[1]) ;
  164.         system(cmd) ;
  165.     }
  166. E 2
  167.     fclose(fd) ;
  168.     sprintf(fname, HDRSKELETON, argv[1]) ;
  169.     if ((fd = fopen(fname, "w")) == NULL) 
  170.     {
  171.         printf("extractheadr, cant open output file %s\n", fname) ;
  172.         exit(3) ;
  173.     }
  174.     output(fd, argv[1]) ;
  175.     fclose(fd) ;
  176. }
  177. output(fd, fname)
  178. FILE * fd ;
  179. char * fname;
  180. {
  181. D 3
  182.     fprintf(fd, "%s\n", fname) ;
  183.     fprintf(fd, "%s\n", to) ;
  184.     fprintf(fd, "%s\n", from) ;
  185.     fprintf(fd, "%s\n", subject) ;
  186.     fprintf(fd, "%s\n", cc) ;
  187.     fprintf(fd, "%s\n", bcc) ;
  188.     fprintf(fd, "N\n") ; /* mark the email as unread */
  189. E 3
  190. I 3
  191.     doout(fd, fname) ;
  192.     doout(fd, to) ;
  193.     doout(fd, from) ;
  194.     doout(fd, subject) ;
  195.     doout(fd, cc) ;
  196.     doout(fd, bcc) ;
  197.     doout(fd, "N") ; /* mark the email as unread */
  198. E 3
  199. }
  200. I 3
  201. doout(fd, str)
  202. FILE * fd ;
  203. char * str ;
  204. {
  205.     fprintf(fd, "%s\n", str) ;
  206. }
  207. shortstr(str)
  208. char * str ;
  209. {
  210.     int i ;
  211.     /* output upto PSIONHDR chars AT MOST */
  212.     if (strlen(str) >= ((size_t) PSIONHDR))
  213.     {
  214.         /* munge down to the first space before the PSIONHDR */
  215.         i = PSIONHDR ;
  216.         while (! isspace(str[i]))
  217.         {
  218.             str[i] = '\0' ;
  219.             i -- ;
  220.         }
  221. I 4
  222.         /* str[i] will be a space, bash that as well */
  223.         str[i] = '\0' ;
  224. E 4
  225.         truncflag = TRUE ;
  226.     }
  227. }
  228.  
  229. E 3
  230. init()
  231. {
  232.     to[0] = '\0' ;
  233.     from[0] = '\0' ;
  234.     subject[0] = '\0' ;
  235.     cc[0] = '\0' ;
  236.     bcc[0] = '\0' ;
  237. I 2
  238.     if (delflag == TRUE)
  239.     {
  240.         if ((outfd = fopen(TMPNAME, "w")) == NULL)
  241.         {
  242.             printf("Warning, could not open %s as temp file, cannot remove unwanted headers\n", TMPNAME) ;
  243.             delflag = FALSE ;
  244.         }
  245.     }
  246. E 2
  247. }
  248.  
  249. process()
  250. {
  251.     int ret;
  252.     ret = getline() ;
  253. D 2
  254.     while( ret != FALSE)
  255. E 2
  256. I 2
  257.     while(( ret != FALSE) && (ret != EOF))
  258. E 2
  259.     {
  260.         /* do the comparisons */
  261.         if (strncasecmp(FROMSTR, inpline, strlen(FROMSTR)) == 0)
  262.             ret = dofrom() ;
  263.         else if(strncasecmp(TOSTR, inpline, strlen(TOSTR)) == 0)
  264. D 2
  265.             ret = domulti(to) ;
  266. E 2
  267. I 2
  268.             ret = domulti(to, TOSTR) ;
  269. E 2
  270.         else if(strncasecmp(SUBJECTSTR, inpline, strlen(SUBJECTSTR)) == 0)
  271.             ret = dosubject() ;
  272.         else if(strncasecmp(CCSTR, inpline, strlen(CCSTR)) == 0)
  273. D 2
  274.             ret = domulti(cc) ;
  275. E 2
  276. I 2
  277.             ret = domulti(cc, CCSTR) ;
  278. E 2
  279.         else if(strncasecmp(BCCSTR, inpline, strlen(BCCSTR)) == 0)
  280. D 2
  281.             ret = domulti(bcc) ;
  282.         if(ret != FALSE)
  283. E 2
  284. I 2
  285.             ret = domulti(bcc, BCCSTR) ;
  286.         if((ret != FALSE) && (ret != EOF))
  287. E 2
  288.             ret = getline() ;
  289.     }
  290. I 2
  291.     return (ret) ;
  292. E 2
  293. }
  294. dofrom()
  295. {
  296.     char * start, *end ;
  297.     /* ths line is probabaly of the format
  298.        From: tim.graves@uk.sun.com (Tim Graves, Sun UK Principal Sales Support)
  299.        fortunatly we know we have removed all the whitespace down to
  300.        single spaces to the character after the first space is the
  301.        start of the address and the next space (If it is there)
  302.        is the end */
  303.     start = strchr(inpline, ' ') ;
  304.     /* if start is NULL there is no from address (dogy of what) 
  305.        hopefully it will be found later */
  306.     if (start == NULL)
  307.         return(COLON) ;
  308.     /* move over the space */
  309.     start ++ ;
  310.     /* find the next space */
  311.     end = strchr(start, ' ') ;
  312.     /* if end is null no space otherwise terminate the string */
  313.     if (end != NULL)
  314.     {
  315.         *end = '\0' ;
  316.     }
  317.     /* copy the string over */
  318.     strcpy(from, start) ;
  319. I 3
  320.     /* reduce the string to something manageable */
  321.     shortstr(from) ;
  322. E 3
  323. I 2
  324.     /* if delflag write the line out */
  325.     if (delflag == TRUE)
  326.     {
  327.         fprintf(outfd, "%s%s\n", FROMSTR, from) ;
  328.     }
  329. E 2
  330.     return(COLON) ; /* there MUST have been a colon here for us to be called */
  331. }
  332. dosubject()
  333. {
  334.     char * start ;
  335.     /* this is even easier, we just need to find the first space and then copy over */
  336.     start = strchr(inpline, ' ') ;
  337.     /* if start is NULL there is no subject */
  338.     if (start == NULL)
  339.         return(COLON) ;
  340.     start ++ ; /* move over the space */
  341.     strcpy(subject, start) ;
  342. I 3
  343.     /* reduce the string to something manageable */
  344.     shortstr(subject) ;
  345. E 3
  346. I 2
  347.     /* ifdelflag write the line out */
  348.     if (delflag == TRUE)
  349.     {
  350.         fprintf(outfd, "%s%s\n", SUBJECTSTR, subject) ;
  351.     }
  352. E 2
  353.     return(COLON) ;
  354. }
  355.  
  356. D 2
  357. domulti(targetstr)
  358. char * targetstr ;
  359. E 2
  360. I 2
  361. domulti(targetstr, hdr)
  362. char * targetstr, *hdr ;
  363. E 2
  364. {
  365.     char * start ;
  366.     int ret ;
  367.     /* as per subject but to cc and bcc can be multi line
  368.        copy over the first line and then call multiline to add the 
  369.        following lines */
  370.     start = strchr(inpline, ' ') ;
  371.     if (start == NULL)
  372.         return(COLON) ;
  373.     start ++ ;
  374.     strcpy(targetstr, start) ;
  375.     ret = multiline(targetstr) ;
  376. I 3
  377.     /* reduce the string to something manageable */
  378.     shortstr(targetstr) ;
  379. E 3
  380. I 2
  381.     if (delflag == TRUE)
  382.     {
  383. D 3
  384.         fprintf(outfd, "%s: %s\n", hdr, targetstr) ;
  385. E 3
  386. I 3
  387.         fprintf(outfd, "%s%s\n", hdr, targetstr) ;
  388. E 3
  389.     }
  390. E 2
  391.     return(ret) ;
  392. }
  393. multiline(targetstr)
  394. char * targetstr;
  395. {
  396.     int ret ;
  397.     int inlen, targetlen ;
  398.     /* provided the line returns NOCOLON from getline add the current
  399.        and new inpute together (remembering to add a space)
  400.        if getline doesnot return NOCOLON we have reached the end
  401.        set dontfgets to leave the line untopuched for further work */
  402.     ret = getline() ;
  403.     if (ret != NOCOLON)
  404.     {
  405.         dontfgets = TRUE ;
  406.         return(ret) ;
  407.     }
  408.     /* we are OK add to the current line */
  409.     while (ret == NOCOLON)
  410.     {
  411.         /* work out the lengths */
  412.         inlen = strlen(inpline) ;
  413.         targetlen = strlen(targetstr) ;
  414.         /* if there if no space eat up the input and break out */
  415.         if ((inlen + targetlen) > MAXHDR)
  416.         {
  417.             while((ret = getline()) == COLON)
  418.                 ;
  419.             dontfgets = TRUE ;
  420.             return(ret) ;
  421.         }
  422.         /* append a ' ' to targetstr */
  423.         strcat(targetstr, " ") ;
  424.         strcat(targetstr, inpline) ;
  425.         ret = getline() ;
  426.     }
  427.     /* we have got a line containing : set dontfget and return the ret */
  428.     dontfgets = TRUE ;
  429.     return(ret) ;
  430. }
  431. I 2
  432. copyremaining()
  433. {
  434.     char * ret ;
  435.     char tmp[1024] ;
  436.     ret = &tmp[0] ;
  437.     while (ret != NULL)
  438.     {
  439.         ret = fgets(tmp, 1024, fd) ;
  440.         fputs(tmp, outfd) ;
  441.     }
  442. }
  443. E 2
  444. getline()
  445. {
  446.     char tmp[MAXHDR] ;
  447.     int inctr, outctr ;
  448.     char *ret ;
  449.     int white ;
  450.     int len ;
  451.  
  452. D 2
  453.     /* if EOF or the line is just \n return FALSE
  454. E 2
  455. I 2
  456.     /* if EOF or the line is just \n return FALSE or EOF
  457. E 2
  458.        otherwise return COLON if the line contains a :
  459.        or NOCOLON otherwise */
  460.  
  461.     /* if dontfgets is set the line has been left over from
  462.        previous processing, the line will be OK and will contain
  463.        a : to have got here to just return COLON */
  464.     if (dontfgets == TRUE)
  465.     {
  466.         dontfgets = FALSE ; /* done want to get into a loop */
  467.         return(COLON) ;
  468.     }
  469.     ret = fgets(tmp, MAXHDR, fd) ;
  470.     /* if the EOF ret will be NULL so return */
  471.     if (ret == NULL)
  472. D 2
  473.         return(FALSE) ;
  474. E 2
  475. I 2
  476.         return(EOF) ;
  477. E 2
  478.     /* if the line is just a newline return FALSE */
  479.     len = strlen(tmp) ;
  480.     if ((len == 1) && (tmp[0] == '\n'))
  481.     {
  482.         return(FALSE) ;
  483.     }
  484.     /* remove the whitespace */
  485.     inctr = 0 ;
  486.     outctr = 0 ;
  487.     white = FALSE ;
  488.     len = strlen(tmp) ;
  489.     while (inctr < len) 
  490.     {
  491.         /* if the char is space AND white is true just move along */
  492.         if ((white == TRUE) && isspace(tmp[inctr]))
  493.         {
  494.             inctr ++ ;    
  495.             continue ;
  496.         }
  497.         /* if the char is space replace it with ' ' and move along 
  498.            setting white to eat up further white space */
  499.         if (isspace(tmp[inctr]))
  500.         {
  501.             /* if we are at the start of a line just move along */
  502.             if (outctr == 0)
  503.             {
  504.                 white = TRUE ;
  505.                 inctr ++ ;
  506.             }
  507.             else
  508.             {
  509.                 inpline[outctr] = ' ' ;
  510.                 outctr ++ ;
  511.                 inctr ++ ;
  512.                 white = TRUE ;
  513.             }
  514.             continue ;
  515.         }
  516.         /* we are not dealing with white space, copy over and unset white */
  517.         inpline[outctr] = tmp[inctr] ;
  518.         inctr ++ ;
  519.         outctr ++ ;
  520.         white = FALSE ;
  521.     }
  522.     /* terminate inpline */
  523.     inpline[outctr] = '\0' ;
  524.     /* if there is a space at the end of the line remove it */
  525.     len = strlen(inpline) ;
  526.     if (isspace(inpline[len -1]))
  527.         inpline[len-1] = '\0' ;
  528.     /* if there is a : in the line return COLON otherwise return NOCOLON */
  529.     if (strchr(inpline, ':') == NULL)
  530.         return(NOCOLON) ;
  531.     else
  532.         return(COLON) ;
  533. }
  534. E 1
  535.