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