|
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); }