1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1995 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 /* 32 * University Copyright- Copyright (c) 1982, 1986, 1988 33 * The Regents of the University of California 34 * All Rights Reserved 35 * 36 * University Acknowledgment- Portions of this document are derived from 37 * software developed by the University of California, Berkeley, and its 38 * contributors. 39 */ 40 41 #pragma ident "%Z%%M% %I% %E% SMI" 42 43 #include "rcv.h" 44 #include <locale.h> 45 46 /* 47 * mailx -- a modified version of a University of California at Berkeley 48 * mail program 49 * 50 * More commands.. 51 */ 52 53 static char *stripquotes(char *str); 54 55 /* 56 * pipe messages to cmd. 57 */ 58 59 int 60 dopipe(char str[]) 61 { 62 register int *ip, mesg; 63 register struct message *mp; 64 char *cp, *cmd; 65 int f, *msgvec, nowait=0; 66 void (*sigint)(int), (*sigpipe)(int); 67 long lc, cc, t; 68 register pid_t pid; 69 int page, s, pivec[2]; 70 char *Shell; 71 FILE *pio = NULL; 72 extern jmp_buf pipestop; 73 extern void brokpipe(int); 74 75 msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec); 76 if ((cmd = stripquotes(snarf(str, &f, 0))) == NOSTR) { 77 if (f == -1) { 78 printf(gettext("pipe command error\n")); 79 return(1); 80 } 81 if ( (cmd = value("cmd")) == NOSTR) { 82 printf(gettext("\"cmd\" not set, ignored.\n")); 83 return(1); 84 } 85 } 86 if (!f) { 87 *msgvec = first(0, MMNORM); 88 if (*msgvec == NULL) { 89 printf(gettext("No messages to pipe.\n")); 90 return(1); 91 } 92 msgvec[1] = NULL; 93 } 94 if (f && getmsglist(str, msgvec, 0) < 0) 95 return(1); 96 if (*(cp=cmd+strlen(cmd)-1)=='&') { 97 *cp=0; 98 nowait++; 99 } 100 printf(gettext("Pipe to: \"%s\"\n"), cmd); 101 flush(); 102 103 if (setjmp(pipestop)) 104 goto err; 105 /* setup pipe */ 106 if (pipe(pivec) < 0) { 107 perror("pipe"); 108 return(0); 109 } 110 111 if ((pid = vfork()) == 0) { 112 close(pivec[1]); /* child */ 113 close(0); 114 dup(pivec[0]); 115 close(pivec[0]); 116 if ((Shell = value("SHELL")) == NOSTR || *Shell=='\0') 117 Shell = SHELL; 118 execlp(Shell, Shell, "-c", cmd, 0); 119 perror(Shell); 120 _exit(1); 121 } 122 if (pid == (pid_t)-1) { /* error */ 123 perror("fork"); 124 close(pivec[0]); 125 close(pivec[1]); 126 return(0); 127 } 128 129 close(pivec[0]); /* parent */ 130 pio=fdopen(pivec[1],"w"); 131 sigint = sigset(SIGINT, SIG_IGN); 132 sigpipe = sigset(SIGPIPE, brokpipe); 133 134 /* send all messages to cmd */ 135 page = (value("page")!=NOSTR); 136 lc = cc = 0; 137 for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { 138 mesg = *ip; 139 touch(mesg); 140 mp = &message[mesg-1]; 141 dot = mp; 142 if ((t = msend(mp, pio, 143 (value("alwaysignore") != NOSTR || 144 value("pipeignore") != NOSTR) 145 ? M_IGNORE : 0, fputs)) < 0) { 146 perror(cmd); 147 sigset(SIGPIPE, sigpipe); 148 sigset(SIGINT, sigint); 149 fclose(pio); 150 return(1); 151 } 152 lc += t; 153 cc += mp->m_size; 154 if (page) putc('\f', pio); 155 } 156 157 fflush(pio); 158 if (ferror(pio)) 159 perror(cmd); 160 fclose(pio); 161 pio = NULL; 162 163 /* wait */ 164 if (!nowait) { 165 while (wait(&s) != pid); 166 s &= 0377; 167 if (s != 0) 168 goto err; 169 } 170 171 printf("\"%s\" %ld/%ld\n", cmd, lc, cc); 172 sigset(SIGPIPE, sigpipe); 173 sigset(SIGINT, sigint); 174 return(0); 175 176 err: 177 printf(gettext("Pipe to \"%s\" failed\n"), cmd); 178 if (pio) 179 fclose(pio); 180 sigset(SIGPIPE, sigpipe); 181 sigset(SIGINT, sigint); 182 return(0); 183 } 184 185 /* 186 * Load the named message from the named file. 187 */ 188 int 189 loadmsg(char str[]) 190 { 191 char *file; 192 int f, *msgvec; 193 register int c, lastc = '\n'; 194 int blank; 195 int lines; 196 long ms; 197 FILE *ibuf; 198 struct message *mp; 199 off_t size; 200 201 msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec); 202 if ((file = snarf(str, &f, 1)) == NOSTR) 203 return(1); 204 if (f==-1) 205 return(1); 206 if (!f) { 207 *msgvec = first(0, MMNORM); 208 if (*msgvec == NULL) { 209 printf(gettext("No message to load into.\n")); 210 return(1); 211 } 212 msgvec[1] = NULL; 213 } 214 if (f && getmsglist(str, msgvec, 0) < 0) 215 return(1); 216 if (msgvec[1] != NULL) { 217 printf(gettext("Can only load into a single message.\n")); 218 return(1); 219 } 220 if ((file = expand(file)) == NOSTR) 221 return(1); 222 printf("\"%s\" ", file); 223 fflush(stdout); 224 if ((ibuf = fopen(file, "r")) == NULL) { 225 perror(""); 226 return(1); 227 } 228 mp = &message[*msgvec-1]; 229 dot = mp; 230 mp->m_flag |= MODIFY; 231 mp->m_flag &= ~MSAVED; /* should probably turn off more */ 232 fseek(otf, (long) 0, 2); 233 size = fsize(otf); 234 mp->m_offset = size; 235 ms = 0L; 236 lines = 0; 237 while ((c = getc(ibuf)) != EOF) { 238 if (c == '\n') { 239 lines++; 240 blank = lastc == '\n'; 241 } 242 lastc = c; 243 putc(c, otf); 244 if (ferror(otf)) 245 break; 246 ms++; 247 } 248 if (!blank) { 249 putc('\n', otf); 250 ms++; 251 lines++; 252 } 253 mp->m_size = ms; 254 mp->m_lines = lines; 255 if (fferror(otf)) 256 perror("/tmp"); 257 fclose(ibuf); 258 setclen(mp); 259 printf(gettext("[Loaded] %d/%ld\n"), lines, ms); 260 return(0); 261 } 262 263 /* 264 * Display the named field. 265 */ 266 int 267 field(char str[]) 268 { 269 register int *ip; 270 register struct message *mp; 271 register char *cp, *fld; 272 int f, *msgvec; 273 274 msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec); 275 if ((fld = stripquotes(snarf(str, &f, 0))) == NOSTR) { 276 if (f == -1) 277 printf(gettext("Bad field\n")); 278 else 279 printf(gettext("No field specified\n")); 280 return(1); 281 } 282 if (!f) { 283 *msgvec = first(0, MMNORM); 284 if (*msgvec == NULL) { 285 printf(gettext("No messages to display.\n")); 286 return(1); 287 } 288 msgvec[1] = NULL; 289 } 290 if (f && getmsglist(str, msgvec, 0) < 0) 291 return(1); 292 293 for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { 294 mp = &message[*ip - 1]; 295 dot = mp; 296 if ((cp = hfield(fld, mp, addone)) != NULL) 297 printf("%s\n", cp); 298 } 299 return(0); 300 } 301 302 /* 303 * Remove the quotes from around the string passed in (if any). Return 304 * the beginning of the result. 305 */ 306 307 static char * 308 stripquotes(char *str) 309 { 310 register int lastch; 311 if (str == NOSTR) { 312 return(NOSTR); 313 } 314 lastch = strlen(str)-1; 315 if (any(*str, "\"'") && str[lastch] == *str) { 316 str[lastch] = '\0'; 317 ++str; 318 } 319 return(str); 320 } 321