1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate /* 26*7c478bd9Sstevel@tonic-gate * Copyright 2001-2002 Sun Microsystems, Inc. All rights reserved. 27*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 28*7c478bd9Sstevel@tonic-gate */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate /* 32*7c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 33*7c478bd9Sstevel@tonic-gate * The Regents of the University of California 34*7c478bd9Sstevel@tonic-gate * All Rights Reserved 35*7c478bd9Sstevel@tonic-gate * 36*7c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 37*7c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 38*7c478bd9Sstevel@tonic-gate * contributors. 39*7c478bd9Sstevel@tonic-gate */ 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate #include "rcv.h" 44*7c478bd9Sstevel@tonic-gate #include <locale.h> 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate /* 47*7c478bd9Sstevel@tonic-gate * mailx -- a modified version of a University of California at Berkeley 48*7c478bd9Sstevel@tonic-gate * mail program 49*7c478bd9Sstevel@tonic-gate * 50*7c478bd9Sstevel@tonic-gate * More user commands. 51*7c478bd9Sstevel@tonic-gate */ 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate static int igshow(void); 54*7c478bd9Sstevel@tonic-gate static int igcomp(const void *l, const void *r); 55*7c478bd9Sstevel@tonic-gate static int save1(char str[], int mark); 56*7c478bd9Sstevel@tonic-gate static int Save1(int *msgvec, int mark); 57*7c478bd9Sstevel@tonic-gate static void savemsglist(char *file, int *msgvec, int flag); 58*7c478bd9Sstevel@tonic-gate static int put1(char str[], int doign); 59*7c478bd9Sstevel@tonic-gate static int svputs(const char *line, FILE *obuf); 60*7c478bd9Sstevel@tonic-gate static int wrputs(const char *line, FILE *obuf); 61*7c478bd9Sstevel@tonic-gate static int retshow(void); 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate /* flags for savemsglist() */ 64*7c478bd9Sstevel@tonic-gate #define S_MARK 1 /* mark the message as saved */ 65*7c478bd9Sstevel@tonic-gate #define S_NOHEADER 2 /* don't write out the header */ 66*7c478bd9Sstevel@tonic-gate #define S_SAVING 4 /* doing save/copy */ 67*7c478bd9Sstevel@tonic-gate #define S_NOIGNORE 8 /* don't do ignore processing */ 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate /* 70*7c478bd9Sstevel@tonic-gate * If any arguments were given, go to the next applicable argument 71*7c478bd9Sstevel@tonic-gate * following dot, otherwise, go to the next applicable message. 72*7c478bd9Sstevel@tonic-gate * If given as first command with no arguments, print first message. 73*7c478bd9Sstevel@tonic-gate */ 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate int 76*7c478bd9Sstevel@tonic-gate next(int *msgvec) 77*7c478bd9Sstevel@tonic-gate { 78*7c478bd9Sstevel@tonic-gate register struct message *mp; 79*7c478bd9Sstevel@tonic-gate register int *ip, *ip2; 80*7c478bd9Sstevel@tonic-gate int list[2], mdot; 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate if (*msgvec != NULL) { 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate /* 85*7c478bd9Sstevel@tonic-gate * If some messages were supplied, find the 86*7c478bd9Sstevel@tonic-gate * first applicable one following dot using 87*7c478bd9Sstevel@tonic-gate * wrap around. 88*7c478bd9Sstevel@tonic-gate */ 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate mdot = dot - &message[0] + 1; 91*7c478bd9Sstevel@tonic-gate 92*7c478bd9Sstevel@tonic-gate /* 93*7c478bd9Sstevel@tonic-gate * Find the first message in the supplied 94*7c478bd9Sstevel@tonic-gate * message list which follows dot. 95*7c478bd9Sstevel@tonic-gate */ 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate for (ip = msgvec; *ip != NULL; ip++) 98*7c478bd9Sstevel@tonic-gate if (*ip > mdot) 99*7c478bd9Sstevel@tonic-gate break; 100*7c478bd9Sstevel@tonic-gate if (*ip == NULL) 101*7c478bd9Sstevel@tonic-gate ip = msgvec; 102*7c478bd9Sstevel@tonic-gate ip2 = ip; 103*7c478bd9Sstevel@tonic-gate do { 104*7c478bd9Sstevel@tonic-gate mp = &message[*ip2 - 1]; 105*7c478bd9Sstevel@tonic-gate if ((mp->m_flag & MDELETED) == 0) { 106*7c478bd9Sstevel@tonic-gate dot = mp; 107*7c478bd9Sstevel@tonic-gate goto hitit; 108*7c478bd9Sstevel@tonic-gate } 109*7c478bd9Sstevel@tonic-gate if (*ip2 != NULL) 110*7c478bd9Sstevel@tonic-gate ip2++; 111*7c478bd9Sstevel@tonic-gate if (*ip2 == NULL) 112*7c478bd9Sstevel@tonic-gate ip2 = msgvec; 113*7c478bd9Sstevel@tonic-gate } while (ip2 != ip); 114*7c478bd9Sstevel@tonic-gate printf(gettext("No messages applicable\n")); 115*7c478bd9Sstevel@tonic-gate return(1); 116*7c478bd9Sstevel@tonic-gate } 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gate /* 119*7c478bd9Sstevel@tonic-gate * If this is the first command, select message 1. 120*7c478bd9Sstevel@tonic-gate * Note that this must exist for us to get here at all. 121*7c478bd9Sstevel@tonic-gate */ 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate if (!sawcom) 124*7c478bd9Sstevel@tonic-gate goto hitit; 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate /* 127*7c478bd9Sstevel@tonic-gate * Just find the next good message after dot, no 128*7c478bd9Sstevel@tonic-gate * wraparound. 129*7c478bd9Sstevel@tonic-gate */ 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate for (mp = dot+1; mp < &message[msgCount]; mp++) 132*7c478bd9Sstevel@tonic-gate if ((mp->m_flag & (MDELETED|MSAVED)) == 0) 133*7c478bd9Sstevel@tonic-gate break; 134*7c478bd9Sstevel@tonic-gate if (mp >= &message[msgCount]) { 135*7c478bd9Sstevel@tonic-gate printf(gettext("At EOF\n")); 136*7c478bd9Sstevel@tonic-gate return(0); 137*7c478bd9Sstevel@tonic-gate } 138*7c478bd9Sstevel@tonic-gate dot = mp; 139*7c478bd9Sstevel@tonic-gate hitit: 140*7c478bd9Sstevel@tonic-gate /* 141*7c478bd9Sstevel@tonic-gate * Print dot. 142*7c478bd9Sstevel@tonic-gate */ 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate list[0] = dot - &message[0] + 1; 145*7c478bd9Sstevel@tonic-gate list[1] = NULL; 146*7c478bd9Sstevel@tonic-gate return(type(list)); 147*7c478bd9Sstevel@tonic-gate } 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate /* 150*7c478bd9Sstevel@tonic-gate * Save a message in a file. Mark the message as saved 151*7c478bd9Sstevel@tonic-gate * so we can discard when the user quits. 152*7c478bd9Sstevel@tonic-gate */ 153*7c478bd9Sstevel@tonic-gate int 154*7c478bd9Sstevel@tonic-gate save(char str[]) 155*7c478bd9Sstevel@tonic-gate { 156*7c478bd9Sstevel@tonic-gate return(save1(str, S_MARK)); 157*7c478bd9Sstevel@tonic-gate } 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate /* 160*7c478bd9Sstevel@tonic-gate * Copy a message to a file without affected its saved-ness 161*7c478bd9Sstevel@tonic-gate */ 162*7c478bd9Sstevel@tonic-gate int 163*7c478bd9Sstevel@tonic-gate copycmd(char str[]) 164*7c478bd9Sstevel@tonic-gate { 165*7c478bd9Sstevel@tonic-gate return(save1(str, 0)); 166*7c478bd9Sstevel@tonic-gate } 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate /* 169*7c478bd9Sstevel@tonic-gate * Save/copy the indicated messages at the end of the passed file name. 170*7c478bd9Sstevel@tonic-gate * If mark is true, mark the message "saved." 171*7c478bd9Sstevel@tonic-gate */ 172*7c478bd9Sstevel@tonic-gate static int 173*7c478bd9Sstevel@tonic-gate save1(char str[], int mark) 174*7c478bd9Sstevel@tonic-gate { 175*7c478bd9Sstevel@tonic-gate char *file, *cmd; 176*7c478bd9Sstevel@tonic-gate int f, *msgvec; 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate cmd = mark ? "save" : "copy"; 179*7c478bd9Sstevel@tonic-gate msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec); 180*7c478bd9Sstevel@tonic-gate if ((file = snarf(str, &f, 0)) == NOSTR) 181*7c478bd9Sstevel@tonic-gate file = Getf("MBOX"); 182*7c478bd9Sstevel@tonic-gate if (f==-1) 183*7c478bd9Sstevel@tonic-gate return(1); 184*7c478bd9Sstevel@tonic-gate if (!f) { 185*7c478bd9Sstevel@tonic-gate *msgvec = first(0, MMNORM); 186*7c478bd9Sstevel@tonic-gate if (*msgvec == NULL) { 187*7c478bd9Sstevel@tonic-gate printf(gettext("No messages to %s.\n"), cmd); 188*7c478bd9Sstevel@tonic-gate return(1); 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate msgvec[1] = NULL; 191*7c478bd9Sstevel@tonic-gate } 192*7c478bd9Sstevel@tonic-gate if (f && getmsglist(str, msgvec, 0) < 0) 193*7c478bd9Sstevel@tonic-gate return(1); 194*7c478bd9Sstevel@tonic-gate if ((file = expand(file)) == NOSTR) 195*7c478bd9Sstevel@tonic-gate return(1); 196*7c478bd9Sstevel@tonic-gate savemsglist(file, msgvec, mark | S_SAVING); 197*7c478bd9Sstevel@tonic-gate return(0); 198*7c478bd9Sstevel@tonic-gate } 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate int 201*7c478bd9Sstevel@tonic-gate Save(int *msgvec) 202*7c478bd9Sstevel@tonic-gate { 203*7c478bd9Sstevel@tonic-gate return(Save1(msgvec, S_MARK)); 204*7c478bd9Sstevel@tonic-gate } 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate int 207*7c478bd9Sstevel@tonic-gate Copy(int *msgvec) 208*7c478bd9Sstevel@tonic-gate { 209*7c478bd9Sstevel@tonic-gate return(Save1(msgvec, 0)); 210*7c478bd9Sstevel@tonic-gate } 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate /* 213*7c478bd9Sstevel@tonic-gate * save/copy the indicated messages at the end of a file named 214*7c478bd9Sstevel@tonic-gate * by the sender of the first message in the msglist. 215*7c478bd9Sstevel@tonic-gate */ 216*7c478bd9Sstevel@tonic-gate static int 217*7c478bd9Sstevel@tonic-gate Save1(int *msgvec, int mark) 218*7c478bd9Sstevel@tonic-gate { 219*7c478bd9Sstevel@tonic-gate register char *from; 220*7c478bd9Sstevel@tonic-gate char recfile[BUFSIZ]; 221*7c478bd9Sstevel@tonic-gate 222*7c478bd9Sstevel@tonic-gate #ifdef notdef 223*7c478bd9Sstevel@tonic-gate from = striphosts(nameof(&message[*msgvec-1], 0)); 224*7c478bd9Sstevel@tonic-gate #else 225*7c478bd9Sstevel@tonic-gate from = nameof(&message[*msgvec-1]); 226*7c478bd9Sstevel@tonic-gate #endif 227*7c478bd9Sstevel@tonic-gate getrecf(from, recfile, 1, sizeof (recfile)); 228*7c478bd9Sstevel@tonic-gate if (*recfile != '\0') 229*7c478bd9Sstevel@tonic-gate savemsglist(safeexpand(recfile), msgvec, mark | S_SAVING); 230*7c478bd9Sstevel@tonic-gate return(0); 231*7c478bd9Sstevel@tonic-gate } 232*7c478bd9Sstevel@tonic-gate 233*7c478bd9Sstevel@tonic-gate int 234*7c478bd9Sstevel@tonic-gate sput(char str[]) 235*7c478bd9Sstevel@tonic-gate { 236*7c478bd9Sstevel@tonic-gate return(put1(str, 0)); 237*7c478bd9Sstevel@tonic-gate } 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate int 240*7c478bd9Sstevel@tonic-gate Sput(char str[]) 241*7c478bd9Sstevel@tonic-gate { 242*7c478bd9Sstevel@tonic-gate return(put1(str, S_NOIGNORE)); 243*7c478bd9Sstevel@tonic-gate } 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate /* 246*7c478bd9Sstevel@tonic-gate * Put the indicated messages at the end of the passed file name. 247*7c478bd9Sstevel@tonic-gate */ 248*7c478bd9Sstevel@tonic-gate static int 249*7c478bd9Sstevel@tonic-gate put1(char str[], int doign) 250*7c478bd9Sstevel@tonic-gate { 251*7c478bd9Sstevel@tonic-gate char *file; 252*7c478bd9Sstevel@tonic-gate int f, *msgvec; 253*7c478bd9Sstevel@tonic-gate 254*7c478bd9Sstevel@tonic-gate msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec); 255*7c478bd9Sstevel@tonic-gate if ((file = snarf(str, &f, 0)) == NOSTR) 256*7c478bd9Sstevel@tonic-gate file = Getf("MBOX"); 257*7c478bd9Sstevel@tonic-gate if (f==-1) 258*7c478bd9Sstevel@tonic-gate return(1); 259*7c478bd9Sstevel@tonic-gate if (!f) { 260*7c478bd9Sstevel@tonic-gate *msgvec = first(0, MMNORM); 261*7c478bd9Sstevel@tonic-gate if (*msgvec == NULL) { 262*7c478bd9Sstevel@tonic-gate printf(gettext("No messages to put.\n")); 263*7c478bd9Sstevel@tonic-gate return(1); 264*7c478bd9Sstevel@tonic-gate } 265*7c478bd9Sstevel@tonic-gate msgvec[1] = NULL; 266*7c478bd9Sstevel@tonic-gate } 267*7c478bd9Sstevel@tonic-gate if (f && getmsglist(str, msgvec, 0) < 0) 268*7c478bd9Sstevel@tonic-gate return(1); 269*7c478bd9Sstevel@tonic-gate if ((file = expand(file)) == NOSTR) 270*7c478bd9Sstevel@tonic-gate return(1); 271*7c478bd9Sstevel@tonic-gate savemsglist(file, msgvec, doign); 272*7c478bd9Sstevel@tonic-gate return(0); 273*7c478bd9Sstevel@tonic-gate } 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate /* 276*7c478bd9Sstevel@tonic-gate * save a message list in a file. 277*7c478bd9Sstevel@tonic-gate * if wr set, doing "write" instead 278*7c478bd9Sstevel@tonic-gate * of "save" or "copy" so don't put 279*7c478bd9Sstevel@tonic-gate * out header. 280*7c478bd9Sstevel@tonic-gate */ 281*7c478bd9Sstevel@tonic-gate 282*7c478bd9Sstevel@tonic-gate static int wr_linecount; /* count of lines written */ 283*7c478bd9Sstevel@tonic-gate static int wr_charcount; /* char count of lines written */ 284*7c478bd9Sstevel@tonic-gate static int wr_inlines; /* count of lines read */ 285*7c478bd9Sstevel@tonic-gate static long wr_maxlines; /* total lines in message */ 286*7c478bd9Sstevel@tonic-gate static int wr_inhead; /* in header of message */ 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate static void 289*7c478bd9Sstevel@tonic-gate savemsglist(char *file, int *msgvec, int flag) 290*7c478bd9Sstevel@tonic-gate { 291*7c478bd9Sstevel@tonic-gate register int *ip, mesg; 292*7c478bd9Sstevel@tonic-gate register struct message *mp; 293*7c478bd9Sstevel@tonic-gate char *disp; 294*7c478bd9Sstevel@tonic-gate FILE *obuf; 295*7c478bd9Sstevel@tonic-gate struct stat statb; 296*7c478bd9Sstevel@tonic-gate long lc, cc, t; 297*7c478bd9Sstevel@tonic-gate int bnry, mflag; 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate printf("\"%s\" ", file); 300*7c478bd9Sstevel@tonic-gate flush(); 301*7c478bd9Sstevel@tonic-gate if (stat(file, &statb) >= 0) 302*7c478bd9Sstevel@tonic-gate disp = "[Appended]"; 303*7c478bd9Sstevel@tonic-gate else 304*7c478bd9Sstevel@tonic-gate disp = "[New file]"; 305*7c478bd9Sstevel@tonic-gate if ((obuf = fopen(file, "a")) == NULL) { 306*7c478bd9Sstevel@tonic-gate perror(""); 307*7c478bd9Sstevel@tonic-gate return; 308*7c478bd9Sstevel@tonic-gate } 309*7c478bd9Sstevel@tonic-gate lc = cc = 0; 310*7c478bd9Sstevel@tonic-gate bnry = 0; 311*7c478bd9Sstevel@tonic-gate if (flag & S_SAVING) 312*7c478bd9Sstevel@tonic-gate mflag = (int)value("alwaysignore")?(M_IGNORE|M_SAVING):M_SAVING; 313*7c478bd9Sstevel@tonic-gate else if (flag & S_NOIGNORE) 314*7c478bd9Sstevel@tonic-gate mflag = 0; 315*7c478bd9Sstevel@tonic-gate else 316*7c478bd9Sstevel@tonic-gate mflag = M_IGNORE; 317*7c478bd9Sstevel@tonic-gate for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { 318*7c478bd9Sstevel@tonic-gate mesg = *ip; 319*7c478bd9Sstevel@tonic-gate mp = &message[mesg-1]; 320*7c478bd9Sstevel@tonic-gate if (!mp->m_text) { 321*7c478bd9Sstevel@tonic-gate bnry = 1; 322*7c478bd9Sstevel@tonic-gate } 323*7c478bd9Sstevel@tonic-gate wr_linecount = 0; 324*7c478bd9Sstevel@tonic-gate wr_charcount = 0; 325*7c478bd9Sstevel@tonic-gate if (flag & S_NOHEADER) { 326*7c478bd9Sstevel@tonic-gate wr_inhead = 1; 327*7c478bd9Sstevel@tonic-gate wr_maxlines = mp->m_lines; 328*7c478bd9Sstevel@tonic-gate wr_inlines = 0; 329*7c478bd9Sstevel@tonic-gate t = msend(mp, obuf, 0, wrputs); 330*7c478bd9Sstevel@tonic-gate } else { 331*7c478bd9Sstevel@tonic-gate t = msend(mp, obuf, mflag, svputs); 332*7c478bd9Sstevel@tonic-gate } 333*7c478bd9Sstevel@tonic-gate if (t < 0) { 334*7c478bd9Sstevel@tonic-gate perror(file); 335*7c478bd9Sstevel@tonic-gate fclose(obuf); 336*7c478bd9Sstevel@tonic-gate return; 337*7c478bd9Sstevel@tonic-gate } 338*7c478bd9Sstevel@tonic-gate touch(mesg); 339*7c478bd9Sstevel@tonic-gate dot = mp; 340*7c478bd9Sstevel@tonic-gate lc += wr_linecount; 341*7c478bd9Sstevel@tonic-gate cc += wr_charcount; 342*7c478bd9Sstevel@tonic-gate if (flag & S_MARK) 343*7c478bd9Sstevel@tonic-gate mp->m_flag |= MSAVED; 344*7c478bd9Sstevel@tonic-gate } 345*7c478bd9Sstevel@tonic-gate fflush(obuf); 346*7c478bd9Sstevel@tonic-gate if (fferror(obuf)) 347*7c478bd9Sstevel@tonic-gate perror(file); 348*7c478bd9Sstevel@tonic-gate fclose(obuf); 349*7c478bd9Sstevel@tonic-gate if (!bnry) { 350*7c478bd9Sstevel@tonic-gate printf("%s %ld/%ld\n", disp, lc, cc); 351*7c478bd9Sstevel@tonic-gate } else { 352*7c478bd9Sstevel@tonic-gate printf("%s binary/%ld\n", disp, cc); 353*7c478bd9Sstevel@tonic-gate } 354*7c478bd9Sstevel@tonic-gate } 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate static int 357*7c478bd9Sstevel@tonic-gate svputs(const char *line, FILE *obuf) 358*7c478bd9Sstevel@tonic-gate { 359*7c478bd9Sstevel@tonic-gate wr_linecount++; 360*7c478bd9Sstevel@tonic-gate wr_charcount += strlen(line); 361*7c478bd9Sstevel@tonic-gate return(fputs(line, obuf)); 362*7c478bd9Sstevel@tonic-gate } 363*7c478bd9Sstevel@tonic-gate 364*7c478bd9Sstevel@tonic-gate static int 365*7c478bd9Sstevel@tonic-gate wrputs(const char *line, FILE *obuf) 366*7c478bd9Sstevel@tonic-gate { 367*7c478bd9Sstevel@tonic-gate /* 368*7c478bd9Sstevel@tonic-gate * If this is a header line or 369*7c478bd9Sstevel@tonic-gate * the last line, don't write it out. Since we may add a 370*7c478bd9Sstevel@tonic-gate * "Status" line the line count may be off by one so insist 371*7c478bd9Sstevel@tonic-gate * that the last line is blank before we skip it. 372*7c478bd9Sstevel@tonic-gate */ 373*7c478bd9Sstevel@tonic-gate wr_inlines++; 374*7c478bd9Sstevel@tonic-gate if (wr_inhead) { 375*7c478bd9Sstevel@tonic-gate if (strcmp(line, "\n") == 0) 376*7c478bd9Sstevel@tonic-gate wr_inhead = 0; 377*7c478bd9Sstevel@tonic-gate return(0); 378*7c478bd9Sstevel@tonic-gate } 379*7c478bd9Sstevel@tonic-gate if (wr_inlines >= wr_maxlines && strcmp(line, "\n") == 0) 380*7c478bd9Sstevel@tonic-gate return(0); 381*7c478bd9Sstevel@tonic-gate wr_linecount++; 382*7c478bd9Sstevel@tonic-gate wr_charcount += strlen(line); 383*7c478bd9Sstevel@tonic-gate return(fputs(line, obuf)); 384*7c478bd9Sstevel@tonic-gate } 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate /* 387*7c478bd9Sstevel@tonic-gate * Write the indicated messages at the end of the passed 388*7c478bd9Sstevel@tonic-gate * file name, minus header and trailing blank line. 389*7c478bd9Sstevel@tonic-gate */ 390*7c478bd9Sstevel@tonic-gate 391*7c478bd9Sstevel@tonic-gate int 392*7c478bd9Sstevel@tonic-gate swrite(char str[]) 393*7c478bd9Sstevel@tonic-gate { 394*7c478bd9Sstevel@tonic-gate register char *file; 395*7c478bd9Sstevel@tonic-gate int f, *msgvec; 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec); 398*7c478bd9Sstevel@tonic-gate if ((file = snarf(str, &f, 1)) == NOSTR) 399*7c478bd9Sstevel@tonic-gate return(1); 400*7c478bd9Sstevel@tonic-gate if (f==-1) 401*7c478bd9Sstevel@tonic-gate return(1); 402*7c478bd9Sstevel@tonic-gate if ((file = expand(file)) == NOSTR) 403*7c478bd9Sstevel@tonic-gate return(1); 404*7c478bd9Sstevel@tonic-gate if (!f) { 405*7c478bd9Sstevel@tonic-gate *msgvec = first(0, MMNORM); 406*7c478bd9Sstevel@tonic-gate if (*msgvec == NULL) { 407*7c478bd9Sstevel@tonic-gate printf(gettext("No messages to write.\n")); 408*7c478bd9Sstevel@tonic-gate return(1); 409*7c478bd9Sstevel@tonic-gate } 410*7c478bd9Sstevel@tonic-gate msgvec[1] = NULL; 411*7c478bd9Sstevel@tonic-gate } 412*7c478bd9Sstevel@tonic-gate if (f && getmsglist(str, msgvec, 0) < 0) 413*7c478bd9Sstevel@tonic-gate return(1); 414*7c478bd9Sstevel@tonic-gate savemsglist(file, msgvec, S_MARK|S_NOHEADER); 415*7c478bd9Sstevel@tonic-gate return(0); 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate /* 419*7c478bd9Sstevel@tonic-gate * Snarf the file from the end of the command line and 420*7c478bd9Sstevel@tonic-gate * return a pointer to it. If there is no file attached, 421*7c478bd9Sstevel@tonic-gate * just return NOSTR. Put a null in front of the file 422*7c478bd9Sstevel@tonic-gate * name so that the message list processing won't see it, 423*7c478bd9Sstevel@tonic-gate * unless the file name is the only thing on the line, in 424*7c478bd9Sstevel@tonic-gate * which case, return 0 in the reference flag variable. 425*7c478bd9Sstevel@tonic-gate */ 426*7c478bd9Sstevel@tonic-gate 427*7c478bd9Sstevel@tonic-gate /* 428*7c478bd9Sstevel@tonic-gate * The following definitions are used to characterize the syntactic 429*7c478bd9Sstevel@tonic-gate * category of the preceding character in the following parse procedure. 430*7c478bd9Sstevel@tonic-gate * The variable pc_type assumes these values. 431*7c478bd9Sstevel@tonic-gate */ 432*7c478bd9Sstevel@tonic-gate 433*7c478bd9Sstevel@tonic-gate #define SN_DELIM 1 /* Delimiter (<blank> or line beginning) */ 434*7c478bd9Sstevel@tonic-gate #define SN_TOKEN 2 /* A part of a token */ 435*7c478bd9Sstevel@tonic-gate #define SN_QUOTE 4 /* An entire quoted string (ie, "...") */ 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate char * 438*7c478bd9Sstevel@tonic-gate snarf(char linebuf[], int *flag, int erf) 439*7c478bd9Sstevel@tonic-gate { 440*7c478bd9Sstevel@tonic-gate register char *p; /* utility pointer */ 441*7c478bd9Sstevel@tonic-gate register char qc; /* quotation character to match */ 442*7c478bd9Sstevel@tonic-gate register unsigned int pc_type; /* preceding character type */ 443*7c478bd9Sstevel@tonic-gate register char *tok_beg; /* beginning of last token */ 444*7c478bd9Sstevel@tonic-gate register char *tok_end; /* end of last token */ 445*7c478bd9Sstevel@tonic-gate char *line_beg; /* beginning of line, after */ 446*7c478bd9Sstevel@tonic-gate /* leading whitespace */ 447*7c478bd9Sstevel@tonic-gate 448*7c478bd9Sstevel@tonic-gate /* 449*7c478bd9Sstevel@tonic-gate * Skip leading whitespace. 450*7c478bd9Sstevel@tonic-gate */ 451*7c478bd9Sstevel@tonic-gate for (line_beg = linebuf; 452*7c478bd9Sstevel@tonic-gate *line_beg && any(*line_beg, " \t"); 453*7c478bd9Sstevel@tonic-gate line_beg++) { 454*7c478bd9Sstevel@tonic-gate /* empty body */ 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate if (!*line_beg) { 457*7c478bd9Sstevel@tonic-gate if (erf) { 458*7c478bd9Sstevel@tonic-gate printf(gettext("No file specified\n.")); 459*7c478bd9Sstevel@tonic-gate } 460*7c478bd9Sstevel@tonic-gate *flag = 0; 461*7c478bd9Sstevel@tonic-gate return(NOSTR); 462*7c478bd9Sstevel@tonic-gate } 463*7c478bd9Sstevel@tonic-gate /* 464*7c478bd9Sstevel@tonic-gate * Process line from left-to-right, 1 char at a time. 465*7c478bd9Sstevel@tonic-gate */ 466*7c478bd9Sstevel@tonic-gate for (pc_type = SN_DELIM, tok_beg = tok_end = NOSTR, p = line_beg; 467*7c478bd9Sstevel@tonic-gate *p != '\0'; ) { 468*7c478bd9Sstevel@tonic-gate if (any(*p, " \t")) { 469*7c478bd9Sstevel@tonic-gate /* This character is a DELIMITER */ 470*7c478bd9Sstevel@tonic-gate if (pc_type & (SN_TOKEN|SN_QUOTE)) { 471*7c478bd9Sstevel@tonic-gate tok_end = p - 1; 472*7c478bd9Sstevel@tonic-gate } 473*7c478bd9Sstevel@tonic-gate pc_type = SN_DELIM; 474*7c478bd9Sstevel@tonic-gate p++; 475*7c478bd9Sstevel@tonic-gate } else if ((qc = *p) == '"' || qc == '\'') { 476*7c478bd9Sstevel@tonic-gate /* This character is a QUOTE character */ 477*7c478bd9Sstevel@tonic-gate if (pc_type == SN_TOKEN) { 478*7c478bd9Sstevel@tonic-gate /* embedded quotation symbols are simply */ 479*7c478bd9Sstevel@tonic-gate /* token characters. */ 480*7c478bd9Sstevel@tonic-gate p++; 481*7c478bd9Sstevel@tonic-gate continue; 482*7c478bd9Sstevel@tonic-gate } 483*7c478bd9Sstevel@tonic-gate /* Search for the matching QUOTE character */ 484*7c478bd9Sstevel@tonic-gate for (tok_beg = p, tok_end = NOSTR, p++; 485*7c478bd9Sstevel@tonic-gate *p != '\0' && *p != qc; 486*7c478bd9Sstevel@tonic-gate p++) { 487*7c478bd9Sstevel@tonic-gate if (*p == '\\' && *(p+1) == qc) { 488*7c478bd9Sstevel@tonic-gate p++; 489*7c478bd9Sstevel@tonic-gate } 490*7c478bd9Sstevel@tonic-gate } 491*7c478bd9Sstevel@tonic-gate if (*p == '\0') { 492*7c478bd9Sstevel@tonic-gate printf(gettext("Syntax error: missing " 493*7c478bd9Sstevel@tonic-gate "%c.\n"), qc); 494*7c478bd9Sstevel@tonic-gate *flag = -1; 495*7c478bd9Sstevel@tonic-gate return(NOSTR); 496*7c478bd9Sstevel@tonic-gate } 497*7c478bd9Sstevel@tonic-gate tok_end = p; 498*7c478bd9Sstevel@tonic-gate pc_type = SN_QUOTE; 499*7c478bd9Sstevel@tonic-gate p++; 500*7c478bd9Sstevel@tonic-gate } else { 501*7c478bd9Sstevel@tonic-gate /* This character should be a TOKEN character */ 502*7c478bd9Sstevel@tonic-gate if (pc_type & (SN_DELIM|SN_TOKEN)) { 503*7c478bd9Sstevel@tonic-gate if (pc_type & SN_DELIM) { 504*7c478bd9Sstevel@tonic-gate tok_beg = p; 505*7c478bd9Sstevel@tonic-gate tok_end = NOSTR; 506*7c478bd9Sstevel@tonic-gate } 507*7c478bd9Sstevel@tonic-gate } else { 508*7c478bd9Sstevel@tonic-gate printf(gettext("improper quotes" 509*7c478bd9Sstevel@tonic-gate " at \"%s\".\n"), p); 510*7c478bd9Sstevel@tonic-gate *flag = -1; 511*7c478bd9Sstevel@tonic-gate return(NOSTR); 512*7c478bd9Sstevel@tonic-gate } 513*7c478bd9Sstevel@tonic-gate if (*p == '\\' && *++p == '\0') { 514*7c478bd9Sstevel@tonic-gate printf(gettext("\'\\\' at " 515*7c478bd9Sstevel@tonic-gate "end of line.\n")); 516*7c478bd9Sstevel@tonic-gate *flag = -1; 517*7c478bd9Sstevel@tonic-gate return(NOSTR); 518*7c478bd9Sstevel@tonic-gate } 519*7c478bd9Sstevel@tonic-gate pc_type = SN_TOKEN; 520*7c478bd9Sstevel@tonic-gate p++; 521*7c478bd9Sstevel@tonic-gate } 522*7c478bd9Sstevel@tonic-gate } 523*7c478bd9Sstevel@tonic-gate if (pc_type == SN_TOKEN) { 524*7c478bd9Sstevel@tonic-gate tok_end = p - 1; 525*7c478bd9Sstevel@tonic-gate } 526*7c478bd9Sstevel@tonic-gate if (tok_beg != NOSTR && tok_end != NOSTR) { 527*7c478bd9Sstevel@tonic-gate if (tok_beg == line_beg) { 528*7c478bd9Sstevel@tonic-gate *flag = 0; 529*7c478bd9Sstevel@tonic-gate } else { 530*7c478bd9Sstevel@tonic-gate tok_beg[-1] = '\0'; 531*7c478bd9Sstevel@tonic-gate *flag = 1; 532*7c478bd9Sstevel@tonic-gate } 533*7c478bd9Sstevel@tonic-gate tok_end[1] = '\0'; 534*7c478bd9Sstevel@tonic-gate return(tok_beg); 535*7c478bd9Sstevel@tonic-gate } else { 536*7c478bd9Sstevel@tonic-gate if (erf) { 537*7c478bd9Sstevel@tonic-gate printf(gettext("No file specified\n.")); 538*7c478bd9Sstevel@tonic-gate } 539*7c478bd9Sstevel@tonic-gate *flag = 0; 540*7c478bd9Sstevel@tonic-gate return(NOSTR); 541*7c478bd9Sstevel@tonic-gate } 542*7c478bd9Sstevel@tonic-gate } 543*7c478bd9Sstevel@tonic-gate 544*7c478bd9Sstevel@tonic-gate /* 545*7c478bd9Sstevel@tonic-gate * Delete messages, then type the new dot. 546*7c478bd9Sstevel@tonic-gate */ 547*7c478bd9Sstevel@tonic-gate 548*7c478bd9Sstevel@tonic-gate int 549*7c478bd9Sstevel@tonic-gate deltype(int msgvec[]) 550*7c478bd9Sstevel@tonic-gate { 551*7c478bd9Sstevel@tonic-gate int list[2]; 552*7c478bd9Sstevel@tonic-gate int lastdot; 553*7c478bd9Sstevel@tonic-gate 554*7c478bd9Sstevel@tonic-gate lastdot = dot - &message[0] + 1; 555*7c478bd9Sstevel@tonic-gate if (delm(msgvec) >= 0) { 556*7c478bd9Sstevel@tonic-gate list[0] = dot - &message[0]; 557*7c478bd9Sstevel@tonic-gate list[0]++; 558*7c478bd9Sstevel@tonic-gate if (list[0] > lastdot) { 559*7c478bd9Sstevel@tonic-gate touch(list[0]); 560*7c478bd9Sstevel@tonic-gate list[1] = NULL; 561*7c478bd9Sstevel@tonic-gate return(type(list)); 562*7c478bd9Sstevel@tonic-gate } 563*7c478bd9Sstevel@tonic-gate printf(gettext("At EOF\n")); 564*7c478bd9Sstevel@tonic-gate return(0); 565*7c478bd9Sstevel@tonic-gate } 566*7c478bd9Sstevel@tonic-gate else { 567*7c478bd9Sstevel@tonic-gate printf(gettext("No more messages\n")); 568*7c478bd9Sstevel@tonic-gate return(0); 569*7c478bd9Sstevel@tonic-gate } 570*7c478bd9Sstevel@tonic-gate } 571*7c478bd9Sstevel@tonic-gate 572*7c478bd9Sstevel@tonic-gate /* 573*7c478bd9Sstevel@tonic-gate * Delete the indicated messages. 574*7c478bd9Sstevel@tonic-gate * Set dot to some nice place afterwards. 575*7c478bd9Sstevel@tonic-gate */ 576*7c478bd9Sstevel@tonic-gate int 577*7c478bd9Sstevel@tonic-gate delm(int *msgvec) 578*7c478bd9Sstevel@tonic-gate { 579*7c478bd9Sstevel@tonic-gate register struct message *mp; 580*7c478bd9Sstevel@tonic-gate register *ip, mesg; 581*7c478bd9Sstevel@tonic-gate int last; 582*7c478bd9Sstevel@tonic-gate 583*7c478bd9Sstevel@tonic-gate last = NULL; 584*7c478bd9Sstevel@tonic-gate for (ip = msgvec; *ip != NULL; ip++) { 585*7c478bd9Sstevel@tonic-gate mesg = *ip; 586*7c478bd9Sstevel@tonic-gate touch(mesg); 587*7c478bd9Sstevel@tonic-gate mp = &message[mesg-1]; 588*7c478bd9Sstevel@tonic-gate mp->m_flag |= MDELETED|MTOUCH; 589*7c478bd9Sstevel@tonic-gate mp->m_flag &= ~(MPRESERVE|MSAVED|MBOX); 590*7c478bd9Sstevel@tonic-gate last = mesg; 591*7c478bd9Sstevel@tonic-gate } 592*7c478bd9Sstevel@tonic-gate if (last != NULL) { 593*7c478bd9Sstevel@tonic-gate dot = &message[last-1]; 594*7c478bd9Sstevel@tonic-gate last = first(0, MDELETED); 595*7c478bd9Sstevel@tonic-gate if (last != NULL) { 596*7c478bd9Sstevel@tonic-gate dot = &message[last-1]; 597*7c478bd9Sstevel@tonic-gate return(0); 598*7c478bd9Sstevel@tonic-gate } 599*7c478bd9Sstevel@tonic-gate else { 600*7c478bd9Sstevel@tonic-gate dot = &message[0]; 601*7c478bd9Sstevel@tonic-gate return(-1); 602*7c478bd9Sstevel@tonic-gate } 603*7c478bd9Sstevel@tonic-gate } 604*7c478bd9Sstevel@tonic-gate 605*7c478bd9Sstevel@tonic-gate /* 606*7c478bd9Sstevel@tonic-gate * Following can't happen -- it keeps lint happy 607*7c478bd9Sstevel@tonic-gate */ 608*7c478bd9Sstevel@tonic-gate 609*7c478bd9Sstevel@tonic-gate return(-1); 610*7c478bd9Sstevel@tonic-gate } 611*7c478bd9Sstevel@tonic-gate 612*7c478bd9Sstevel@tonic-gate /* 613*7c478bd9Sstevel@tonic-gate * Undelete the indicated messages. 614*7c478bd9Sstevel@tonic-gate */ 615*7c478bd9Sstevel@tonic-gate int 616*7c478bd9Sstevel@tonic-gate undelete(int *msgvec) 617*7c478bd9Sstevel@tonic-gate { 618*7c478bd9Sstevel@tonic-gate register struct message *mp; 619*7c478bd9Sstevel@tonic-gate register *ip, mesg; 620*7c478bd9Sstevel@tonic-gate 621*7c478bd9Sstevel@tonic-gate for (ip = msgvec; ip-msgvec < msgCount; ip++) { 622*7c478bd9Sstevel@tonic-gate mesg = *ip; 623*7c478bd9Sstevel@tonic-gate if (mesg == 0) 624*7c478bd9Sstevel@tonic-gate return(0); 625*7c478bd9Sstevel@tonic-gate touch(mesg); 626*7c478bd9Sstevel@tonic-gate mp = &message[mesg-1]; 627*7c478bd9Sstevel@tonic-gate dot = mp; 628*7c478bd9Sstevel@tonic-gate mp->m_flag &= ~MDELETED; 629*7c478bd9Sstevel@tonic-gate } 630*7c478bd9Sstevel@tonic-gate return(0); 631*7c478bd9Sstevel@tonic-gate } 632*7c478bd9Sstevel@tonic-gate 633*7c478bd9Sstevel@tonic-gate /* 634*7c478bd9Sstevel@tonic-gate * Add the given header fields to the retained list. 635*7c478bd9Sstevel@tonic-gate * If no arguments, print the current list of retained fields. 636*7c478bd9Sstevel@tonic-gate */ 637*7c478bd9Sstevel@tonic-gate int 638*7c478bd9Sstevel@tonic-gate retfield(char *list[]) 639*7c478bd9Sstevel@tonic-gate { 640*7c478bd9Sstevel@tonic-gate char field[BUFSIZ]; 641*7c478bd9Sstevel@tonic-gate register int h; 642*7c478bd9Sstevel@tonic-gate register struct ignore *igp; 643*7c478bd9Sstevel@tonic-gate char **ap; 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate if (argcount(list) == 0) 646*7c478bd9Sstevel@tonic-gate return(retshow()); 647*7c478bd9Sstevel@tonic-gate for (ap = list; *ap != 0; ap++) { 648*7c478bd9Sstevel@tonic-gate istrcpy(field, sizeof (field), *ap); 649*7c478bd9Sstevel@tonic-gate 650*7c478bd9Sstevel@tonic-gate if (member(field, retain)) 651*7c478bd9Sstevel@tonic-gate continue; 652*7c478bd9Sstevel@tonic-gate 653*7c478bd9Sstevel@tonic-gate h = hash(field); 654*7c478bd9Sstevel@tonic-gate if ((igp = (struct ignore *) 655*7c478bd9Sstevel@tonic-gate calloc(1, sizeof (struct ignore))) == NULL) { 656*7c478bd9Sstevel@tonic-gate panic("Couldn't allocate memory"); 657*7c478bd9Sstevel@tonic-gate } 658*7c478bd9Sstevel@tonic-gate if ((igp->i_field = (char *) 659*7c478bd9Sstevel@tonic-gate calloc(strlen(field) + 1, sizeof (char))) == NULL) { 660*7c478bd9Sstevel@tonic-gate panic("Couldn't allocate memory"); 661*7c478bd9Sstevel@tonic-gate } 662*7c478bd9Sstevel@tonic-gate strcpy(igp->i_field, field); 663*7c478bd9Sstevel@tonic-gate igp->i_link = retain[h]; 664*7c478bd9Sstevel@tonic-gate retain[h] = igp; 665*7c478bd9Sstevel@tonic-gate nretained++; 666*7c478bd9Sstevel@tonic-gate } 667*7c478bd9Sstevel@tonic-gate return(0); 668*7c478bd9Sstevel@tonic-gate } 669*7c478bd9Sstevel@tonic-gate 670*7c478bd9Sstevel@tonic-gate /* 671*7c478bd9Sstevel@tonic-gate * Print out all currently retained fields. 672*7c478bd9Sstevel@tonic-gate */ 673*7c478bd9Sstevel@tonic-gate static int 674*7c478bd9Sstevel@tonic-gate retshow(void) 675*7c478bd9Sstevel@tonic-gate { 676*7c478bd9Sstevel@tonic-gate register int h, count; 677*7c478bd9Sstevel@tonic-gate struct ignore *igp; 678*7c478bd9Sstevel@tonic-gate char **ap, **ring; 679*7c478bd9Sstevel@tonic-gate 680*7c478bd9Sstevel@tonic-gate count = 0; 681*7c478bd9Sstevel@tonic-gate for (h = 0; h < HSHSIZE; h++) 682*7c478bd9Sstevel@tonic-gate for (igp = retain[h]; igp != 0; igp = igp->i_link) 683*7c478bd9Sstevel@tonic-gate count++; 684*7c478bd9Sstevel@tonic-gate if (count == 0) { 685*7c478bd9Sstevel@tonic-gate printf(gettext("No fields currently being retained.\n")); 686*7c478bd9Sstevel@tonic-gate return(0); 687*7c478bd9Sstevel@tonic-gate } 688*7c478bd9Sstevel@tonic-gate ring = (char **) salloc((count + 1) * sizeof (char *)); 689*7c478bd9Sstevel@tonic-gate ap = ring; 690*7c478bd9Sstevel@tonic-gate for (h = 0; h < HSHSIZE; h++) 691*7c478bd9Sstevel@tonic-gate for (igp = retain[h]; igp != 0; igp = igp->i_link) 692*7c478bd9Sstevel@tonic-gate *ap++ = igp->i_field; 693*7c478bd9Sstevel@tonic-gate *ap = 0; 694*7c478bd9Sstevel@tonic-gate qsort(ring, count, sizeof (char *), igcomp); 695*7c478bd9Sstevel@tonic-gate for (ap = ring; *ap != 0; ap++) 696*7c478bd9Sstevel@tonic-gate printf("%s\n", *ap); 697*7c478bd9Sstevel@tonic-gate return(0); 698*7c478bd9Sstevel@tonic-gate } 699*7c478bd9Sstevel@tonic-gate 700*7c478bd9Sstevel@tonic-gate /* 701*7c478bd9Sstevel@tonic-gate * Remove a list of fields from the retain list. 702*7c478bd9Sstevel@tonic-gate */ 703*7c478bd9Sstevel@tonic-gate int 704*7c478bd9Sstevel@tonic-gate unretfield(char *list[]) 705*7c478bd9Sstevel@tonic-gate { 706*7c478bd9Sstevel@tonic-gate char **ap, field[BUFSIZ]; 707*7c478bd9Sstevel@tonic-gate register int h, count = 0; 708*7c478bd9Sstevel@tonic-gate register struct ignore *ig1, *ig2; 709*7c478bd9Sstevel@tonic-gate 710*7c478bd9Sstevel@tonic-gate if (argcount(list) == 0) { 711*7c478bd9Sstevel@tonic-gate for (h = 0; h < HSHSIZE; h++) { 712*7c478bd9Sstevel@tonic-gate ig1 = retain[h]; 713*7c478bd9Sstevel@tonic-gate while (ig1) { 714*7c478bd9Sstevel@tonic-gate free(ig1->i_field); 715*7c478bd9Sstevel@tonic-gate ig2 = ig1->i_link; 716*7c478bd9Sstevel@tonic-gate free((char *) ig1); 717*7c478bd9Sstevel@tonic-gate ig1 = ig2; 718*7c478bd9Sstevel@tonic-gate count++; 719*7c478bd9Sstevel@tonic-gate } 720*7c478bd9Sstevel@tonic-gate retain[h] = NULL; 721*7c478bd9Sstevel@tonic-gate } 722*7c478bd9Sstevel@tonic-gate if (count == 0) 723*7c478bd9Sstevel@tonic-gate printf(gettext( 724*7c478bd9Sstevel@tonic-gate "No fields currently being retained.\n")); 725*7c478bd9Sstevel@tonic-gate nretained = 0; 726*7c478bd9Sstevel@tonic-gate return 0; 727*7c478bd9Sstevel@tonic-gate } 728*7c478bd9Sstevel@tonic-gate for (ap = list; *ap; ap++) { 729*7c478bd9Sstevel@tonic-gate istrcpy(field, sizeof (field), *ap); 730*7c478bd9Sstevel@tonic-gate h = hash(field); 731*7c478bd9Sstevel@tonic-gate for (ig1 = retain[h]; ig1; ig2 = ig1, ig1 = ig1->i_link) 732*7c478bd9Sstevel@tonic-gate if (strcmp(ig1->i_field, field) == 0) { 733*7c478bd9Sstevel@tonic-gate if (ig1 == retain[h]) 734*7c478bd9Sstevel@tonic-gate retain[h] = ig1->i_link; 735*7c478bd9Sstevel@tonic-gate else 736*7c478bd9Sstevel@tonic-gate ig2->i_link = ig1->i_link; 737*7c478bd9Sstevel@tonic-gate free(ig1->i_field); 738*7c478bd9Sstevel@tonic-gate free((char *) ig1); 739*7c478bd9Sstevel@tonic-gate nretained--; 740*7c478bd9Sstevel@tonic-gate break; 741*7c478bd9Sstevel@tonic-gate } 742*7c478bd9Sstevel@tonic-gate } 743*7c478bd9Sstevel@tonic-gate return 0; 744*7c478bd9Sstevel@tonic-gate } 745*7c478bd9Sstevel@tonic-gate 746*7c478bd9Sstevel@tonic-gate /* 747*7c478bd9Sstevel@tonic-gate * Add the given header fields to the ignored list. 748*7c478bd9Sstevel@tonic-gate * If no arguments, print the current list of ignored fields. 749*7c478bd9Sstevel@tonic-gate */ 750*7c478bd9Sstevel@tonic-gate int 751*7c478bd9Sstevel@tonic-gate igfield(char *list[]) 752*7c478bd9Sstevel@tonic-gate { 753*7c478bd9Sstevel@tonic-gate char field[BUFSIZ]; 754*7c478bd9Sstevel@tonic-gate register int h; 755*7c478bd9Sstevel@tonic-gate register struct ignore *igp; 756*7c478bd9Sstevel@tonic-gate char **ap; 757*7c478bd9Sstevel@tonic-gate 758*7c478bd9Sstevel@tonic-gate if (argcount(list) == 0) 759*7c478bd9Sstevel@tonic-gate return(igshow()); 760*7c478bd9Sstevel@tonic-gate for (ap = list; *ap != 0; ap++) { 761*7c478bd9Sstevel@tonic-gate if (isign(*ap, 0)) 762*7c478bd9Sstevel@tonic-gate continue; 763*7c478bd9Sstevel@tonic-gate istrcpy(field, sizeof (field), *ap); 764*7c478bd9Sstevel@tonic-gate h = hash(field); 765*7c478bd9Sstevel@tonic-gate if ((igp = (struct ignore *) 766*7c478bd9Sstevel@tonic-gate calloc(1, sizeof (struct ignore))) == NULL) { 767*7c478bd9Sstevel@tonic-gate panic("Couldn't allocate memory"); 768*7c478bd9Sstevel@tonic-gate } 769*7c478bd9Sstevel@tonic-gate if ((igp->i_field = (char *) 770*7c478bd9Sstevel@tonic-gate calloc((unsigned)strlen(field) + 1, 771*7c478bd9Sstevel@tonic-gate sizeof (char))) == NULL) { 772*7c478bd9Sstevel@tonic-gate panic("Couldn't allocate memory"); 773*7c478bd9Sstevel@tonic-gate } 774*7c478bd9Sstevel@tonic-gate strcpy(igp->i_field, field); 775*7c478bd9Sstevel@tonic-gate igp->i_link = ignore[h]; 776*7c478bd9Sstevel@tonic-gate ignore[h] = igp; 777*7c478bd9Sstevel@tonic-gate } 778*7c478bd9Sstevel@tonic-gate return(0); 779*7c478bd9Sstevel@tonic-gate } 780*7c478bd9Sstevel@tonic-gate 781*7c478bd9Sstevel@tonic-gate /* 782*7c478bd9Sstevel@tonic-gate * Print out all currently ignored fields. 783*7c478bd9Sstevel@tonic-gate */ 784*7c478bd9Sstevel@tonic-gate static int 785*7c478bd9Sstevel@tonic-gate igshow(void) 786*7c478bd9Sstevel@tonic-gate { 787*7c478bd9Sstevel@tonic-gate register int h, count; 788*7c478bd9Sstevel@tonic-gate struct ignore *igp; 789*7c478bd9Sstevel@tonic-gate char **ap, **ring; 790*7c478bd9Sstevel@tonic-gate 791*7c478bd9Sstevel@tonic-gate count = 0; 792*7c478bd9Sstevel@tonic-gate for (h = 0; h < HSHSIZE; h++) 793*7c478bd9Sstevel@tonic-gate for (igp = ignore[h]; igp != 0; igp = igp->i_link) 794*7c478bd9Sstevel@tonic-gate count++; 795*7c478bd9Sstevel@tonic-gate if (count == 0) { 796*7c478bd9Sstevel@tonic-gate printf(gettext("No fields currently being ignored.\n")); 797*7c478bd9Sstevel@tonic-gate return(0); 798*7c478bd9Sstevel@tonic-gate } 799*7c478bd9Sstevel@tonic-gate ring = (char **) salloc((count + 1) * sizeof (char *)); 800*7c478bd9Sstevel@tonic-gate ap = ring; 801*7c478bd9Sstevel@tonic-gate for (h = 0; h < HSHSIZE; h++) 802*7c478bd9Sstevel@tonic-gate for (igp = ignore[h]; igp != 0; igp = igp->i_link) 803*7c478bd9Sstevel@tonic-gate *ap++ = igp->i_field; 804*7c478bd9Sstevel@tonic-gate *ap = 0; 805*7c478bd9Sstevel@tonic-gate qsort((char *) ring, (unsigned) count, sizeof (char *), igcomp); 806*7c478bd9Sstevel@tonic-gate for (ap = ring; *ap != 0; ap++) 807*7c478bd9Sstevel@tonic-gate printf("%s\n", *ap); 808*7c478bd9Sstevel@tonic-gate return(0); 809*7c478bd9Sstevel@tonic-gate } 810*7c478bd9Sstevel@tonic-gate 811*7c478bd9Sstevel@tonic-gate /* 812*7c478bd9Sstevel@tonic-gate * Compare two names for sorting ignored field list. 813*7c478bd9Sstevel@tonic-gate */ 814*7c478bd9Sstevel@tonic-gate static int 815*7c478bd9Sstevel@tonic-gate igcomp(const void *l, const void *r) 816*7c478bd9Sstevel@tonic-gate { 817*7c478bd9Sstevel@tonic-gate return(strcmp(*(char **)l, *(char **)r)); 818*7c478bd9Sstevel@tonic-gate } 819*7c478bd9Sstevel@tonic-gate 820*7c478bd9Sstevel@tonic-gate /* 821*7c478bd9Sstevel@tonic-gate * Remove a list of fields from the ignore list. 822*7c478bd9Sstevel@tonic-gate */ 823*7c478bd9Sstevel@tonic-gate int 824*7c478bd9Sstevel@tonic-gate unigfield(char *list[]) 825*7c478bd9Sstevel@tonic-gate { 826*7c478bd9Sstevel@tonic-gate char **ap, field[BUFSIZ]; 827*7c478bd9Sstevel@tonic-gate register int h, count = 0; 828*7c478bd9Sstevel@tonic-gate register struct ignore *ig1, *ig2; 829*7c478bd9Sstevel@tonic-gate 830*7c478bd9Sstevel@tonic-gate if (argcount(list) == 0) { 831*7c478bd9Sstevel@tonic-gate for (h = 0; h < HSHSIZE; h++) { 832*7c478bd9Sstevel@tonic-gate ig1 = ignore[h]; 833*7c478bd9Sstevel@tonic-gate while (ig1) { 834*7c478bd9Sstevel@tonic-gate free(ig1->i_field); 835*7c478bd9Sstevel@tonic-gate ig2 = ig1->i_link; 836*7c478bd9Sstevel@tonic-gate free((char *) ig1); 837*7c478bd9Sstevel@tonic-gate ig1 = ig2; 838*7c478bd9Sstevel@tonic-gate count++; 839*7c478bd9Sstevel@tonic-gate } 840*7c478bd9Sstevel@tonic-gate ignore[h] = NULL; 841*7c478bd9Sstevel@tonic-gate } 842*7c478bd9Sstevel@tonic-gate if (count == 0) 843*7c478bd9Sstevel@tonic-gate printf(gettext("No fields currently being ignored.\n")); 844*7c478bd9Sstevel@tonic-gate return 0; 845*7c478bd9Sstevel@tonic-gate } 846*7c478bd9Sstevel@tonic-gate for (ap = list; *ap; ap++) { 847*7c478bd9Sstevel@tonic-gate istrcpy(field, sizeof (field), *ap); 848*7c478bd9Sstevel@tonic-gate h = hash(field); 849*7c478bd9Sstevel@tonic-gate for (ig1 = ignore[h]; ig1; ig2 = ig1, ig1 = ig1->i_link) 850*7c478bd9Sstevel@tonic-gate if (strcmp(ig1->i_field, field) == 0) { 851*7c478bd9Sstevel@tonic-gate if (ig1 == ignore[h]) 852*7c478bd9Sstevel@tonic-gate ignore[h] = ig1->i_link; 853*7c478bd9Sstevel@tonic-gate else 854*7c478bd9Sstevel@tonic-gate ig2->i_link = ig1->i_link; 855*7c478bd9Sstevel@tonic-gate free(ig1->i_field); 856*7c478bd9Sstevel@tonic-gate free((char *) ig1); 857*7c478bd9Sstevel@tonic-gate break; 858*7c478bd9Sstevel@tonic-gate } 859*7c478bd9Sstevel@tonic-gate } 860*7c478bd9Sstevel@tonic-gate return 0; 861*7c478bd9Sstevel@tonic-gate } 862