* Copyright (c) 1980 Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)fio.c 5.24 (Berkeley) 2/3/91";
* Set up the input pointers while copying the mail file into /tmp.
/* Get temporary file. */
(void)sprintf(linebuf
, "%s/mail.XXXXXX", _PATH_TMP
);
if ((c
= mkstemp(linebuf
)) == -1 ||
(mestmp
= Fdopen(c
, "r+")) == NULL
) {
(void)fprintf(stderr
, "mail: can't open %s\n", linebuf
);
this.m_flag
= MUSED
|MNEW
;
if (fgets(linebuf
, LINESIZE
, ibuf
) == NULL
) {
if (append(&this, mestmp
)) {
perror("temporary file");
(void) fwrite(linebuf
, sizeof *linebuf
, count
, otf
);
if (maybe
&& linebuf
[0] == 'F' && ishead(linebuf
)) {
if (append(&this, mestmp
)) {
perror("temporary file");
this.m_flag
= MUSED
|MNEW
;
this.m_block
= blockof(offset
);
this.m_offset
= offsetof(offset
);
} else if (linebuf
[0] == 0) {
for (cp
= linebuf
, cp2
= "status";; cp
++) {
if (*cp
!= c
&& *cp
!= toupper(c
))
* Drop the passed line onto the passed output buffer.
* If a write error occurs, return -1, else the count of
* characters written, including the newline.
(void) fwrite(linebuf
, sizeof *linebuf
, c
, obuf
);
* Read up a line from the specified input into the line
* buffer. Return the number of characters read. Do not
* include the newline at the end.
readline(ibuf
, linebuf
, linesize
)
if (fgets(linebuf
, linesize
, ibuf
) == NULL
)
if (n
> 0 && linebuf
[n
- 1] == '\n')
* Return a file buffer all ready to read up the
* passed message pointer.
register struct message
*mp
;
if (fseek(itf
, positionof(mp
->m_block
, mp
->m_offset
), 0) < 0) {
panic("temporary file seek");
* Take the data out of the passed ghost file and toss it into
* a dynamically allocated message structure.
register size
= (msgCount
+ 1) * sizeof (struct message
);
if ((message
= (struct message
*) malloc((unsigned) size
)) == 0)
panic("Insufficient memory for %d messages", msgCount
);
size
-= sizeof (struct message
);
(void) lseek(fileno(f
), (long) sizeof *message
, 0);
if (read(fileno(f
), (char *) message
, size
) != size
)
panic("Message temporary file corrupted");
message
[msgCount
].m_size
= 0;
message
[msgCount
].m_lines
= 0;
* Append the passed message descriptor onto the temp file.
* If the write fails, return 1, else 0
return fwrite((char *) mp
, sizeof *mp
, 1, f
) != 1;
* Delete a file, but only if the file is a plain file.
if (!S_ISREG(sb
.st_mode
)) {
static int sigdepth
; /* depth of holdsigs() */
* Hold signals SIGHUP, SIGINT, and SIGQUIT.
omask
= sigblock(sigmask(SIGHUP
)|sigmask(SIGINT
)|sigmask(SIGQUIT
));
* Release signals SIGHUP, SIGINT, and SIGQUIT.
* Determine the size of the file possessed by
if (fstat(fileno(iob
), &sbuf
) < 0)
* Evaluate the string given as a new mailbox name.
* Supported meta characters:
* % for my system mail box
* %user for user's system mail box
* +file file in folder directory
* any shell meta character
* Return the file name as a dynamic string.
char cmdbuf
[PATHSIZE
]; /* also used for file names */
register char *cp
, *shell
;
extern union wait wait_status
;
* The order of evaluation is "%" and "#" expand into constants.
* "&" can expand into "+". "+" can expand into shell meta characters.
* Shell meta characters expand into constants.
* This way, we make no recursive expansion.
findmail(name
[1] ? name
+ 1 : myname
, xname
);
printf("No previous file\n");
return savestr(prevfile
);
if (name
[1] == 0 && (name
= value("MBOX")) == NOSTR
)
if (name
[0] == '+' && getfold(cmdbuf
) >= 0) {
sprintf(xname
, "%s/%s", cmdbuf
, name
+ 1);
/* catch the most common shell meta character */
if (name
[0] == '~' && (name
[1] == '/' || name
[1] == '\0')) {
sprintf(xname
, "%s%s", homedir
, name
+ 1);
if (!anyof(name
, "~{[*?$`'\"\\"))
sprintf(cmdbuf
, "echo %s", name
);
if ((shell
= value("SHELL")) == NOSTR
)
pid
= start_command(shell
, 0, -1, pivec
[1], "-c", cmdbuf
, NOSTR
);
l
= read(pivec
[0], xname
, BUFSIZ
);
if (wait_child(pid
) < 0 && wait_status
.w_termsig
!= SIGPIPE
) {
fprintf(stderr
, "\"%s\": Expansion failed.\n", name
);
fprintf(stderr
, "\"%s\": No match.\n", name
);
fprintf(stderr
, "\"%s\": Expansion buffer overflow.\n", name
);
for (cp
= &xname
[l
-1]; *cp
== '\n' && cp
> xname
; cp
--)
if (index(xname
, ' ') && stat(xname
, &sbuf
) < 0) {
fprintf(stderr
, "\"%s\": Ambiguous.\n", name
);
* Determine the current folder directory name.
if ((folder
= value("folder")) == NOSTR
)
sprintf(name
, "%s/%s", homedir
, folder
);
* Return the name of the dead.letter file.
if ((cp
= value("DEAD")) == NOSTR
|| (cp
= expand(cp
)) == NOSTR
)
cp
= expand("~/dead.letter");
(void) sprintf(buf
, "~/%s", cp
);