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 #include "rcv.h" 42 #include <locale.h> 43 44 /* 45 * mailx -- a modified version of a University of California at Berkeley 46 * mail program 47 * 48 * More commands.. 49 */ 50 51 static char *stripquotes(char *str); 52 53 /* 54 * pipe messages to cmd. 55 */ 56 57 int 58 dopipe(char str[]) 59 { 60 int *ip, mesg; 61 struct message *mp; 62 char *cp, *cmd; 63 int f, *msgvec, nowait=0; 64 void (*sigint)(int), (*sigpipe)(int); 65 long lc, cc, t; 66 pid_t pid; 67 int page, s, pivec[2]; 68 char *Shell; 69 FILE *pio = NULL; 70 extern jmp_buf pipestop; 71 extern void brokpipe(int); 72 73 msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec); 74 if ((cmd = stripquotes(snarf(str, &f, 0))) == NOSTR) { 75 if (f == -1) { 76 printf(gettext("pipe command error\n")); 77 return(1); 78 } 79 if ( (cmd = value("cmd")) == NOSTR) { 80 printf(gettext("\"cmd\" not set, ignored.\n")); 81 return(1); 82 } 83 } 84 if (!f) { 85 *msgvec = first(0, MMNORM); 86 if (*msgvec == 0) { 87 printf(gettext("No messages to pipe.\n")); 88 return(1); 89 } 90 msgvec[1] = 0; 91 } 92 if (f && getmsglist(str, msgvec, 0) < 0) 93 return(1); 94 if (*(cp=cmd+strlen(cmd)-1)=='&') { 95 *cp=0; 96 nowait++; 97 } 98 printf(gettext("Pipe to: \"%s\"\n"), cmd); 99 flush(); 100 101 if (setjmp(pipestop)) 102 goto err; 103 /* setup pipe */ 104 if (pipe(pivec) < 0) { 105 perror("pipe"); 106 return(0); 107 } 108 109 if ((pid = vfork()) == 0) { 110 close(pivec[1]); /* child */ 111 close(0); 112 dup(pivec[0]); 113 close(pivec[0]); 114 if ((Shell = value("SHELL")) == NOSTR || *Shell=='\0') 115 Shell = SHELL; 116 execlp(Shell, Shell, "-c", cmd, 0); 117 perror(Shell); 118 _exit(1); 119 } 120 if (pid == (pid_t)-1) { /* error */ 121 perror("fork"); 122 close(pivec[0]); 123 close(pivec[1]); 124 return(0); 125 } 126 127 close(pivec[0]); /* parent */ 128 pio=fdopen(pivec[1],"w"); 129 sigint = sigset(SIGINT, SIG_IGN); 130 sigpipe = sigset(SIGPIPE, brokpipe); 131 132 /* send all messages to cmd */ 133 page = (value("page")!=NOSTR); 134 lc = cc = 0; 135 for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { 136 mesg = *ip; 137 touch(mesg); 138 mp = &message[mesg-1]; 139 dot = mp; 140 if ((t = msend(mp, pio, 141 (value("alwaysignore") != NOSTR || 142 value("pipeignore") != NOSTR) 143 ? M_IGNORE : 0, fputs)) < 0) { 144 perror(cmd); 145 sigset(SIGPIPE, sigpipe); 146 sigset(SIGINT, sigint); 147 fclose(pio); 148 return(1); 149 } 150 lc += t; 151 cc += mp->m_size; 152 if (page) putc('\f', pio); 153 } 154 155 fflush(pio); 156 if (ferror(pio)) 157 perror(cmd); 158 fclose(pio); 159 pio = NULL; 160 161 /* wait */ 162 if (!nowait) { 163 while (wait(&s) != pid); 164 s &= 0377; 165 if (s != 0) 166 goto err; 167 } 168 169 printf("\"%s\" %ld/%ld\n", cmd, lc, cc); 170 sigset(SIGPIPE, sigpipe); 171 sigset(SIGINT, sigint); 172 return(0); 173 174 err: 175 printf(gettext("Pipe to \"%s\" failed\n"), cmd); 176 if (pio) 177 fclose(pio); 178 sigset(SIGPIPE, sigpipe); 179 sigset(SIGINT, sigint); 180 return(0); 181 } 182 183 /* 184 * Load the named message from the named file. 185 */ 186 int 187 loadmsg(char str[]) 188 { 189 char *file; 190 int f, *msgvec; 191 int c, lastc = '\n'; 192 int blank; 193 int lines; 194 long ms; 195 FILE *ibuf; 196 struct message *mp; 197 off_t size; 198 199 msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec); 200 if ((file = snarf(str, &f, 1)) == NOSTR) 201 return(1); 202 if (f==-1) 203 return(1); 204 if (!f) { 205 *msgvec = first(0, MMNORM); 206 if (*msgvec == 0) { 207 printf(gettext("No message to load into.\n")); 208 return(1); 209 } 210 msgvec[1] = 0; 211 } 212 if (f && getmsglist(str, msgvec, 0) < 0) 213 return(1); 214 if (msgvec[1] != 0) { 215 printf(gettext("Can only load into a single message.\n")); 216 return(1); 217 } 218 if ((file = expand(file)) == NOSTR) 219 return(1); 220 printf("\"%s\" ", file); 221 fflush(stdout); 222 if ((ibuf = fopen(file, "r")) == NULL) { 223 perror(""); 224 return(1); 225 } 226 mp = &message[*msgvec-1]; 227 dot = mp; 228 mp->m_flag |= MODIFY; 229 mp->m_flag &= ~MSAVED; /* should probably turn off more */ 230 fseek(otf, (long) 0, 2); 231 size = fsize(otf); 232 mp->m_offset = size; 233 ms = 0L; 234 lines = 0; 235 while ((c = getc(ibuf)) != EOF) { 236 if (c == '\n') { 237 lines++; 238 blank = lastc == '\n'; 239 } 240 lastc = c; 241 putc(c, otf); 242 if (ferror(otf)) 243 break; 244 ms++; 245 } 246 if (!blank) { 247 putc('\n', otf); 248 ms++; 249 lines++; 250 } 251 mp->m_size = ms; 252 mp->m_lines = lines; 253 if (fferror(otf)) 254 perror("/tmp"); 255 fclose(ibuf); 256 setclen(mp); 257 printf(gettext("[Loaded] %d/%ld\n"), lines, ms); 258 return(0); 259 } 260 261 /* 262 * Display the named field. 263 */ 264 int 265 field(char str[]) 266 { 267 int *ip; 268 struct message *mp; 269 char *cp, *fld; 270 int f, *msgvec; 271 272 msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec); 273 if ((fld = stripquotes(snarf(str, &f, 0))) == NOSTR) { 274 if (f == -1) 275 printf(gettext("Bad field\n")); 276 else 277 printf(gettext("No field specified\n")); 278 return(1); 279 } 280 if (!f) { 281 *msgvec = first(0, MMNORM); 282 if (*msgvec == 0) { 283 printf(gettext("No messages to display.\n")); 284 return(1); 285 } 286 msgvec[1] = 0; 287 } 288 if (f && getmsglist(str, msgvec, 0) < 0) 289 return(1); 290 291 for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { 292 mp = &message[*ip - 1]; 293 dot = mp; 294 if ((cp = hfield(fld, mp, addone)) != NULL) 295 printf("%s\n", cp); 296 } 297 return(0); 298 } 299 300 /* 301 * Remove the quotes from around the string passed in (if any). Return 302 * the beginning of the result. 303 */ 304 305 static char * 306 stripquotes(char *str) 307 { 308 int lastch; 309 if (str == NOSTR) { 310 return(NOSTR); 311 } 312 lastch = strlen(str)-1; 313 if (any(*str, "\"'") && str[lastch] == *str) { 314 str[lastch] = '\0'; 315 ++str; 316 } 317 return(str); 318 } 319