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