#include #include #include #include #include #include #include "misc.h" #include "mailhead.h" PUBLIC MAILADR::MAILADR() { adr[0] = '\0'; name[0] = '\0'; } PUBLIC MAILHEADER::MAILHEADER() { nbreceived = 0; reply[0] = '\0'; subject[0] = '\0'; msgid[0] = '\0'; replyid[0] = '\0'; date[0] = '\0'; priority[0] = '\0'; } void mail2fax_stripcopy ( char dst[MAXHLINE+1], char *src) { strip_end (src); src = str_skip (src); if (src[0] == '"'){ src = str_skip (src+1); int last = strlen(src) -1; if (last >= 0 && src[last] == '"') src[last] = '\0'; strip_end (src); } strncpy (dst,src,MAXHLINE); dst[MAXHLINE] = '\0'; } static void mail2fax_copy2adr( char *accum, char *split, char endsplit, char first[MAXHLINE+1], char second[MAXHLINE+1]) { *split++ = '\0'; mail2fax_stripcopy (first,accum); accum = split; split = strchr(accum,endsplit); if (split != NULL) *split = '\0'; mail2fax_stripcopy (second,accum); } /* Parse a user address + name */ static void mail2fax_parsename ( MAILADR &adr, char *accum) { /* We have either "user name " or "email (user name) or simply email */ char *split = strchr(accum,'<'); if (split != NULL){ mail2fax_copy2adr (accum,split,'>',adr.name,adr.adr); }else{ split = strchr (accum,'('); if (split != NULL){ mail2fax_copy2adr (accum,split,')',adr.adr,adr.name); }else{ mail2fax_stripcopy (adr.adr,accum); adr.name[0] = '\0'; } } } /* Parse one line of the header */ static void mail2fax_parsehead ( char *accum, // One line MAILHEADER &head, int *ret) // Put any error in that { // syslog (LOG_ERR,"Parse %d %s",*ret,accum); if (strncasecmp(accum,"From: ",6)==0){ mail2fax_parsename (head.from,accum+6); *ret = 0; }else if (strncasecmp(accum,"To: ",4)==0){ mail2fax_parsename (head.to,accum+4); }else if (strncmp(accum,"Received: ",10)==0){ head.nbreceived++; }else if (strncasecmp(accum,"Reply-to: ",10)==0){ MAILADR tmp; mail2fax_parsename (tmp,accum+10); strncpy (head.reply,tmp.adr,MAXHLINE); head.reply[MAXHLINE] = '\0'; }else if (strncasecmp(accum,"Message-ID: ",12)==0){ strncpy (head.msgid,accum+12,MAXHLINE); head.msgid[MAXHLINE] = '\0'; }else if (strncasecmp(accum,"In-Reply-to: ",13)==0){ MAILADR tmp; mail2fax_parsename (tmp,accum+13); strncpy (head.replyid,tmp.adr,MAXHLINE); head.replyid[MAXHLINE] = '\0'; }else if (strncasecmp(accum,"Date: ",6)==0){ strncpy (head.date,accum+6,MAXHLINE); head.date[MAXHLINE] = '\0'; }else if (strncasecmp(accum,"Precedence: ",12)==0){ strncpy (head.priority,accum+12,MAXHLINE); head.priority[MAXHLINE] = '\0'; }else if (strncasecmp(accum,"Subject: ",9)==0){ strncpy (head.subject,accum+9,MAXHLINE); head.subject[MAXHLINE] = '\0'; } } unsigned long mailhead_getdate (MAILHEADER &head) { unsigned long ret = 0; char tmp[6][MAXHLINE]; if (sscanf (head.date,"%s %s %s %s %s %s" ,tmp[0],tmp[1],tmp[2],tmp[3],tmp[4],tmp[5])==6){ static const char *tbmonth[]={ "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep", "Oct","Nov","Dec" }; int i; struct tm t; t.tm_mday = atoi(tmp[1]); t.tm_year = atoi(tmp[3])-1900; t.tm_hour = atoi(tmp[4]); t.tm_min = atoi(tmp[4]+3); t.tm_sec = atoi(tmp[4]+6); t.tm_isdst = -1; for (i=0; i<12; i++){ if (strcmp(tmp[2],tbmonth[i])==0){ t.tm_mon = i; ret = mktime (&t); break; } } } return ret; } /* Read the beginning of the mail and extract various useful field from the header. Stop at the first empty line (end of the header) */ int mail2fax_getheader ( FILE *fin, MAILHEADER &head, char *collect, // Will contain the header if not NULL int size) // size of the collect buffer { int ret = -1; char buf[500]; char accum[2000]; accum[0] = '\0'; head.nbreceived = 0; head.from.adr[0] = head.from.name[0] = '\0'; head.to.adr[0] = head.to.name[0] = '\0'; head.reply[0] = head.subject[0] = '\0'; head.date[0] = head.replyid[0] = head.msgid[0] = '\0'; char *ptcol = collect; size -= sizeof(buf); // Avoid overflow without thinking much int lenaccum = 0; while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ if (ptcol != NULL && (ptcol - collect) < size){ // ptcol = stpcpy (ptcol,buf); ptcol = strcpy (ptcol,buf) + strlen(buf); } strip_end (buf); if (buf[0] == '\0'){ break; }else if (isspace(buf[0])){ int len = strlen(buf); if (len + lenaccum < (int)sizeof(accum)-1){ strcat (accum,buf); lenaccum += len; } // We ignore header line larger than accum }else{ if (accum[0] != '\0'){ mail2fax_parsehead (accum,head,&ret); } strcpy (accum,buf); lenaccum = strlen(accum); } } if (accum[0] != '\0'){ mail2fax_parsehead (accum,head,&ret); } return ret; } int mail2fax_getheader (FILE *fin, MAILHEADER &head) { return mail2fax_getheader (fin,head,NULL,0); } int mail2fax_getheader (MAILHEADER &head) { return mail2fax_getheader (stdin,head); }