|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T s
Length: 8819 (0x2273)
Types: TextFile
Names: »syscall.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦4fd8323b9⟧ »EurOpenD3/mail/elm2.3.tar.Z«
└─⟦698c4f91f⟧
└─⟦this⟧ »src/syscall.c«
static char rcsid[] = "@(#)$Id: syscall.c,v 4.1 90/04/28 22:44:18 syd Exp $";
/*******************************************************************************
* The Elm Mail System - $Revision: 4.1 $ $State: Exp $
*
* Copyright (c) 1986, 1987 Dave Taylor
* Copyright (c) 1988, 1989, 1990 USENET Community Trust
*******************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Syd Weinstein, Elm Coordinator
* elm@DSI.COM dsinc!elm
*
*******************************************************************************
* $Log: syscall.c,v $
* Revision 4.1 90/04/28 22:44:18 syd
* checkin of Elm 2.3 as of Release PL0
*
*
******************************************************************************/
/** These routines are used for user-level system calls, including the
'!' command and the '|' commands...
**/
#include "headers.h"
#include <signal.h>
#ifdef BSD
# include <sys/wait.h>
#endif
char *argv_zero();
void _exit();
#ifdef ALLOW_SUBSHELL
int
subshell()
{
/** spawn a subshell with either the specified command
returns non-zero if screen rewrite needed
**/
char command[SLEN];
int old_raw, helpful, ret;
helpful = (user_level == 0);
if (helpful)
PutLine0(LINES-3,COLUMNS-40,"(Use the shell name for a shell.)");
PutLine0(LINES-2,0,"Shell command: ");
CleartoEOS();
command[0] = '\0';
(void) optionally_enter(command, LINES-2, 15, FALSE, FALSE);
if (command[0] == 0) {
if (helpful)
MoveCursor(LINES-3,COLUMNS-40);
else
MoveCursor(LINES-2,0);
CleartoEOS();
return 0;
}
MoveCursor(LINES,0);
CleartoEOLN();
if ((old_raw = RawState()) == ON)
Raw(OFF);
softkeys_off();
if (cursor_control)
transmit_functions(OFF);
umask(original_umask); /* restore original umask so users new files are ok */
ret = system_call(command, USER_SHELL, TRUE, TRUE);
umask(077); /* now put it back to private for mail files */
PutLine0(LINES, 0, "\n\nPress any key to return to ELM: ");
Raw(ON);
(void) getchar();
if (old_raw == OFF)
Raw(OFF);
softkeys_on();
if (cursor_control)
transmit_functions(ON);
if (ret)
error1("Return code was %d.", ret);
return 1;
}
#endif /* ALLOW_SUBSHELL */
system_call(string, shell_type, allow_signals, allow_interrupt)
char *string;
int shell_type, allow_signals, allow_interrupt;
{
/** execute 'string', setting uid to userid... **/
/** if shell-type is "SH" /bin/sh is used regardless of the
users shell setting. Otherwise, "USER_SHELL" is sent.
If allow_signals is TRUE, then allow the executed
command handle hangup, and optionally if allow_interrupt
is also true handle interrupt in its own way.
This is useful for executed programs with
user interaction that handle those signals on their
own terms. It is especially important for vi, so that
a message being edited when a user connection is
dropped is recovered by vi's expreserve program **/
int stat = 0, pid, w;
#if defined(BSD) && !defined(WEXITSTATUS)
union wait status;
#else
int status;
#endif
#ifdef VOIDSIG
register void (*istat)(), (*qstat)();
# ifdef SIGTSTP
register void (*oldstop)(), (*oldstart)();
# endif
#else
register int (*istat)(), (*qstat)();
# ifdef SIGTSTP
register int (*oldstop)(), (*oldstart)();
# endif
#endif
dprint(2, (debugfile,
"System Call: %s\n\t%s\n", shell_type == SH? "/bin/sh" : shell,
string));
#ifdef VFORK
if ((pid = vfork()) == 0)
#else
if ((pid = fork()) == 0)
#endif
{
setgid(groupid); /* and group id */
setuid(userid); /* back to the normal user! */
if(allow_signals) {
/* program to exec should handle interrupt, accidental hangup, and stop signals */
(void)signal(SIGHUP, SIG_DFL);
if (allow_interrupt)
(void)signal(SIGINT, SIG_DFL);
else
(void)signal(SIGINT, SIG_IGN);
#ifdef SIGTSTP
(void)signal(SIGTSTP, SIG_DFL);
(void)signal(SIGCONT, SIG_DFL);
#endif
} else {
/* program to exec should ignore interrupt, accidental hangup, and stop signals */
(void)signal(SIGHUP, SIG_IGN);
(void)signal(SIGINT, SIG_IGN);
#ifdef SIGTSTP
(void)signal(SIGTSTP, SIG_IGN);
(void)signal(SIGCONT, SIG_IGN);
#endif
}
if (strlen(shell) > 0 && shell_type == USER_SHELL) {
execl(shell, argv_zero(shell), "-c", string, (char *) 0);
}
else
execl("/bin/sh", "sh", "-c", string, (char *) 0);
_exit(127);
}
istat = signal(SIGINT, SIG_IGN);
qstat = signal(SIGQUIT, SIG_IGN);
#ifdef SIGTSTP
oldstop = signal(SIGTSTP, SIG_DFL);
oldstart = signal(SIGCONT, SIG_DFL);
#endif
while ((w = wait(&status)) != pid && w != -1)
;
if (w == pid) {
#ifdef WEXITSTATUS
stat = WEXITSTATUS(status);
#else
# ifdef BSD
if (status.w_retcode != 0) stat = status.w_retcode;
# else
stat = status;
# endif
#endif
}
(void)signal(SIGINT, istat);
(void)signal(SIGQUIT, qstat);
#ifdef SIGTSTP
(void)signal(SIGTSTP, oldstop);
(void)signal(SIGCONT, oldstart);
#endif
return(stat);
}
int
do_pipe()
{
/** pipe the current message or tagged messages to
the specified sequence.. **/
char command[SLEN], buffer[SLEN], message_list[SLEN];
register int ret, to_pipe;
int old_raw;
to_pipe = make_msg_list(message_list);
sprintf(buffer, "Pipe message%s to: ", plural(to_pipe));
PutLine0(LINES-2,0,buffer);
command[0] = '\0';
(void) optionally_enter(command, LINES-2, strlen(buffer), FALSE, FALSE);
if (strlen(command) == 0) {
MoveCursor(LINES-2,0); CleartoEOLN();
return(0);
}
MoveCursor(LINES,0); CleartoEOLN();
if (( old_raw = RawState()) == ON)
Raw(OFF);
if (cursor_control) transmit_functions(OFF);
sprintf(buffer, "%s -f %s -h %s | %s",
readmsg,
(folder_type == NON_SPOOL ? cur_folder : cur_tempfolder),
message_list,
command);
ret = system_call(buffer, USER_SHELL, TRUE, TRUE);
PutLine0(LINES, 0, "\n\nPress any key to return to ELM.");
if (old_raw == ON)
Raw(ON);
(void) getchar();
if (cursor_control) transmit_functions(ON);
if (ret != 0) error1("Return code was %d.", ret);
return(1);
}
print_msg()
{
/** Print current message or tagged messages using 'printout'
variable. Error message iff printout not defined! **/
char buffer[SLEN], filename[SLEN], printbuffer[SLEN];
char message_list[SLEN];
register int retcode, to_print;
if (strlen(printout) == 0) {
error("Don't know how to print - option \"printmail\" undefined!");
return;
}
to_print = make_msg_list(message_list);
sprintf(filename,"%s%s%d", temp_dir, temp_print, getpid());
if (in_string(printout, "%s"))
sprintf(printbuffer, printout, filename);
else
sprintf(printbuffer, "%s %s", printout, filename);
sprintf(buffer,"(%s -p -f %s%s > %s; %s 2>&1) > /dev/null",
readmsg,
(folder_type == NON_SPOOL ? cur_folder : cur_tempfolder),
message_list,
filename,
printbuffer);
dprint(2, (debugfile, "Printing system call...\n"));
Centerline(LINES, "Queuing...");
if ((retcode = system_call(buffer, SH, FALSE, FALSE)) == 0) {
sprintf(buffer, "Message%s queued up to print.", plural(to_print));
Centerline(LINES, buffer);
}
else
error1("Printout failed with return code %d.", retcode);
unlink(filename); /* remove da temp file! */
}
make_msg_list(message_list)
char *message_list;
{
/** make a list of the tagged or just the current, if none tagged.
check for overflow on messsage length
**/
int i, msgs_selected = 0;
*message_list = '\0'; /* start with an empty list */
for (i=0; i < message_count; i++)
if (headers[i]->status & TAGGED) {
if (strlen(message_list) + 6 >= SLEN) {
error1("Too many messages selected, messages from %d on not used", i);
return(msgs_selected);
}
sprintf(message_list, "%s %d", message_list,
headers[i]->index_number);
msgs_selected++;
}
if (! msgs_selected) {
sprintf(message_list," %d", headers[current-1]->index_number);
msgs_selected = 1;
}
return(msgs_selected);
}
list_folders(numlines, helpmsg)
unsigned numlines;
char *helpmsg;
{
/** list the folders in the users FOLDERHOME directory. This is
simply a call to "ls -C"
Numlines is the number of lines to scroll afterwards. This is
useful when a portion of the screen needs to be cleared for
subsequent prompts, but you don't want to overwrite the
list of folders.
Helpmsg is what should be printed before the listing if not NULL.
**/
char buffer[SLEN];
Raw(OFF);
ClearScreen();
MoveCursor(LINES, 0);
if(helpmsg)
printf(helpmsg);
sprintf(buffer, "cd %s;ls -C", folders);
printf("\n\rContents of your folder directory:\n\r\n\r");
system_call(buffer, SH, FALSE, FALSE);
while(numlines--)
printf("\n\r");
Raw(ON);
}