home *** CD-ROM | disk | FTP | other *** search
/ PDA Software Library / pdasoftwarelib.iso / PSION / COMMS / PSIONMAI / PMFULLSO / SUNMAIL / EXTRACTH.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-13  |  9.9 KB  |  387 lines

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