DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T s

⟦d0ea53351⟧ TextFile

    Length: 8819 (0x2273)
    Types: TextFile
    Names: »syscall.c«

Derivation

└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
    └─⟦4fd8323b9⟧ »EurOpenD3/mail/elm2.3.tar.Z« 
        └─⟦698c4f91f⟧ 
            └─⟦this⟧ »src/syscall.c« 

TextFile


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