/* * NAME: mkcatdefs * * FUNCTION: Make message catalog definitions. * * EXECUTION ENVIRONMENT: * User mode. * * RETURNS: None */ static void mkcatdefs(char *fname) /*---- fname: message descriptor file name ----*/ { char msgname [PATH_MAX]; char line [MAXLINELEN]; register char *cp; register char *cpt; register int m; register int n; int contin = 0; int len; /* # bytes in a character */ /* put out header for include file */ if (inclfile) { fprintf (outfp, "/* $%s$ */\n", "XConsortium"); fprintf (outfp, "\n\n/* The following was generated from %s. */\n\n", fname); } /* process the message file */ while (fgets(line, MAXLINELEN, descfile)) { /* find first nonblank character */ for (cp=line; *cp; cp+=len) { len = mblen(cp, MB_CUR_MAX); if (len < 0) { fprintf (stderr, "mkcatdefs: sourcefile contains invalid character:\n\t%s", line); errflg = 1; return; } if (len == 1 && isspace(*cp) == 0) break; } if (*cp == KEY_START) { cp++; for (cpt = cp; *cp; cp += len) { len = mblen(cp, MB_CUR_MAX); if (len < 0) { fprintf (stderr, "mkcatdefs: sourcefile contains invalid character:\n\t%s", line); errflg = 1; return; } if (len == 1 && isspace(*cp) == 0) break; } if (cp != cpt) { sscanf (cp, "%s", msgname); if ((m = nsearch(msgname)) > 0) { fprintf (msgfp, "$ %d", m); cp += strlen(msgname); fprintf (msgfp, "%s", cp); } else fputs (line, msgfp); continue; /* line is a comment */ } if ((strncmp (cp, "set", 3) == 0) && ((len = mblen(&(cp[3]), MB_CUR_MAX)) == 1) && (isspace(cp[3]) != 0)) { char setname [MAXIDLEN]; sscanf (cp+3+len, "%s", setname); if (inclfile) fprintf (outfp, "\n/* definitions for set %s */\n", setname, ""); if (isdigit(setname[0])) { cpt = setname; do { if (!isdigit(*cpt)) { fprintf(stderr, "mkcatdefs: %s is an invalid identifier\n", setname); errflg = 1; return; } } while (*++cpt); n = atoi (setname); if (n >= setno) setno = n; else { if (n == 0) fprintf(stderr, "mkcatdefs: %s is an invalid identifier\n", setname); else fprintf(stderr, "mkcatdefs: set # %d already assigned or sets not in ascending sequence\n", n); errflg = 1; return; } } else { cpt = setname; do { len = mblen(cpt, MB_CUR_MAX); if (len <= 0) { fprintf (stderr, "mkcatdefs: sourcefile contains invalid character:\n\t%s", line); errflg = 1; return; } if (len == 1 && (isalnum(*cpt) == 0) && (*cpt != '_')) { fprintf(stderr, "mkcatdefs: %s is an invalid identifier\n", setname); errflg = 1; return; } } while (*(cpt += len)); if (inclfile) fprintf (outfp, "#define %s %d\n\n", setname, (char *)setno); symbflg = 1; } #ifdef aix fprintf (msgfp,"$delset"); fprintf (msgfp," %d\n", setno); #endif fprintf (msgfp,"%.4s", line); fprintf (msgfp," %d\n", setno++); msgno = 1; continue; } else { /* !!!other command */ } } else if (contin) { if (!chkcontin(line)) contin = 0; } else if (setno > 1) { /* set must have been seen first */ char msgname [MAXIDLEN]; msgname [0] = '\0'; if (sscanf (cp, "%s", msgname) && msgname[0]) { len = mblen(cp, MB_CUR_MAX); if (len < 0) { fprintf (stderr, "mkcatdefs: sourcefile contains invalid character:\n\t%s", line); errflg = 1; return; } if (len == 1 && isalpha(*cp) != 0) { cpt = msgname; do { len = mblen(cpt, MB_CUR_MAX); if (len < 0) { fprintf (stderr, "mkcatdefs: sourcefile contains invalid character:\n\t%s", line); errflg = 1; return; } if (len == 1 && (isalnum(*cpt) == 0) && (*cpt != '_')) { fprintf(stderr, "mkcatdefs: %s is an invalid identifier\n", msgname); errflg = 1; return; } } while (*(cpt += len)); cp += strlen(msgname); fprintf (msgfp,"%d%s", msgno,cp); if (inclfile) fprintf (outfp, "#define %s %d\n", msgname, (char *)msgno); symbflg = 1; if (chkcontin(line)) contin = 1; if(insert(msgname,msgno++) < 0) { fprintf(stderr, "mkcatdefs: name %s used more than once\n", msgname); errflg = 1; return; } continue; } else if (isdigit (msgname[0])){ cpt = msgname; do { if (!isdigit(*cpt)) { fprintf(stderr, "mkcatdefs: invalid syntax in %s\n", line); errflg = 1; return; } } while (*++cpt); n = atoi (msgname); if ((n >= msgno) || (n == 0 && msgno == 1)) msgno = n + 1; else { errflg = 1; if (n == 0) fprintf(stderr, "mkcatdefs: %s is an invalid identifier\n", msgno); else if (n == msgno) fprintf(stderr, "mkcatdefs: message id %s already assigned to identifier\n", msgname); else fprintf(stderr, "mkcatdefs: source messages not in ascending sequence\n"); return; } } } if (chkcontin(line)) contin = 1; } fputs (line, msgfp); } /* make sure the operations read/write operations were successful */ if (ferror(descfile)) { fprintf (stderr, "mkcatdefs: There were read errors on file %s\n", inname); errflg = 1; } return; }
/* * readheaders -- * read mail headers */ void readheaders(void) { char buf[MAXLINE], *p; int tome, cont; ALIAS *cur; cont = tome = 0; while (fgets(buf, sizeof(buf), stdin) && *buf != '\n') switch (*buf) { case 'A': /* "Auto-Submitted:" */ case 'a': cont = 0; if (strncasecmp(buf, "Auto-Submitted:", 15)) break; for (p = buf + 15; isspace((unsigned char)*p); ++p) ; /* * RFC 3834 section 2: * Automatic responses SHOULD NOT be issued in response * to any message which contains an Auto-Submitted * header where the field has any value other than "no". */ if ((p[0] == 'n' || p[0] == 'N') && (p[1] == 'o' || p[1] == 'O')) { for (p += 2; isspace((unsigned char)*p); ++p) ; if (*p == '\0') break; /* Auto-Submitted: no */ } exit(0); case 'F': /* "From " */ case 'f': cont = 0; if (!strncasecmp(buf, "From ", 5)) { for (p = buf + 5; *p && *p != ' '; ++p) ; *p = '\0'; (void)strlcpy(from, buf + 5, sizeof(from)); from[strcspn(from, "\n")] = '\0'; if (junkmail()) exit(0); } break; case 'L': /* "List-Id:" */ case 'l': cont = 0; /* * If present (with any value), message is coming from a * mailing list, cf. RFC2919. */ if (strncasecmp(buf, "List-Id:", 8) == 0) exit(0); break; case 'R': /* "Return-Path:" */ case 'r': cont = 0; if (strncasecmp(buf, "Return-Path:", sizeof("Return-Path:")-1) || (buf[12] != ' ' && buf[12] != '\t')) break; for (p = buf + 12; isspace((unsigned char)*p); ++p) ; if (strlcpy(from, p, sizeof(from)) >= sizeof(from)) { syslog(LOG_NOTICE, "Return-Path %s exceeds limits", p); exit(1); } from[strcspn(from, "\n")] = '\0'; if (junkmail()) exit(0); break; case 'P': /* "Precedence:" */ case 'p': cont = 0; if (strncasecmp(buf, "Precedence:", 11)) break; for (p = buf + 11; isspace((unsigned char)*p); ++p) ; if (!strncasecmp(p, "junk", 4) || !strncasecmp(p, "bulk", 4) || !strncasecmp(p, "list", 4)) exit(0); break; case 'S': /* Subject: */ case 's': cont = 0; if (strncasecmp(buf, "Subject:", sizeof("Subject:")-1) || (buf[8] != ' ' && buf[8] != '\t')) break; for (p = buf + 8; isspace((unsigned char)*p); ++p) ; if (strlcpy(subj, p, sizeof(subj)) >= sizeof(subj)) { syslog(LOG_NOTICE, "Subject %s exceeds limits", p); exit(1); } subj[strcspn(subj, "\n")] = '\0'; break; case 'C': /* "Cc:" */ case 'c': if (strncasecmp(buf, "Cc:", 3)) break; cont = 1; goto findme; case 'T': /* "To:" */ case 't': if (strncasecmp(buf, "To:", 3)) break; cont = 1; goto findme; default: if (!isspace((unsigned char)*buf) || !cont || tome) { cont = 0; break; } findme: for (cur = names; !tome && cur; cur = cur->next) tome += nsearch(cur->name, buf); } if (!tome) exit(0); if (!*from) { syslog(LOG_NOTICE, "no initial \"From\" or \"Return-Path\"line."); exit(1); } }