17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5eb2b0a61Sas145665 * Common Development and Distribution License (the "License"). 6eb2b0a61Sas145665 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate 227c478bd9Sstevel@tonic-gate /* 23*2f72c445SViswanathan Kannappan * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 276c83d09fSrobbin /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 286c83d09fSrobbin /* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate /* 317c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 327c478bd9Sstevel@tonic-gate * The Regents of the University of California 337c478bd9Sstevel@tonic-gate * All Rights Reserved 347c478bd9Sstevel@tonic-gate * 357c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 367c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 377c478bd9Sstevel@tonic-gate * contributors. 387c478bd9Sstevel@tonic-gate */ 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate #include "rcv.h" 417c478bd9Sstevel@tonic-gate #include <locale.h> 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate /* 447c478bd9Sstevel@tonic-gate * mailx -- a modified version of a University of California at Berkeley 457c478bd9Sstevel@tonic-gate * mail program 467c478bd9Sstevel@tonic-gate * 477c478bd9Sstevel@tonic-gate * More user commands. 487c478bd9Sstevel@tonic-gate */ 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate static int igshow(void); 517c478bd9Sstevel@tonic-gate static int igcomp(const void *l, const void *r); 527c478bd9Sstevel@tonic-gate static int save1(char str[], int mark); 537c478bd9Sstevel@tonic-gate static int Save1(int *msgvec, int mark); 547c478bd9Sstevel@tonic-gate static void savemsglist(char *file, int *msgvec, int flag); 557c478bd9Sstevel@tonic-gate static int put1(char str[], int doign); 567c478bd9Sstevel@tonic-gate static int svputs(const char *line, FILE *obuf); 577c478bd9Sstevel@tonic-gate static int wrputs(const char *line, FILE *obuf); 587c478bd9Sstevel@tonic-gate static int retshow(void); 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate /* flags for savemsglist() */ 617c478bd9Sstevel@tonic-gate #define S_MARK 1 /* mark the message as saved */ 627c478bd9Sstevel@tonic-gate #define S_NOHEADER 2 /* don't write out the header */ 637c478bd9Sstevel@tonic-gate #define S_SAVING 4 /* doing save/copy */ 647c478bd9Sstevel@tonic-gate #define S_NOIGNORE 8 /* don't do ignore processing */ 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate /* 67eb2b0a61Sas145665 * If any arguments were given, print the first message 68eb2b0a61Sas145665 * identified by the first argument. If no arguments are given, 69eb2b0a61Sas145665 * print the next applicable message after dot. 707c478bd9Sstevel@tonic-gate */ 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate int 737c478bd9Sstevel@tonic-gate next(int *msgvec) 747c478bd9Sstevel@tonic-gate { 757c478bd9Sstevel@tonic-gate register struct message *mp; 76eb2b0a61Sas145665 int list[2]; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate if (*msgvec != NULL) { 79eb2b0a61Sas145665 if (*msgvec < 0) { 80eb2b0a61Sas145665 printf((gettext("Negative message given\n"))); 81eb2b0a61Sas145665 return (1); 82eb2b0a61Sas145665 } 83eb2b0a61Sas145665 mp = &message[*msgvec - 1]; 847c478bd9Sstevel@tonic-gate if ((mp->m_flag & MDELETED) == 0) { 857c478bd9Sstevel@tonic-gate dot = mp; 867c478bd9Sstevel@tonic-gate goto hitit; 877c478bd9Sstevel@tonic-gate } 88eb2b0a61Sas145665 printf(gettext("No applicable message\n")); 897c478bd9Sstevel@tonic-gate return (1); 907c478bd9Sstevel@tonic-gate } 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate /* 937c478bd9Sstevel@tonic-gate * If this is the first command, select message 1. 947c478bd9Sstevel@tonic-gate * Note that this must exist for us to get here at all. 957c478bd9Sstevel@tonic-gate */ 967c478bd9Sstevel@tonic-gate if (!sawcom) 977c478bd9Sstevel@tonic-gate goto hitit; 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate /* 1007c478bd9Sstevel@tonic-gate * Just find the next good message after dot, no 1017c478bd9Sstevel@tonic-gate * wraparound. 1027c478bd9Sstevel@tonic-gate */ 1037c478bd9Sstevel@tonic-gate for (mp = dot+1; mp < &message[msgCount]; mp++) 1047c478bd9Sstevel@tonic-gate if ((mp->m_flag & (MDELETED|MSAVED)) == 0) 1057c478bd9Sstevel@tonic-gate break; 1067c478bd9Sstevel@tonic-gate if (mp >= &message[msgCount]) { 1077c478bd9Sstevel@tonic-gate printf(gettext("At EOF\n")); 1087c478bd9Sstevel@tonic-gate return (0); 1097c478bd9Sstevel@tonic-gate } 1107c478bd9Sstevel@tonic-gate dot = mp; 1117c478bd9Sstevel@tonic-gate hitit: 1127c478bd9Sstevel@tonic-gate /* 1137c478bd9Sstevel@tonic-gate * Print dot. 1147c478bd9Sstevel@tonic-gate */ 1157c478bd9Sstevel@tonic-gate list[0] = dot - &message[0] + 1; 1167c478bd9Sstevel@tonic-gate list[1] = NULL; 1177c478bd9Sstevel@tonic-gate return (type(list)); 1187c478bd9Sstevel@tonic-gate } 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate /* 1217c478bd9Sstevel@tonic-gate * Save a message in a file. Mark the message as saved 1227c478bd9Sstevel@tonic-gate * so we can discard when the user quits. 1237c478bd9Sstevel@tonic-gate */ 1247c478bd9Sstevel@tonic-gate int 1257c478bd9Sstevel@tonic-gate save(char str[]) 1267c478bd9Sstevel@tonic-gate { 1277c478bd9Sstevel@tonic-gate return (save1(str, S_MARK)); 1287c478bd9Sstevel@tonic-gate } 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate /* 1317c478bd9Sstevel@tonic-gate * Copy a message to a file without affected its saved-ness 1327c478bd9Sstevel@tonic-gate */ 1337c478bd9Sstevel@tonic-gate int 1347c478bd9Sstevel@tonic-gate copycmd(char str[]) 1357c478bd9Sstevel@tonic-gate { 1367c478bd9Sstevel@tonic-gate return (save1(str, 0)); 1377c478bd9Sstevel@tonic-gate } 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate /* 1407c478bd9Sstevel@tonic-gate * Save/copy the indicated messages at the end of the passed file name. 1417c478bd9Sstevel@tonic-gate * If mark is true, mark the message "saved." 1427c478bd9Sstevel@tonic-gate */ 1437c478bd9Sstevel@tonic-gate static int 1447c478bd9Sstevel@tonic-gate save1(char str[], int mark) 1457c478bd9Sstevel@tonic-gate { 1467c478bd9Sstevel@tonic-gate char *file, *cmd; 1477c478bd9Sstevel@tonic-gate int f, *msgvec; 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate cmd = mark ? "save" : "copy"; 150eb2b0a61Sas145665 msgvec = (int *)salloc((msgCount + 2) * sizeof (*msgvec)); 1517c478bd9Sstevel@tonic-gate if ((file = snarf(str, &f, 0)) == NOSTR) 1527c478bd9Sstevel@tonic-gate file = Getf("MBOX"); 1537c478bd9Sstevel@tonic-gate if (f == -1) 1547c478bd9Sstevel@tonic-gate return (1); 1557c478bd9Sstevel@tonic-gate if (!f) { 1567c478bd9Sstevel@tonic-gate *msgvec = first(0, MMNORM); 1577c478bd9Sstevel@tonic-gate if (*msgvec == NULL) { 1587c478bd9Sstevel@tonic-gate printf(gettext("No messages to %s.\n"), cmd); 1597c478bd9Sstevel@tonic-gate return (1); 1607c478bd9Sstevel@tonic-gate } 1617c478bd9Sstevel@tonic-gate msgvec[1] = NULL; 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate if (f && getmsglist(str, msgvec, 0) < 0) 1647c478bd9Sstevel@tonic-gate return (1); 1657c478bd9Sstevel@tonic-gate if ((file = expand(file)) == NOSTR) 1667c478bd9Sstevel@tonic-gate return (1); 1677c478bd9Sstevel@tonic-gate savemsglist(file, msgvec, mark | S_SAVING); 1687c478bd9Sstevel@tonic-gate return (0); 1697c478bd9Sstevel@tonic-gate } 1707c478bd9Sstevel@tonic-gate 1717c478bd9Sstevel@tonic-gate int 1727c478bd9Sstevel@tonic-gate Save(int *msgvec) 1737c478bd9Sstevel@tonic-gate { 1747c478bd9Sstevel@tonic-gate return (Save1(msgvec, S_MARK)); 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate int 1787c478bd9Sstevel@tonic-gate Copy(int *msgvec) 1797c478bd9Sstevel@tonic-gate { 1807c478bd9Sstevel@tonic-gate return (Save1(msgvec, 0)); 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate /* 1847c478bd9Sstevel@tonic-gate * save/copy the indicated messages at the end of a file named 1857c478bd9Sstevel@tonic-gate * by the sender of the first message in the msglist. 1867c478bd9Sstevel@tonic-gate */ 1877c478bd9Sstevel@tonic-gate static int 1887c478bd9Sstevel@tonic-gate Save1(int *msgvec, int mark) 1897c478bd9Sstevel@tonic-gate { 1907c478bd9Sstevel@tonic-gate register char *from; 1917c478bd9Sstevel@tonic-gate char recfile[BUFSIZ]; 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate #ifdef notdef 1947c478bd9Sstevel@tonic-gate from = striphosts(nameof(&message[*msgvec-1], 0)); 1957c478bd9Sstevel@tonic-gate #else 1967c478bd9Sstevel@tonic-gate from = nameof(&message[*msgvec-1]); 1977c478bd9Sstevel@tonic-gate #endif 1987c478bd9Sstevel@tonic-gate getrecf(from, recfile, 1, sizeof (recfile)); 1997c478bd9Sstevel@tonic-gate if (*recfile != '\0') 2007c478bd9Sstevel@tonic-gate savemsglist(safeexpand(recfile), msgvec, mark | S_SAVING); 2017c478bd9Sstevel@tonic-gate return (0); 2027c478bd9Sstevel@tonic-gate } 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate int 2057c478bd9Sstevel@tonic-gate sput(char str[]) 2067c478bd9Sstevel@tonic-gate { 2077c478bd9Sstevel@tonic-gate return (put1(str, 0)); 2087c478bd9Sstevel@tonic-gate } 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate int 2117c478bd9Sstevel@tonic-gate Sput(char str[]) 2127c478bd9Sstevel@tonic-gate { 2137c478bd9Sstevel@tonic-gate return (put1(str, S_NOIGNORE)); 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate /* 2177c478bd9Sstevel@tonic-gate * Put the indicated messages at the end of the passed file name. 2187c478bd9Sstevel@tonic-gate */ 2197c478bd9Sstevel@tonic-gate static int 2207c478bd9Sstevel@tonic-gate put1(char str[], int doign) 2217c478bd9Sstevel@tonic-gate { 2227c478bd9Sstevel@tonic-gate char *file; 2237c478bd9Sstevel@tonic-gate int f, *msgvec; 2247c478bd9Sstevel@tonic-gate 225eb2b0a61Sas145665 msgvec = (int *)salloc((msgCount + 2) * sizeof (*msgvec)); 2267c478bd9Sstevel@tonic-gate if ((file = snarf(str, &f, 0)) == NOSTR) 2277c478bd9Sstevel@tonic-gate file = Getf("MBOX"); 2287c478bd9Sstevel@tonic-gate if (f == -1) 2297c478bd9Sstevel@tonic-gate return (1); 2307c478bd9Sstevel@tonic-gate if (!f) { 2317c478bd9Sstevel@tonic-gate *msgvec = first(0, MMNORM); 2327c478bd9Sstevel@tonic-gate if (*msgvec == NULL) { 2337c478bd9Sstevel@tonic-gate printf(gettext("No messages to put.\n")); 2347c478bd9Sstevel@tonic-gate return (1); 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate msgvec[1] = NULL; 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate if (f && getmsglist(str, msgvec, 0) < 0) 2397c478bd9Sstevel@tonic-gate return (1); 2407c478bd9Sstevel@tonic-gate if ((file = expand(file)) == NOSTR) 2417c478bd9Sstevel@tonic-gate return (1); 2427c478bd9Sstevel@tonic-gate savemsglist(file, msgvec, doign); 2437c478bd9Sstevel@tonic-gate return (0); 2447c478bd9Sstevel@tonic-gate } 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate /* 2477c478bd9Sstevel@tonic-gate * save a message list in a file. 2487c478bd9Sstevel@tonic-gate * if wr set, doing "write" instead 2497c478bd9Sstevel@tonic-gate * of "save" or "copy" so don't put 2507c478bd9Sstevel@tonic-gate * out header. 2517c478bd9Sstevel@tonic-gate */ 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate static int wr_linecount; /* count of lines written */ 2547c478bd9Sstevel@tonic-gate static int wr_charcount; /* char count of lines written */ 2557c478bd9Sstevel@tonic-gate static int wr_inlines; /* count of lines read */ 2567c478bd9Sstevel@tonic-gate static long wr_maxlines; /* total lines in message */ 2577c478bd9Sstevel@tonic-gate static int wr_inhead; /* in header of message */ 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate static void 2607c478bd9Sstevel@tonic-gate savemsglist(char *file, int *msgvec, int flag) 2617c478bd9Sstevel@tonic-gate { 2627c478bd9Sstevel@tonic-gate register int *ip, mesg; 2637c478bd9Sstevel@tonic-gate register struct message *mp; 2647c478bd9Sstevel@tonic-gate char *disp; 2657c478bd9Sstevel@tonic-gate FILE *obuf; 2667c478bd9Sstevel@tonic-gate struct stat statb; 2677c478bd9Sstevel@tonic-gate long lc, cc, t; 2687c478bd9Sstevel@tonic-gate int bnry, mflag; 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate printf("\"%s\" ", file); 2717c478bd9Sstevel@tonic-gate flush(); 2727c478bd9Sstevel@tonic-gate if (stat(file, &statb) >= 0) 2737c478bd9Sstevel@tonic-gate disp = "[Appended]"; 2747c478bd9Sstevel@tonic-gate else 2757c478bd9Sstevel@tonic-gate disp = "[New file]"; 2767c478bd9Sstevel@tonic-gate if ((obuf = fopen(file, "a")) == NULL) { 2777c478bd9Sstevel@tonic-gate perror(""); 2787c478bd9Sstevel@tonic-gate return; 2797c478bd9Sstevel@tonic-gate } 2807c478bd9Sstevel@tonic-gate lc = cc = 0; 2817c478bd9Sstevel@tonic-gate bnry = 0; 2827c478bd9Sstevel@tonic-gate if (flag & S_SAVING) 2837c478bd9Sstevel@tonic-gate mflag = (int)value("alwaysignore")?(M_IGNORE|M_SAVING):M_SAVING; 2847c478bd9Sstevel@tonic-gate else if (flag & S_NOIGNORE) 2857c478bd9Sstevel@tonic-gate mflag = 0; 2867c478bd9Sstevel@tonic-gate else 2877c478bd9Sstevel@tonic-gate mflag = M_IGNORE; 2887c478bd9Sstevel@tonic-gate for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { 2897c478bd9Sstevel@tonic-gate mesg = *ip; 2907c478bd9Sstevel@tonic-gate mp = &message[mesg-1]; 2917c478bd9Sstevel@tonic-gate if (!mp->m_text) { 2927c478bd9Sstevel@tonic-gate bnry = 1; 2937c478bd9Sstevel@tonic-gate } 2947c478bd9Sstevel@tonic-gate wr_linecount = 0; 2957c478bd9Sstevel@tonic-gate wr_charcount = 0; 2967c478bd9Sstevel@tonic-gate if (flag & S_NOHEADER) { 2977c478bd9Sstevel@tonic-gate wr_inhead = 1; 2987c478bd9Sstevel@tonic-gate wr_maxlines = mp->m_lines; 2997c478bd9Sstevel@tonic-gate wr_inlines = 0; 3007c478bd9Sstevel@tonic-gate t = msend(mp, obuf, 0, wrputs); 3017c478bd9Sstevel@tonic-gate } else { 3027c478bd9Sstevel@tonic-gate t = msend(mp, obuf, mflag, svputs); 3037c478bd9Sstevel@tonic-gate } 3047c478bd9Sstevel@tonic-gate if (t < 0) { 3057c478bd9Sstevel@tonic-gate perror(file); 3067c478bd9Sstevel@tonic-gate fclose(obuf); 3077c478bd9Sstevel@tonic-gate return; 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate touch(mesg); 3107c478bd9Sstevel@tonic-gate dot = mp; 3117c478bd9Sstevel@tonic-gate lc += wr_linecount; 3127c478bd9Sstevel@tonic-gate cc += wr_charcount; 3137c478bd9Sstevel@tonic-gate if (flag & S_MARK) 3147c478bd9Sstevel@tonic-gate mp->m_flag |= MSAVED; 3157c478bd9Sstevel@tonic-gate } 3167c478bd9Sstevel@tonic-gate fflush(obuf); 3177c478bd9Sstevel@tonic-gate if (fferror(obuf)) 3187c478bd9Sstevel@tonic-gate perror(file); 3197c478bd9Sstevel@tonic-gate fclose(obuf); 3207c478bd9Sstevel@tonic-gate if (!bnry) { 3217c478bd9Sstevel@tonic-gate printf("%s %ld/%ld\n", disp, lc, cc); 3227c478bd9Sstevel@tonic-gate } else { 3237c478bd9Sstevel@tonic-gate printf("%s binary/%ld\n", disp, cc); 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate } 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate static int 3287c478bd9Sstevel@tonic-gate svputs(const char *line, FILE *obuf) 3297c478bd9Sstevel@tonic-gate { 3307c478bd9Sstevel@tonic-gate wr_linecount++; 3317c478bd9Sstevel@tonic-gate wr_charcount += strlen(line); 3327c478bd9Sstevel@tonic-gate return (fputs(line, obuf)); 3337c478bd9Sstevel@tonic-gate } 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate static int 3367c478bd9Sstevel@tonic-gate wrputs(const char *line, FILE *obuf) 3377c478bd9Sstevel@tonic-gate { 3387c478bd9Sstevel@tonic-gate /* 3397c478bd9Sstevel@tonic-gate * If this is a header line or 3407c478bd9Sstevel@tonic-gate * the last line, don't write it out. Since we may add a 3417c478bd9Sstevel@tonic-gate * "Status" line the line count may be off by one so insist 3427c478bd9Sstevel@tonic-gate * that the last line is blank before we skip it. 3437c478bd9Sstevel@tonic-gate */ 3447c478bd9Sstevel@tonic-gate wr_inlines++; 3457c478bd9Sstevel@tonic-gate if (wr_inhead) { 3467c478bd9Sstevel@tonic-gate if (strcmp(line, "\n") == 0) 3477c478bd9Sstevel@tonic-gate wr_inhead = 0; 3487c478bd9Sstevel@tonic-gate return (0); 3497c478bd9Sstevel@tonic-gate } 3507c478bd9Sstevel@tonic-gate if (wr_inlines >= wr_maxlines && strcmp(line, "\n") == 0) 3517c478bd9Sstevel@tonic-gate return (0); 3527c478bd9Sstevel@tonic-gate wr_linecount++; 3537c478bd9Sstevel@tonic-gate wr_charcount += strlen(line); 3547c478bd9Sstevel@tonic-gate return (fputs(line, obuf)); 3557c478bd9Sstevel@tonic-gate } 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate /* 3587c478bd9Sstevel@tonic-gate * Write the indicated messages at the end of the passed 3597c478bd9Sstevel@tonic-gate * file name, minus header and trailing blank line. 3607c478bd9Sstevel@tonic-gate */ 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate int 3637c478bd9Sstevel@tonic-gate swrite(char str[]) 3647c478bd9Sstevel@tonic-gate { 3657c478bd9Sstevel@tonic-gate register char *file; 3667c478bd9Sstevel@tonic-gate int f, *msgvec; 3677c478bd9Sstevel@tonic-gate 368eb2b0a61Sas145665 msgvec = (int *)salloc((msgCount + 2) * sizeof (*msgvec)); 3697c478bd9Sstevel@tonic-gate if ((file = snarf(str, &f, 1)) == NOSTR) 3707c478bd9Sstevel@tonic-gate return (1); 3717c478bd9Sstevel@tonic-gate if (f == -1) 3727c478bd9Sstevel@tonic-gate return (1); 3737c478bd9Sstevel@tonic-gate if ((file = expand(file)) == NOSTR) 3747c478bd9Sstevel@tonic-gate return (1); 3757c478bd9Sstevel@tonic-gate if (!f) { 3767c478bd9Sstevel@tonic-gate *msgvec = first(0, MMNORM); 3777c478bd9Sstevel@tonic-gate if (*msgvec == NULL) { 3787c478bd9Sstevel@tonic-gate printf(gettext("No messages to write.\n")); 3797c478bd9Sstevel@tonic-gate return (1); 3807c478bd9Sstevel@tonic-gate } 3817c478bd9Sstevel@tonic-gate msgvec[1] = NULL; 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate if (f && getmsglist(str, msgvec, 0) < 0) 3847c478bd9Sstevel@tonic-gate return (1); 3857c478bd9Sstevel@tonic-gate savemsglist(file, msgvec, S_MARK|S_NOHEADER); 3867c478bd9Sstevel@tonic-gate return (0); 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate /* 3907c478bd9Sstevel@tonic-gate * Snarf the file from the end of the command line and 3917c478bd9Sstevel@tonic-gate * return a pointer to it. If there is no file attached, 3927c478bd9Sstevel@tonic-gate * just return NOSTR. Put a null in front of the file 3937c478bd9Sstevel@tonic-gate * name so that the message list processing won't see it, 3947c478bd9Sstevel@tonic-gate * unless the file name is the only thing on the line, in 3957c478bd9Sstevel@tonic-gate * which case, return 0 in the reference flag variable. 3967c478bd9Sstevel@tonic-gate */ 3977c478bd9Sstevel@tonic-gate 3987c478bd9Sstevel@tonic-gate /* 3997c478bd9Sstevel@tonic-gate * The following definitions are used to characterize the syntactic 4007c478bd9Sstevel@tonic-gate * category of the preceding character in the following parse procedure. 4017c478bd9Sstevel@tonic-gate * The variable pc_type assumes these values. 4027c478bd9Sstevel@tonic-gate */ 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate #define SN_DELIM 1 /* Delimiter (<blank> or line beginning) */ 4057c478bd9Sstevel@tonic-gate #define SN_TOKEN 2 /* A part of a token */ 4067c478bd9Sstevel@tonic-gate #define SN_QUOTE 4 /* An entire quoted string (ie, "...") */ 4077c478bd9Sstevel@tonic-gate 4087c478bd9Sstevel@tonic-gate char * 4097c478bd9Sstevel@tonic-gate snarf(char linebuf[], int *flag, int erf) 4107c478bd9Sstevel@tonic-gate { 4117c478bd9Sstevel@tonic-gate register char *p; /* utility pointer */ 4127c478bd9Sstevel@tonic-gate register char qc; /* quotation character to match */ 4137c478bd9Sstevel@tonic-gate register unsigned int pc_type; /* preceding character type */ 4147c478bd9Sstevel@tonic-gate register char *tok_beg; /* beginning of last token */ 4157c478bd9Sstevel@tonic-gate register char *tok_end; /* end of last token */ 4167c478bd9Sstevel@tonic-gate char *line_beg; /* beginning of line, after */ 4177c478bd9Sstevel@tonic-gate /* leading whitespace */ 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate /* 4207c478bd9Sstevel@tonic-gate * Skip leading whitespace. 4217c478bd9Sstevel@tonic-gate */ 4227c478bd9Sstevel@tonic-gate for (line_beg = linebuf; 4237c478bd9Sstevel@tonic-gate *line_beg && any(*line_beg, " \t"); 4247c478bd9Sstevel@tonic-gate line_beg++) { 4257c478bd9Sstevel@tonic-gate /* empty body */ 4267c478bd9Sstevel@tonic-gate } 4277c478bd9Sstevel@tonic-gate if (!*line_beg) { 4287c478bd9Sstevel@tonic-gate if (erf) { 429*2f72c445SViswanathan Kannappan printf(gettext("No file specified.\n")); 4307c478bd9Sstevel@tonic-gate } 4317c478bd9Sstevel@tonic-gate *flag = 0; 4327c478bd9Sstevel@tonic-gate return (NOSTR); 4337c478bd9Sstevel@tonic-gate } 4347c478bd9Sstevel@tonic-gate /* 4357c478bd9Sstevel@tonic-gate * Process line from left-to-right, 1 char at a time. 4367c478bd9Sstevel@tonic-gate */ 437eb2b0a61Sas145665 pc_type = SN_DELIM; 438eb2b0a61Sas145665 tok_beg = tok_end = NOSTR; 439eb2b0a61Sas145665 p = line_beg; 440eb2b0a61Sas145665 while (*p != '\0') { 4417c478bd9Sstevel@tonic-gate if (any(*p, " \t")) { 4427c478bd9Sstevel@tonic-gate /* This character is a DELIMITER */ 4437c478bd9Sstevel@tonic-gate if (pc_type & (SN_TOKEN|SN_QUOTE)) { 4447c478bd9Sstevel@tonic-gate tok_end = p - 1; 4457c478bd9Sstevel@tonic-gate } 4467c478bd9Sstevel@tonic-gate pc_type = SN_DELIM; 4477c478bd9Sstevel@tonic-gate p++; 4487c478bd9Sstevel@tonic-gate } else if ((qc = *p) == '"' || qc == '\'') { 4497c478bd9Sstevel@tonic-gate /* This character is a QUOTE character */ 4507c478bd9Sstevel@tonic-gate if (pc_type == SN_TOKEN) { 4517c478bd9Sstevel@tonic-gate /* embedded quotation symbols are simply */ 4527c478bd9Sstevel@tonic-gate /* token characters. */ 4537c478bd9Sstevel@tonic-gate p++; 4547c478bd9Sstevel@tonic-gate continue; 4557c478bd9Sstevel@tonic-gate } 4567c478bd9Sstevel@tonic-gate /* Search for the matching QUOTE character */ 4577c478bd9Sstevel@tonic-gate for (tok_beg = p, tok_end = NOSTR, p++; 4587c478bd9Sstevel@tonic-gate *p != '\0' && *p != qc; 4597c478bd9Sstevel@tonic-gate p++) { 4607c478bd9Sstevel@tonic-gate if (*p == '\\' && *(p+1) == qc) { 4617c478bd9Sstevel@tonic-gate p++; 4627c478bd9Sstevel@tonic-gate } 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate if (*p == '\0') { 4657c478bd9Sstevel@tonic-gate printf(gettext("Syntax error: missing " 4667c478bd9Sstevel@tonic-gate "%c.\n"), qc); 4677c478bd9Sstevel@tonic-gate *flag = -1; 4687c478bd9Sstevel@tonic-gate return (NOSTR); 4697c478bd9Sstevel@tonic-gate } 4707c478bd9Sstevel@tonic-gate tok_end = p; 4717c478bd9Sstevel@tonic-gate pc_type = SN_QUOTE; 4727c478bd9Sstevel@tonic-gate p++; 4737c478bd9Sstevel@tonic-gate } else { 4747c478bd9Sstevel@tonic-gate /* This character should be a TOKEN character */ 4757c478bd9Sstevel@tonic-gate if (pc_type & (SN_DELIM|SN_TOKEN)) { 4767c478bd9Sstevel@tonic-gate if (pc_type & SN_DELIM) { 4777c478bd9Sstevel@tonic-gate tok_beg = p; 4787c478bd9Sstevel@tonic-gate tok_end = NOSTR; 4797c478bd9Sstevel@tonic-gate } 4807c478bd9Sstevel@tonic-gate } else { 4817c478bd9Sstevel@tonic-gate printf(gettext("improper quotes" 4827c478bd9Sstevel@tonic-gate " at \"%s\".\n"), p); 4837c478bd9Sstevel@tonic-gate *flag = -1; 4847c478bd9Sstevel@tonic-gate return (NOSTR); 4857c478bd9Sstevel@tonic-gate } 4867c478bd9Sstevel@tonic-gate if (*p == '\\' && *++p == '\0') { 4877c478bd9Sstevel@tonic-gate printf(gettext("\'\\\' at " 4887c478bd9Sstevel@tonic-gate "end of line.\n")); 4897c478bd9Sstevel@tonic-gate *flag = -1; 4907c478bd9Sstevel@tonic-gate return (NOSTR); 4917c478bd9Sstevel@tonic-gate } 4927c478bd9Sstevel@tonic-gate pc_type = SN_TOKEN; 4937c478bd9Sstevel@tonic-gate p++; 4947c478bd9Sstevel@tonic-gate } 4957c478bd9Sstevel@tonic-gate } 4967c478bd9Sstevel@tonic-gate if (pc_type == SN_TOKEN) { 4977c478bd9Sstevel@tonic-gate tok_end = p - 1; 4987c478bd9Sstevel@tonic-gate } 4997c478bd9Sstevel@tonic-gate if (tok_beg != NOSTR && tok_end != NOSTR) { 5007c478bd9Sstevel@tonic-gate if (tok_beg == line_beg) { 5017c478bd9Sstevel@tonic-gate *flag = 0; 5027c478bd9Sstevel@tonic-gate } else { 5037c478bd9Sstevel@tonic-gate tok_beg[-1] = '\0'; 5047c478bd9Sstevel@tonic-gate *flag = 1; 5057c478bd9Sstevel@tonic-gate } 5067c478bd9Sstevel@tonic-gate tok_end[1] = '\0'; 5077c478bd9Sstevel@tonic-gate return (tok_beg); 5087c478bd9Sstevel@tonic-gate } else { 5097c478bd9Sstevel@tonic-gate if (erf) { 510*2f72c445SViswanathan Kannappan printf(gettext("No file specified.\n")); 5117c478bd9Sstevel@tonic-gate } 5127c478bd9Sstevel@tonic-gate *flag = 0; 5137c478bd9Sstevel@tonic-gate return (NOSTR); 5147c478bd9Sstevel@tonic-gate } 5157c478bd9Sstevel@tonic-gate } 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate /* 5187c478bd9Sstevel@tonic-gate * Delete messages, then type the new dot. 5197c478bd9Sstevel@tonic-gate */ 5207c478bd9Sstevel@tonic-gate 5217c478bd9Sstevel@tonic-gate int 5227c478bd9Sstevel@tonic-gate deltype(int msgvec[]) 5237c478bd9Sstevel@tonic-gate { 5247c478bd9Sstevel@tonic-gate int list[2]; 5257c478bd9Sstevel@tonic-gate int lastdot; 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate lastdot = dot - &message[0] + 1; 5287c478bd9Sstevel@tonic-gate if (delm(msgvec) >= 0) { 5297c478bd9Sstevel@tonic-gate list[0] = dot - &message[0]; 5307c478bd9Sstevel@tonic-gate list[0]++; 5317c478bd9Sstevel@tonic-gate if (list[0] > lastdot) { 5327c478bd9Sstevel@tonic-gate touch(list[0]); 5337c478bd9Sstevel@tonic-gate list[1] = NULL; 5347c478bd9Sstevel@tonic-gate return (type(list)); 5357c478bd9Sstevel@tonic-gate } 5367c478bd9Sstevel@tonic-gate printf(gettext("At EOF\n")); 5377c478bd9Sstevel@tonic-gate return (0); 538eb2b0a61Sas145665 } else { 5397c478bd9Sstevel@tonic-gate printf(gettext("No more messages\n")); 5407c478bd9Sstevel@tonic-gate return (0); 5417c478bd9Sstevel@tonic-gate } 5427c478bd9Sstevel@tonic-gate } 5437c478bd9Sstevel@tonic-gate 5447c478bd9Sstevel@tonic-gate /* 5457c478bd9Sstevel@tonic-gate * Delete the indicated messages. 5467c478bd9Sstevel@tonic-gate * Set dot to some nice place afterwards. 5477c478bd9Sstevel@tonic-gate */ 5487c478bd9Sstevel@tonic-gate int 5497c478bd9Sstevel@tonic-gate delm(int *msgvec) 5507c478bd9Sstevel@tonic-gate { 5517c478bd9Sstevel@tonic-gate register struct message *mp; 5526c83d09fSrobbin int *ip, mesg; 5537c478bd9Sstevel@tonic-gate int last; 5547c478bd9Sstevel@tonic-gate 5557c478bd9Sstevel@tonic-gate last = NULL; 5567c478bd9Sstevel@tonic-gate for (ip = msgvec; *ip != NULL; ip++) { 5577c478bd9Sstevel@tonic-gate mesg = *ip; 5587c478bd9Sstevel@tonic-gate touch(mesg); 5597c478bd9Sstevel@tonic-gate mp = &message[mesg-1]; 5607c478bd9Sstevel@tonic-gate mp->m_flag |= MDELETED|MTOUCH; 5617c478bd9Sstevel@tonic-gate mp->m_flag &= ~(MPRESERVE|MSAVED|MBOX); 5627c478bd9Sstevel@tonic-gate last = mesg; 5637c478bd9Sstevel@tonic-gate } 5647c478bd9Sstevel@tonic-gate if (last != NULL) { 5657c478bd9Sstevel@tonic-gate dot = &message[last-1]; 5667c478bd9Sstevel@tonic-gate last = first(0, MDELETED); 5677c478bd9Sstevel@tonic-gate if (last != NULL) { 5687c478bd9Sstevel@tonic-gate dot = &message[last-1]; 5697c478bd9Sstevel@tonic-gate return (0); 570eb2b0a61Sas145665 } else { 5717c478bd9Sstevel@tonic-gate dot = &message[0]; 5727c478bd9Sstevel@tonic-gate return (-1); 5737c478bd9Sstevel@tonic-gate } 5747c478bd9Sstevel@tonic-gate } 5757c478bd9Sstevel@tonic-gate 5767c478bd9Sstevel@tonic-gate /* 5777c478bd9Sstevel@tonic-gate * Following can't happen -- it keeps lint happy 5787c478bd9Sstevel@tonic-gate */ 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate return (-1); 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate /* 5847c478bd9Sstevel@tonic-gate * Undelete the indicated messages. 5857c478bd9Sstevel@tonic-gate */ 5867c478bd9Sstevel@tonic-gate int 5877c478bd9Sstevel@tonic-gate undelete(int *msgvec) 5887c478bd9Sstevel@tonic-gate { 5897c478bd9Sstevel@tonic-gate register struct message *mp; 5906c83d09fSrobbin int *ip, mesg; 5917c478bd9Sstevel@tonic-gate 5927c478bd9Sstevel@tonic-gate for (ip = msgvec; ip-msgvec < msgCount; ip++) { 5937c478bd9Sstevel@tonic-gate mesg = *ip; 5947c478bd9Sstevel@tonic-gate if (mesg == 0) 5957c478bd9Sstevel@tonic-gate return (0); 5967c478bd9Sstevel@tonic-gate touch(mesg); 5977c478bd9Sstevel@tonic-gate mp = &message[mesg-1]; 5987c478bd9Sstevel@tonic-gate dot = mp; 5997c478bd9Sstevel@tonic-gate mp->m_flag &= ~MDELETED; 6007c478bd9Sstevel@tonic-gate } 6017c478bd9Sstevel@tonic-gate return (0); 6027c478bd9Sstevel@tonic-gate } 6037c478bd9Sstevel@tonic-gate 6047c478bd9Sstevel@tonic-gate /* 6057c478bd9Sstevel@tonic-gate * Add the given header fields to the retained list. 6067c478bd9Sstevel@tonic-gate * If no arguments, print the current list of retained fields. 6077c478bd9Sstevel@tonic-gate */ 6087c478bd9Sstevel@tonic-gate int 6097c478bd9Sstevel@tonic-gate retfield(char *list[]) 6107c478bd9Sstevel@tonic-gate { 6117c478bd9Sstevel@tonic-gate char field[BUFSIZ]; 6127c478bd9Sstevel@tonic-gate register int h; 6137c478bd9Sstevel@tonic-gate register struct ignore *igp; 6147c478bd9Sstevel@tonic-gate char **ap; 6157c478bd9Sstevel@tonic-gate 6167c478bd9Sstevel@tonic-gate if (argcount(list) == 0) 6177c478bd9Sstevel@tonic-gate return (retshow()); 6187c478bd9Sstevel@tonic-gate for (ap = list; *ap != 0; ap++) { 6197c478bd9Sstevel@tonic-gate istrcpy(field, sizeof (field), *ap); 6207c478bd9Sstevel@tonic-gate 6217c478bd9Sstevel@tonic-gate if (member(field, retain)) 6227c478bd9Sstevel@tonic-gate continue; 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate h = hash(field); 6257c478bd9Sstevel@tonic-gate if ((igp = (struct ignore *) 6267c478bd9Sstevel@tonic-gate calloc(1, sizeof (struct ignore))) == NULL) { 6277c478bd9Sstevel@tonic-gate panic("Couldn't allocate memory"); 6287c478bd9Sstevel@tonic-gate } 6297c478bd9Sstevel@tonic-gate if ((igp->i_field = (char *) 6307c478bd9Sstevel@tonic-gate calloc(strlen(field) + 1, sizeof (char))) == NULL) { 6317c478bd9Sstevel@tonic-gate panic("Couldn't allocate memory"); 6327c478bd9Sstevel@tonic-gate } 6337c478bd9Sstevel@tonic-gate strcpy(igp->i_field, field); 6347c478bd9Sstevel@tonic-gate igp->i_link = retain[h]; 6357c478bd9Sstevel@tonic-gate retain[h] = igp; 6367c478bd9Sstevel@tonic-gate nretained++; 6377c478bd9Sstevel@tonic-gate } 6387c478bd9Sstevel@tonic-gate return (0); 6397c478bd9Sstevel@tonic-gate } 6407c478bd9Sstevel@tonic-gate 6417c478bd9Sstevel@tonic-gate /* 6427c478bd9Sstevel@tonic-gate * Print out all currently retained fields. 6437c478bd9Sstevel@tonic-gate */ 6447c478bd9Sstevel@tonic-gate static int 6457c478bd9Sstevel@tonic-gate retshow(void) 6467c478bd9Sstevel@tonic-gate { 6477c478bd9Sstevel@tonic-gate register int h, count; 6487c478bd9Sstevel@tonic-gate struct ignore *igp; 6497c478bd9Sstevel@tonic-gate char **ap, **ring; 6507c478bd9Sstevel@tonic-gate 6517c478bd9Sstevel@tonic-gate count = 0; 6527c478bd9Sstevel@tonic-gate for (h = 0; h < HSHSIZE; h++) 6537c478bd9Sstevel@tonic-gate for (igp = retain[h]; igp != 0; igp = igp->i_link) 6547c478bd9Sstevel@tonic-gate count++; 6557c478bd9Sstevel@tonic-gate if (count == 0) { 6567c478bd9Sstevel@tonic-gate printf(gettext("No fields currently being retained.\n")); 6577c478bd9Sstevel@tonic-gate return (0); 6587c478bd9Sstevel@tonic-gate } 6597c478bd9Sstevel@tonic-gate ring = (char **)salloc((count + 1) * sizeof (char *)); 6607c478bd9Sstevel@tonic-gate ap = ring; 6617c478bd9Sstevel@tonic-gate for (h = 0; h < HSHSIZE; h++) 6627c478bd9Sstevel@tonic-gate for (igp = retain[h]; igp != 0; igp = igp->i_link) 6637c478bd9Sstevel@tonic-gate *ap++ = igp->i_field; 6647c478bd9Sstevel@tonic-gate *ap = 0; 6657c478bd9Sstevel@tonic-gate qsort(ring, count, sizeof (char *), igcomp); 6667c478bd9Sstevel@tonic-gate for (ap = ring; *ap != 0; ap++) 6677c478bd9Sstevel@tonic-gate printf("%s\n", *ap); 6687c478bd9Sstevel@tonic-gate return (0); 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate 6717c478bd9Sstevel@tonic-gate /* 6727c478bd9Sstevel@tonic-gate * Remove a list of fields from the retain list. 6737c478bd9Sstevel@tonic-gate */ 6747c478bd9Sstevel@tonic-gate int 6757c478bd9Sstevel@tonic-gate unretfield(char *list[]) 6767c478bd9Sstevel@tonic-gate { 6777c478bd9Sstevel@tonic-gate char **ap, field[BUFSIZ]; 6787c478bd9Sstevel@tonic-gate register int h, count = 0; 6797c478bd9Sstevel@tonic-gate register struct ignore *ig1, *ig2; 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate if (argcount(list) == 0) { 6827c478bd9Sstevel@tonic-gate for (h = 0; h < HSHSIZE; h++) { 6837c478bd9Sstevel@tonic-gate ig1 = retain[h]; 6847c478bd9Sstevel@tonic-gate while (ig1) { 6857c478bd9Sstevel@tonic-gate free(ig1->i_field); 6867c478bd9Sstevel@tonic-gate ig2 = ig1->i_link; 6877c478bd9Sstevel@tonic-gate free((char *)ig1); 6887c478bd9Sstevel@tonic-gate ig1 = ig2; 6897c478bd9Sstevel@tonic-gate count++; 6907c478bd9Sstevel@tonic-gate } 6917c478bd9Sstevel@tonic-gate retain[h] = NULL; 6927c478bd9Sstevel@tonic-gate } 6937c478bd9Sstevel@tonic-gate if (count == 0) 6947c478bd9Sstevel@tonic-gate printf(gettext( 6957c478bd9Sstevel@tonic-gate "No fields currently being retained.\n")); 6967c478bd9Sstevel@tonic-gate nretained = 0; 697eb2b0a61Sas145665 return (0); 6987c478bd9Sstevel@tonic-gate } 6997c478bd9Sstevel@tonic-gate for (ap = list; *ap; ap++) { 7007c478bd9Sstevel@tonic-gate istrcpy(field, sizeof (field), *ap); 7017c478bd9Sstevel@tonic-gate h = hash(field); 7027c478bd9Sstevel@tonic-gate for (ig1 = retain[h]; ig1; ig2 = ig1, ig1 = ig1->i_link) 7037c478bd9Sstevel@tonic-gate if (strcmp(ig1->i_field, field) == 0) { 7047c478bd9Sstevel@tonic-gate if (ig1 == retain[h]) 7057c478bd9Sstevel@tonic-gate retain[h] = ig1->i_link; 7067c478bd9Sstevel@tonic-gate else 7077c478bd9Sstevel@tonic-gate ig2->i_link = ig1->i_link; 7087c478bd9Sstevel@tonic-gate free(ig1->i_field); 7097c478bd9Sstevel@tonic-gate free((char *)ig1); 7107c478bd9Sstevel@tonic-gate nretained--; 7117c478bd9Sstevel@tonic-gate break; 7127c478bd9Sstevel@tonic-gate } 7137c478bd9Sstevel@tonic-gate } 714eb2b0a61Sas145665 return (0); 7157c478bd9Sstevel@tonic-gate } 7167c478bd9Sstevel@tonic-gate 7177c478bd9Sstevel@tonic-gate /* 7187c478bd9Sstevel@tonic-gate * Add the given header fields to the ignored list. 7197c478bd9Sstevel@tonic-gate * If no arguments, print the current list of ignored fields. 7207c478bd9Sstevel@tonic-gate */ 7217c478bd9Sstevel@tonic-gate int 7227c478bd9Sstevel@tonic-gate igfield(char *list[]) 7237c478bd9Sstevel@tonic-gate { 7247c478bd9Sstevel@tonic-gate char field[BUFSIZ]; 7257c478bd9Sstevel@tonic-gate register int h; 7267c478bd9Sstevel@tonic-gate register struct ignore *igp; 7277c478bd9Sstevel@tonic-gate char **ap; 7287c478bd9Sstevel@tonic-gate 7297c478bd9Sstevel@tonic-gate if (argcount(list) == 0) 7307c478bd9Sstevel@tonic-gate return (igshow()); 7317c478bd9Sstevel@tonic-gate for (ap = list; *ap != 0; ap++) { 7327c478bd9Sstevel@tonic-gate if (isign(*ap, 0)) 7337c478bd9Sstevel@tonic-gate continue; 7347c478bd9Sstevel@tonic-gate istrcpy(field, sizeof (field), *ap); 7357c478bd9Sstevel@tonic-gate h = hash(field); 7367c478bd9Sstevel@tonic-gate if ((igp = (struct ignore *) 7377c478bd9Sstevel@tonic-gate calloc(1, sizeof (struct ignore))) == NULL) { 7387c478bd9Sstevel@tonic-gate panic("Couldn't allocate memory"); 7397c478bd9Sstevel@tonic-gate } 7407c478bd9Sstevel@tonic-gate if ((igp->i_field = (char *) 7417c478bd9Sstevel@tonic-gate calloc((unsigned)strlen(field) + 1, 7427c478bd9Sstevel@tonic-gate sizeof (char))) == NULL) { 7437c478bd9Sstevel@tonic-gate panic("Couldn't allocate memory"); 7447c478bd9Sstevel@tonic-gate } 7457c478bd9Sstevel@tonic-gate strcpy(igp->i_field, field); 7467c478bd9Sstevel@tonic-gate igp->i_link = ignore[h]; 7477c478bd9Sstevel@tonic-gate ignore[h] = igp; 7487c478bd9Sstevel@tonic-gate } 7497c478bd9Sstevel@tonic-gate return (0); 7507c478bd9Sstevel@tonic-gate } 7517c478bd9Sstevel@tonic-gate 7527c478bd9Sstevel@tonic-gate /* 7537c478bd9Sstevel@tonic-gate * Print out all currently ignored fields. 7547c478bd9Sstevel@tonic-gate */ 7557c478bd9Sstevel@tonic-gate static int 7567c478bd9Sstevel@tonic-gate igshow(void) 7577c478bd9Sstevel@tonic-gate { 7587c478bd9Sstevel@tonic-gate register int h, count; 7597c478bd9Sstevel@tonic-gate struct ignore *igp; 7607c478bd9Sstevel@tonic-gate char **ap, **ring; 7617c478bd9Sstevel@tonic-gate 7627c478bd9Sstevel@tonic-gate count = 0; 7637c478bd9Sstevel@tonic-gate for (h = 0; h < HSHSIZE; h++) 7647c478bd9Sstevel@tonic-gate for (igp = ignore[h]; igp != 0; igp = igp->i_link) 7657c478bd9Sstevel@tonic-gate count++; 7667c478bd9Sstevel@tonic-gate if (count == 0) { 7677c478bd9Sstevel@tonic-gate printf(gettext("No fields currently being ignored.\n")); 7687c478bd9Sstevel@tonic-gate return (0); 7697c478bd9Sstevel@tonic-gate } 7707c478bd9Sstevel@tonic-gate ring = (char **)salloc((count + 1) * sizeof (char *)); 7717c478bd9Sstevel@tonic-gate ap = ring; 7727c478bd9Sstevel@tonic-gate for (h = 0; h < HSHSIZE; h++) 7737c478bd9Sstevel@tonic-gate for (igp = ignore[h]; igp != 0; igp = igp->i_link) 7747c478bd9Sstevel@tonic-gate *ap++ = igp->i_field; 7757c478bd9Sstevel@tonic-gate *ap = 0; 7767c478bd9Sstevel@tonic-gate qsort((char *)ring, (unsigned)count, sizeof (char *), igcomp); 7777c478bd9Sstevel@tonic-gate for (ap = ring; *ap != 0; ap++) 7787c478bd9Sstevel@tonic-gate printf("%s\n", *ap); 7797c478bd9Sstevel@tonic-gate return (0); 7807c478bd9Sstevel@tonic-gate } 7817c478bd9Sstevel@tonic-gate 7827c478bd9Sstevel@tonic-gate /* 7837c478bd9Sstevel@tonic-gate * Compare two names for sorting ignored field list. 7847c478bd9Sstevel@tonic-gate */ 7857c478bd9Sstevel@tonic-gate static int 7867c478bd9Sstevel@tonic-gate igcomp(const void *l, const void *r) 7877c478bd9Sstevel@tonic-gate { 7887c478bd9Sstevel@tonic-gate return (strcmp(*(char **)l, *(char **)r)); 7897c478bd9Sstevel@tonic-gate } 7907c478bd9Sstevel@tonic-gate 7917c478bd9Sstevel@tonic-gate /* 7927c478bd9Sstevel@tonic-gate * Remove a list of fields from the ignore list. 7937c478bd9Sstevel@tonic-gate */ 7947c478bd9Sstevel@tonic-gate int 7957c478bd9Sstevel@tonic-gate unigfield(char *list[]) 7967c478bd9Sstevel@tonic-gate { 7977c478bd9Sstevel@tonic-gate char **ap, field[BUFSIZ]; 7987c478bd9Sstevel@tonic-gate register int h, count = 0; 7997c478bd9Sstevel@tonic-gate register struct ignore *ig1, *ig2; 8007c478bd9Sstevel@tonic-gate 8017c478bd9Sstevel@tonic-gate if (argcount(list) == 0) { 8027c478bd9Sstevel@tonic-gate for (h = 0; h < HSHSIZE; h++) { 8037c478bd9Sstevel@tonic-gate ig1 = ignore[h]; 8047c478bd9Sstevel@tonic-gate while (ig1) { 8057c478bd9Sstevel@tonic-gate free(ig1->i_field); 8067c478bd9Sstevel@tonic-gate ig2 = ig1->i_link; 8077c478bd9Sstevel@tonic-gate free((char *)ig1); 8087c478bd9Sstevel@tonic-gate ig1 = ig2; 8097c478bd9Sstevel@tonic-gate count++; 8107c478bd9Sstevel@tonic-gate } 8117c478bd9Sstevel@tonic-gate ignore[h] = NULL; 8127c478bd9Sstevel@tonic-gate } 8137c478bd9Sstevel@tonic-gate if (count == 0) 8147c478bd9Sstevel@tonic-gate printf(gettext("No fields currently being ignored.\n")); 815eb2b0a61Sas145665 return (0); 8167c478bd9Sstevel@tonic-gate } 8177c478bd9Sstevel@tonic-gate for (ap = list; *ap; ap++) { 8187c478bd9Sstevel@tonic-gate istrcpy(field, sizeof (field), *ap); 8197c478bd9Sstevel@tonic-gate h = hash(field); 8207c478bd9Sstevel@tonic-gate for (ig1 = ignore[h]; ig1; ig2 = ig1, ig1 = ig1->i_link) 8217c478bd9Sstevel@tonic-gate if (strcmp(ig1->i_field, field) == 0) { 8227c478bd9Sstevel@tonic-gate if (ig1 == ignore[h]) 8237c478bd9Sstevel@tonic-gate ignore[h] = ig1->i_link; 8247c478bd9Sstevel@tonic-gate else 8257c478bd9Sstevel@tonic-gate ig2->i_link = ig1->i_link; 8267c478bd9Sstevel@tonic-gate free(ig1->i_field); 8277c478bd9Sstevel@tonic-gate free((char *)ig1); 8287c478bd9Sstevel@tonic-gate break; 8297c478bd9Sstevel@tonic-gate } 8307c478bd9Sstevel@tonic-gate } 831eb2b0a61Sas145665 return (0); 8327c478bd9Sstevel@tonic-gate } 833