Merge commit 'b1e7e97d3b60469b243b3b2e22c7d8cbd11c7c90'
[unleashed.git] / usr / src / cmd / mailx / cmd4.c
blob64e9163fff614982d197e699edf424d85dada0c6
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
23 * Copyright 1995 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
32 * University Copyright- Copyright (c) 1982, 1986, 1988
33 * The Regents of the University of California
34 * All Rights Reserved
36 * University Acknowledgment- Portions of this document are derived from
37 * software developed by the University of California, Berkeley, and its
38 * contributors.
41 #include "rcv.h"
42 #include <locale.h>
45 * mailx -- a modified version of a University of California at Berkeley
46 * mail program
48 * More commands..
51 static char *stripquotes(char *str);
54 * pipe messages to cmd.
57 int
58 dopipe(char str[])
60 register int *ip, mesg;
61 register 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 register 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);
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);
79 if ( (cmd = value("cmd")) == NOSTR) {
80 printf(gettext("\"cmd\" not set, ignored.\n"));
81 return(1);
84 if (!f) {
85 *msgvec = first(0, MMNORM);
86 if (*msgvec == 0) {
87 printf(gettext("No messages to pipe.\n"));
88 return(1);
90 msgvec[1] = 0;
92 if (f && getmsglist(str, msgvec, 0) < 0)
93 return(1);
94 if (*(cp=cmd+strlen(cmd)-1)=='&') {
95 *cp=0;
96 nowait++;
98 printf(gettext("Pipe to: \"%s\"\n"), cmd);
99 flush();
101 if (setjmp(pipestop))
102 goto err;
103 /* setup pipe */
104 if (pipe(pivec) < 0) {
105 perror("pipe");
106 return(0);
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);
120 if (pid == (pid_t)-1) { /* error */
121 perror("fork");
122 close(pivec[0]);
123 close(pivec[1]);
124 return(0);
127 close(pivec[0]); /* parent */
128 pio=fdopen(pivec[1],"w");
129 sigint = sigset(SIGINT, SIG_IGN);
130 sigpipe = sigset(SIGPIPE, brokpipe);
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);
150 lc += t;
151 cc += mp->m_size;
152 if (page) putc('\f', pio);
155 fflush(pio);
156 if (ferror(pio))
157 perror(cmd);
158 fclose(pio);
159 pio = NULL;
161 /* wait */
162 if (!nowait) {
163 while (wait(&s) != pid);
164 s &= 0377;
165 if (s != 0)
166 goto err;
169 printf("\"%s\" %ld/%ld\n", cmd, lc, cc);
170 sigset(SIGPIPE, sigpipe);
171 sigset(SIGINT, sigint);
172 return(0);
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);
184 * Load the named message from the named file.
186 int
187 loadmsg(char str[])
189 char *file;
190 int f, *msgvec;
191 register int c, lastc = '\n';
192 int blank;
193 int lines;
194 long ms;
195 FILE *ibuf;
196 struct message *mp;
197 off_t size;
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);
210 msgvec[1] = 0;
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);
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);
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';
240 lastc = c;
241 putc(c, otf);
242 if (ferror(otf))
243 break;
244 ms++;
246 if (!blank) {
247 putc('\n', otf);
248 ms++;
249 lines++;
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);
262 * Display the named field.
264 int
265 field(char str[])
267 register int *ip;
268 register struct message *mp;
269 register char *cp, *fld;
270 int f, *msgvec;
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);
280 if (!f) {
281 *msgvec = first(0, MMNORM);
282 if (*msgvec == 0) {
283 printf(gettext("No messages to display.\n"));
284 return(1);
286 msgvec[1] = 0;
288 if (f && getmsglist(str, msgvec, 0) < 0)
289 return(1);
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);
297 return(0);
301 * Remove the quotes from around the string passed in (if any). Return
302 * the beginning of the result.
305 static char *
306 stripquotes(char *str)
308 register int lastch;
309 if (str == NOSTR) {
310 return(NOSTR);
312 lastch = strlen(str)-1;
313 if (any(*str, "\"'") && str[lastch] == *str) {
314 str[lastch] = '\0';
315 ++str;
317 return(str);