4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1985, 2010, Oracle and/or its affiliates. All rights reserved.
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
30 * University Copyright- Copyright (c) 1982, 1986, 1988
31 * The Regents of the University of California
34 * University Acknowledgment- Portions of this document are derived from
35 * software developed by the University of California, Berkeley, and its
40 * mailx -- a modified version of a University of California at Berkeley
43 * Collect input from standard input, handling
51 static void collcont(int);
53 static void collrub(int s
);
54 static void cpout(char *str
, FILE *ofd
);
55 static int exwrite(char name
[], FILE *ibuf
);
56 static int forward(char ms
[], FILE *obuf
, int f
);
57 static void intack(int);
58 static int forward(char ms
[], FILE *obuf
, int f
);
59 static FILE *mesedit(FILE *ibuf
, FILE *obuf
, int c
, struct header
*hp
);
60 static FILE *mespipe(FILE *ibuf
, FILE *obuf
, char cmd
[]);
61 static void resetsigs(int resethup
);
62 static int stripnulls(register char *linebuf
, register int nread
);
63 static void xhalt(void);
64 static char **Xaddone(char **hf
, char news
[]);
65 static int tabputs(const char *line
, FILE *obuf
);
68 * Read a message from standard output and return a read file to it
73 * The following hokiness with global variables is so that on
74 * receipt of an interrupt signal, the partial message can be salted
75 * away on dead.letter. The output file must be available to flush,
76 * and the input to read. Several open files could be saved all through
77 * mailx if stdio allowed simultaneous read/write access.
80 static void (*savesig
)(int); /* Previous SIGINT value */
81 static void (*savehup
)(int); /* Previous SIGHUP value */
83 static void (*savecont
)(int); /* Previous SIGCONT value */
85 static FILE *newi
; /* File for saving away */
86 static FILE *newo
; /* Output side of same */
87 static int ignintr
; /* Ignore interrups */
88 static int hadintr
; /* Have seen one SIGINT so far */
89 static struct header
*savehp
;
90 static jmp_buf coljmp
; /* To get back to work */
93 collect(struct header
*hp
)
95 FILE *ibuf
, *fbuf
, *obuf
;
100 char linebuf
[LINESIZE
+1], *cp
;
103 void (*sigpipe
)(int), (*sigint
)(int);
109 if ((fd
= open(tempMail
, O_RDWR
|O_CREAT
|O_EXCL
, 0600)) < 0 ||
110 (obuf
= fdopen(fd
, "w")) == NULL
) {
115 if ((ibuf
= fopen(tempMail
, "r")) == NULL
) {
122 removefile(tempMail
);
124 ignintr
= (int)value("ignore");
129 if ((savesig
= sigset(SIGINT
, SIG_IGN
)) != SIG_IGN
)
130 sigset(SIGINT
, ignintr
? intack
: collrub
), sigblock(sigmask(SIGINT
));
131 if ((savehup
= sigset(SIGHUP
, SIG_IGN
)) != SIG_IGN
)
132 sigset(SIGHUP
, collrub
), sigblock(sigmask(SIGHUP
));
135 if ((savesig
= sigset(SIGINT
, SIG_IGN
)) != SIG_IGN
)
136 sigset(SIGINT
, ignintr
? intack
: collrub
);
137 if ((savehup
= sigset(SIGHUP
, SIG_IGN
)) != SIG_IGN
)
138 sigset(SIGHUP
, collrub
);
140 if ((savesig
= sigset(SIGINT
, SIG_IGN
)) != SIG_IGN
) {
144 sigaddset(&mask
, SIGINT
);
145 sigset(SIGINT
, ignintr
? intack
: collrub
);
146 sigprocmask(SIG_BLOCK
, &mask
, NULL
);
148 if ((savehup
= sigset(SIGHUP
, SIG_IGN
)) != SIG_IGN
) {
152 sigaddset(&mask
, SIGHUP
);
153 sigset(SIGHUP
, collrub
);
154 sigprocmask(SIG_BLOCK
, &mask
, NULL
);
159 savecont
= sigset(SIGCONT
, collcont
);
162 * If we are going to prompt for subject/cc/bcc,
163 * refrain from printing a newline after
164 * the headers (since some people mind).
167 if (hp
->h_subject
== NOSTR
) {
168 hp
->h_subject
= sflag
;
171 if (hp
->h_cc
== NOSTR
) {
175 if (hp
->h_bcc
== NOSTR
) {
181 if (intty
&& !tflag
) {
182 if (hp
->h_to
== NOSTR
)
184 if (hp
->h_subject
== NOSTR
&& value("asksub"))
186 if (hp
->h_cc
== NOSTR
&& value("askcc"))
188 if (hp
->h_bcc
== NOSTR
&& value("askbcc"))
193 if (hp
->h_seq
!= 0) {
194 puthead(hp
, stdout
, t
, 0);
200 if ((cp
= value("escape")) != NOSTR
)
203 if ((cp
= value("MAILX_HEAD")) != NOSTR
) {
205 if (isatty(fileno(stdin
)))
208 iprompt
= value("iprompt");
214 int omask
= sigblock(0) &~ (sigmask(SIGINT
)|sigmask(SIGHUP
));
216 # ifndef OLD_BSD_SIGS
218 sigprocmask(0, NULL
, &omask
);
219 sigdelset(&omask
, SIGINT
);
220 sigdelset(&omask
, SIGHUP
);
232 sigprocmask(SIG_SETMASK
, &omask
, NULL
);
235 if (intty
&& !tflag
&& outtty
&& iprompt
)
236 fputs(iprompt
, stdout
);
243 if ((nread
= getaline(linebuf
,LINESIZE
,stdin
,&hasnulls
)) == 0) {
244 if (intty
&& value("ignoreeof") != NOSTR
) {
248 "Use \".\" to terminate letter\n"));
255 if (intty
&& equal(".\n", linebuf
) &&
256 (value("dot") != NOSTR
|| value("ignoreeof") != NOSTR
))
259 * If -t, scan text for headers.
266 if (write(fileno(obuf
),linebuf
,nread
) != nread
)
270 if (linebuf
[0] == '\n') {
271 /* got blank line after header, ignore it */
275 if (!headerp(linebuf
)) {
276 /* got non-header line, save it */
281 nread
= stripnulls(linebuf
, nread
);
283 char line2
[LINESIZE
];
287 if (!isspace(c
) || c
== '\n')
289 if (readline(stdin
, line2
) < 0)
291 for (cp2
= line2
; *cp2
!= 0 && isspace(*cp2
);
294 if (strlen(linebuf
) + strlen(cp2
) >=
295 (unsigned)LINESIZE
-2)
297 cp
= &linebuf
[strlen(linebuf
)];
298 while (cp
> linebuf
&&
299 (isspace(cp
[-1]) || cp
[-1] == '\\'))
304 if ((c
= strlen(linebuf
)) > 0) {
306 while (cp
> linebuf
&& isspace(*cp
))
310 if (ishfield(linebuf
, "to"))
311 hp
->h_to
= addto(hp
->h_to
, hcontents(linebuf
));
312 else if (ishfield(linebuf
, "subject"))
314 addone(hp
->h_subject
, hcontents(linebuf
));
315 else if (ishfield(linebuf
, "cc"))
316 hp
->h_cc
= addto(hp
->h_cc
, hcontents(linebuf
));
317 else if (ishfield(linebuf
, "bcc"))
319 addto(hp
->h_bcc
, hcontents(linebuf
));
320 else if (ishfield(linebuf
, "default-options"))
322 addone(hp
->h_defopt
, hcontents(linebuf
));
324 hp
->h_others
= Xaddone(hp
->h_others
, linebuf
);
328 if ((linebuf
[0] != escape
) || (rflag
!= NOSTR
) ||
329 (!intty
&& !(int)value("escapeok"))) {
330 if (write(fileno(obuf
),linebuf
,nread
) != nread
)
335 * On double escape, just send the single one.
337 if ((nread
> 1) && (linebuf
[1] == escape
)) {
338 if (write(fileno(obuf
),linebuf
+1,nread
-1) != (nread
-1))
343 nread
= stripnulls(linebuf
, nread
);
345 linebuf
[nread
- 1] = '\0';
349 * Otherwise, it's an error.
351 printf(gettext("Unknown tilde escape.\n"));
357 * autograph; sign the letter.
360 if (cp
= value(c
=='a' ? "sign":"Sign")) {
363 if (isatty(fileno(stdin
))) {
375 for (cp
= &linebuf
[2]; any(*cp
, " \t"); cp
++)
382 if (isatty(fileno(stdout
))) {
391 * Shell escape, send the balance of the
401 * Escape to command mode, but be nice!
404 execute(&linebuf
[2], 1);
405 iprompt
= value("iprompt");
406 if (cp
= value("escape"))
408 printf(gettext("(continue)\n"));
413 * Simulate end of file on input.
420 * Force a quit of sending mail.
421 * Act like an interrupt happened.
431 break; /* not reached */
435 * Grab a bunch of headers.
437 if (!intty
|| !outtty
) {
438 printf(gettext("~h: no can do!?\n"));
441 grabh(hp
, GMASK
, (int)value("bsdcompat"));
442 printf(gettext("(continue)\n"));
447 * Add to the To list.
450 hp
->h_to
= addto(hp
->h_to
, &linebuf
[2]);
456 * Set the Subject list.
460 while (any(*cp
, " \t"))
462 hp
->h_subject
= savestr(cp
);
468 * Add to the CC list.
471 hp
->h_cc
= addto(hp
->h_cc
, &linebuf
[2]);
477 * Add stuff to blind carbon copies list.
479 hp
->h_bcc
= addto(hp
->h_bcc
, &linebuf
[2]);
484 hp
->h_defopt
= addone(hp
->h_defopt
, myname
);
486 fprintf(stderr
, gettext("Return receipt marked.\n"));
491 copy(Getf("DEAD"), &linebuf
[2]);
499 * Search for the file name,
500 * then open it and copy the contents to obuf.
502 * if name begins with '!', read from a command
506 while (any(*cp
, " \t"))
509 printf(gettext("Interpolate what file?\n"));
513 /* take input from a command */
515 if ((fbuf
= npopen(++cp
, "r"))==NULL
) {
519 sigint
= sigset(SIGINT
, SIG_IGN
);
526 printf(gettext("%s: directory\n"), cp
);
529 if ((fbuf
= fopen(cp
, "r")) == NULL
) {
534 printf("\"%s\" ", cp
);
537 while ((t
= getc(fbuf
)) != EOF
) {
540 if (putc(t
, obuf
) == EOF
) {
543 sigset(SIGINT
, sigint
);
552 sigset(SIGINT
, sigint
);
555 printf("%ld/%ld\n", lc
, cc
);
562 * Write the message on a file.
566 while (any(*cp
, " \t"))
569 fprintf(stderr
, gettext("Write what file!?\n"));
572 if ((cp
= expand(cp
)) == NOSTR
)
584 * Interpolate the named messages, if we
585 * are in receiving mail mode. Does the
586 * standard list processing garbage.
587 * If ~f or ~F is given, we don't shift over.
592 "No messages to send from!?!\n"));
596 while (any(*cp
, " \t"))
598 if (forward(cp
, obuf
, c
) < 0)
601 printf(gettext("(continue)\n"));
605 if ((fbuf
= fopen(THELPFILE
, "r")) == NULL
) {
606 printf(gettext("No help just now.\n"));
619 * Print out the current state of the
620 * message without altering anything.
623 extern jmp_buf pipestop
;
624 extern void brokpipe(int);
629 if (setjmp(pipestop
))
631 if (intty
&& outtty
&& (cp
= value("crt")) != NOSTR
) {
633 (*cp
== '\0' ? screensize() : atoi(cp
)) - 7;
634 /* 7 for hdr lines */
635 while ((t
= getc(ibuf
)) != EOF
) {
642 fbuf
= npopen(MORE
, "w");
647 sigint
= sigset(SIGINT
, SIG_IGN
);
648 sigpipe
= sigset(SIGPIPE
, brokpipe
);
652 fprintf(fbuf
, gettext("-------\nMessage contains:\n"));
653 puthead(hp
, fbuf
, GMASK
, 0);
654 while ((t
= getc(ibuf
))!=EOF
)
657 if (fbuf
!= stdout
) {
659 sigset(SIGPIPE
, sigpipe
);
660 sigset(SIGINT
, sigint
);
662 printf(gettext("(continue)\n"));
669 * Pipe message through command.
670 * Collect output as new message.
673 obuf
= mespipe(ibuf
, obuf
, &linebuf
[2]);
677 printf(gettext("(continue)\n"));
683 * Edit the current message.
684 * 'e' means to use EDITOR
685 * 'v' means to use VISUAL
688 if ((obuf
= mesedit(ibuf
, obuf
, c
, hp
)) == NULL
)
692 printf(gettext("(continue)\n"));
699 if ((cp
= value("MAILX_TAIL")) != NOSTR
) {
701 if (isatty(fileno(stdin
)))
712 * Write error occurred on tmp file, save partial
713 * message in dead.letter.
718 if (fsize(ibuf
) > 0) {
721 deadletter
= Getf("DEAD");
722 fprintf(stderr
, gettext("Saving partial message in %s\n"),
724 if ((fbuf
= fopen(deadletter
,
725 value("appenddeadletter") == NOSTR
? "w" : "a")) != NULL
) {
726 chmod(deadletter
, DEADPERM
);
727 puthead(hp
, fbuf
, GMASK
|GCLEN
, fsize(ibuf
));
728 lcwrite(deadletter
, ibuf
, fbuf
, value("appenddeadletter") != NOSTR
);
745 resetsigs(int resethup
)
747 (void) sigset(SIGINT
, savesig
);
749 (void) sigset(SIGHUP
, savehup
);
752 (void) sigset(SIGCONT
, savecont
);
755 struct sigaction nsig
;
756 nsig
.sa_handler
= (void (*)())savecont
;
757 sigemptyset(&nsig
.sa_mask
);
758 nsig
.sa_flags
= SA_RESTART
;
759 (void) sigaction(SIGCONT
, &nsig
, NULL
);
766 * Write a file ex-like.
770 exwrite(char name
[], FILE *ibuf
)
774 void (*sigint
)(int), (*sigpipe
)(int);
775 int pi
= (*name
== '!');
777 if ((of
= pi
? npopen(++name
, "w") : fopen(name
, "a")) == NULL
) {
782 sigint
= sigset(SIGINT
, SIG_IGN
);
783 sigpipe
= sigset(SIGPIPE
, SIG_IGN
);
785 lcwrite(name
, ibuf
, of
, 0);
786 pi
? npclose(of
) : fclose(of
);
788 sigset(SIGPIPE
, sigpipe
);
789 sigset(SIGINT
, sigint
);
795 lcwrite(char *fn
, FILE *fi
, FILE *fo
, int addnl
)
800 printf("\"%s\" ", fn
);
803 while ((c
= getc(fi
)) != EOF
) {
805 if (putc(c
, fo
) == '\n')
822 printf("%ld/%ld\n", lc
, cc
);
827 * Edit the message being collected on ibuf and obuf.
828 * Write the message out onto some poorly-named temp file
829 * and point an editor at it.
831 * On return, make the edit file the new temp file.
835 mesedit(FILE *ibuf
, FILE *obuf
, int c
, struct header
*hp
)
842 void (*sigcont
)(int);
847 char *oto
, *osubject
, *occ
, *obcc
, **oothers
;
850 if (stat(tempEdit
, &sbuf
) >= 0) {
851 printf(gettext("%s: file exists\n"), tempEdit
);
854 if ((fd
= open(tempEdit
, O_RDWR
|O_CREAT
|O_EXCL
, 0600)) < 0 ||
855 (fbuf
= fdopen(fd
, "w")) == NULL
) {
861 puthead(hp
, fbuf
, GMASK
, 0);
862 while ((t
= getc(ibuf
)) != EOF
)
867 removefile(tempEdit
);
871 if ((edit
= value(c
== 'e' ? "EDITOR" : "VISUAL")) == NOSTR
||
873 edit
= c
== 'e' ? EDITOR
: VISUAL
;
874 edit
= safeexpand(edit
);
877 * Fork/execlp the editor on the edit file
881 if (pid
== (pid_t
)-1) {
883 removefile(tempEdit
);
891 execlp(edit
, edit
, tempEdit
, (char *)0);
893 * If execlp fails, "edit" might really be a complete
894 * shell command, not a simple pathname. Try using
895 * the shell to run it.
897 snprintf(ecmd
, sizeof (ecmd
), "exec %s %s", edit
, tempEdit
);
898 if ((Shell
= value("SHELL")) == NULL
|| *Shell
=='\0')
900 execlp(Shell
, Shell
, "-c", ecmd
, NULL
);
904 sigint
= sigset(SIGINT
, SIG_IGN
);
906 sigcont
= sigset(SIGCONT
, SIG_DFL
);
908 while (wait((int *)0) != pid
)
910 sigset(SIGINT
, sigint
);
912 sigset(SIGCONT
, sigcont
);
915 * Now switch to new file.
918 if ((fbuf
= fopen(tempEdit
, "r")) == NULL
) {
920 removefile(tempEdit
);
923 removefile(tempEdit
);
925 /* save the old headers, in case they are accidentally deleted */
926 osubject
= hp
->h_subject
;
930 oothers
= hp
->h_others
;
931 hp
->h_to
= hp
->h_subject
= hp
->h_cc
= hp
->h_bcc
= hp
->h_defopt
= NOSTR
;
932 hp
->h_others
= NOSTRPTR
;
934 while (gethfield(fbuf
, hdr
, 9999L) > 0) {
935 if (ishfield(hdr
, "to"))
936 hp
->h_to
= addto(hp
->h_to
, hcontents(hdr
));
937 else if (ishfield(hdr
, "subject"))
938 hp
->h_subject
= addone(hp
->h_subject
, hcontents(hdr
));
939 else if (ishfield(hdr
, "cc"))
940 hp
->h_cc
= addto(hp
->h_cc
, hcontents(hdr
));
941 else if (ishfield(hdr
, "bcc"))
942 hp
->h_bcc
= addto(hp
->h_bcc
, hcontents(hdr
));
943 else if (ishfield(hdr
, "default-options"))
944 hp
->h_defopt
= addone(hp
->h_defopt
, hcontents(hdr
));
946 hp
->h_others
= Xaddone(hp
->h_others
, hdr
);
949 if (hp
->h_seq
== 0) {
950 /* if we didn't see any headers, restore the original headers */
951 hp
->h_subject
= osubject
;
955 hp
->h_others
= oothers
;
957 "(Deleted headers restored to original values)\n"));
959 if ((fd
= open(tempMail
, O_RDWR
|O_CREAT
|O_EXCL
, 0600)) < 0 ||
960 (obuf
= fdopen(fd
, "w")) == NULL
) {
965 if ((ibuf
= fopen(tempMail
, "r")) == NULL
) {
967 removefile(tempMail
);
972 removefile(tempMail
);
973 if (strlen(hdr
) != 0) {
977 while ((t
= getc(fbuf
)) != EOF
)
989 * Pipe the message through the command.
990 * Old message is on stdin of command;
991 * New message collected from stdout.
992 * Sh -c must return 0 to accept the new message.
996 mespipe(FILE *ibuf
, FILE *obuf
, char cmd
[])
998 register FILE *ni
, *no
;
1001 void (*sigint
)(int);
1006 if ((fd
= open(tempEdit
, O_RDWR
|O_CREAT
|O_EXCL
, 0600)) < 0 ||
1007 (no
= fdopen(fd
, "w")) == NULL
) {
1011 if ((ni
= fopen(tempEdit
, "r")) == NULL
) {
1014 removefile(tempEdit
);
1017 removefile(tempEdit
);
1020 if ((Shell
= value("SHELL")) == NULL
|| *Shell
=='\0')
1022 if ((pid
= vfork()) == (pid_t
)-1) {
1028 * stdin = current message.
1029 * stdout = new message.
1037 for (s
= 4; s
< 15; s
++)
1039 execlp(Shell
, Shell
, "-c", cmd
, (char *)0);
1043 sigint
= sigset(SIGINT
, SIG_IGN
);
1044 while (wait(&s
) != pid
)
1046 sigset(SIGINT
, sigint
);
1047 if (s
!= 0 || pid
== (pid_t
)-1) {
1048 fprintf(stderr
, gettext("\"%s\" failed!?\n"), cmd
);
1051 if (fsize(ni
) == 0) {
1052 fprintf(stderr
, gettext("No bytes from \"%s\" !?\n"), cmd
);
1071 static char *indentprefix
; /* used instead of tab by tabputs */
1074 * Interpolate the named messages into the current
1075 * message, preceding each line with a tab.
1076 * Return a count of the number of characters now in
1077 * the message, or -1 if an error is encountered writing
1078 * the message temporary. The flag argument is 'm' if we
1079 * should shift over and 'f' if not.
1082 forward(char ms
[], FILE *obuf
, int f
)
1084 register int *msgvec
, *ip
;
1086 msgvec
= (int *) salloc((msgCount
+1) * sizeof *msgvec
);
1087 if (msgvec
== NOINTPTR
)
1089 if (getmsglist(ms
, msgvec
, 0) < 0)
1092 *msgvec
= first(0, MMNORM
);
1094 printf(gettext("No appropriate messages\n"));
1099 if (tolower(f
) == 'm')
1100 indentprefix
= value("indentprefix");
1101 printf(gettext("Interpolating:"));
1102 for (ip
= msgvec
; *ip
!= 0; ip
++) {
1105 if (msend(&message
[*ip
-1], obuf
, islower(f
) ? M_IGNORE
: 0,
1106 tolower(f
) == 'm' ? tabputs
: fputs
) < 0) {
1112 if (fferror(obuf
)) {
1121 tabputs(const char *line
, FILE *obuf
)
1125 fputs(indentprefix
, obuf
);
1126 /* Don't create lines with only a tab on them */
1127 else if (line
[0] != '\n')
1129 return (fputs(line
, obuf
));
1133 * Print (continue) when continued after ^Z.
1144 printf(gettext("(continue)\n"));
1147 #endif /* SIGCONT */
1150 * On interrupt, go here to save the partial
1151 * message on ~/dead.letter.
1152 * Then restore signals and execute the normal
1153 * signal routine. We only come here if signals
1154 * were previously set anyway.
1159 register FILE *dbuf
;
1160 register char *deadletter
;
1162 # ifdef OLD_BSD_SIGS
1166 if (s
== SIGINT
&& hadintr
== 0) {
1170 gettext("\n(Interrupt -- one more to kill letter)\n"));
1171 # ifdef OLD_BSD_SIGS
1178 if (s
== SIGINT
&& value("save")==NOSTR
|| fsize(newi
) == 0)
1180 deadletter
= Getf("DEAD");
1181 if ((dbuf
= fopen(deadletter
,
1182 (value("appenddeadletter") == NOSTR
? "w" : "a"))) == NULL
) {
1186 chmod(deadletter
, DEADPERM
);
1187 puthead(savehp
, dbuf
, GMASK
|GCLEN
, fsize(newi
));
1188 lcwrite(deadletter
, newi
, dbuf
, value("appenddeadletter") != NOSTR
);
1204 * Acknowledge an interrupt signal from the tty by typing an @
1221 /* Read line from stdin, noting any NULL characters.
1222 Return the number of characters read. Note that the buffer
1223 passed must be 1 larger than "size" for the trailing NUL byte.
1226 getaline(char *line
, int size
, FILE *f
, int *hasnulls
)
1229 for (i
= 0; (i
< size
) && ((ch
=getc(f
)) != EOF
); ) {
1232 if ((line
[i
++] = (char)ch
) == '\n') break;
1252 * Add a list of addresses to the end of a header entry field.
1255 addto(char hf
[], char news
[])
1257 char name
[LINESIZE
];
1258 int comma
= docomma(news
);
1260 while (news
= yankword(news
, name
, sizeof (name
), comma
)) {
1261 nstrcat(name
, sizeof (name
), ", ");
1262 hf
= addone(hf
, name
);
1268 * Add a string to the end of a header entry field.
1271 addone(char hf
[], char news
[])
1273 register char *cp
, *cp2
, *linebuf
;
1279 linebuf
= (char *)srealloc(hf
, (unsigned)(strlen(hf
) + strlen(news
) + 2));
1280 cp2
= strchr(linebuf
, '\0');
1281 if (cp2
> linebuf
&& cp2
[-1] != ' ')
1283 for (cp
= news
; any(*cp
, " \t"); cp
++)
1298 for (i
= 0; *hf
; hf
++)
1304 * Add a non-standard header to the end of the non-standard headers.
1307 Xaddone(char **hf
, char news
[])
1309 register char *linebuf
;
1311 int nhf
= nptrs(hf
);
1314 hf
= (char**)salloc(sizeof(char*) * 2);
1316 hf
= (char**)srealloc(hf
, sizeof(char*) * (nhf
+ 2));
1317 if (hf
== NOSTRPTR
) {
1318 fprintf(stderr
, gettext("No room, header lost: %s\n"), news
);
1321 linebuf
= (char *)salloc((unsigned)(strlen(news
) + 1));
1322 strcpy(linebuf
, news
);
1323 hf
[nhf
++] = linebuf
;
1329 cpout(char *str
, FILE *ofd
)
1331 register char *cp
= str
;
1361 sigset(SIGINT
, savesig
);
1362 sigset(SIGHUP
, savehup
);
1370 * Strip the nulls from a buffer of length n
1373 stripnulls(register char *linebuf
, register int nread
)
1377 for (i
= 0; i
< nread
; i
++)
1378 if (linebuf
[i
] == '\0')
1380 for (j
= i
; j
< nread
; j
++)
1381 if (linebuf
[j
] != '\0')
1382 linebuf
[i
++] = linebuf
[j
];