⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd_rexd.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		if (ioctl(OutputSocket, SIOCATMARK, &atmark) < 0) {			perror("ioctl");			break;		}		if (atmark)			break;		(void) read(OutputSocket, waste, sizeof (waste));	}	(void) recv(OutputSocket, &mark, 1, MSG_OOB);}/* * rex_wait - wait for command to finish, unmount the file system, * and return the exit status. * message gets an optional string error message. */rex_wait(message)	char **message;{	static char error[1024];	int count;	*message = error;	strcpy("",error);	if (child == 0) {		errprintf(error,"No process to wait for!\n");		rex_cleanup();		return (1);	}	kill(child, SIGHUP);	for (count=0;!ChildDied && count<WaitLimit;count++)		sleep(1);	if (ChildStatus & 0xFF)		return (ChildStatus);	return (ChildStatus >> 8);}/* * cleanup - unmount and remove our temporary directory */rex_cleanup(){	if (tmpdir) {		if (child && !ChildDied) {		    fprintf(stderr,		    "sd_rexd: child killed to unmount %s\r\n", nfsdir);		    kill(child, SIGKILL);		}		chdir("/");		if (nfsdir[0] && umount_nfs(nfsdir, tmpdir))			fprintf(stderr,				 "sd_rexd: couldn't umount %s from %s\r\n", 				   nfsdir, tmpdir);		if (rmdir(tmpdir) < 0)		   if (errno != EBUSY) perror("rmdir");		tmpdir = NULL;	}      if (HasHelper) KillHelper(child);      HasHelper = 0;}/* * This function does the server work to get a command executed * Returns 0 if OK, nonzero if error */rex_start(rst, ucred, message, sock)	struct rex_start *rst;	struct authunix_parms *ucred;	char **message;	int sock;{	char *index(), *mktemp();	char hostname[255];	char *p, *wdhost, *fsname, *subdir;	char dirbuf[1024];	static char error[1024];	char defaultShell[1024];	/* command executed if none given */	char defaultDir[1024];		/* directory used if none given */	struct sockaddr_in sin;	int len;	int fd0, fd1, fd2;	extern char **environ;	int icount = 0;	if (child) {	/* already started */		killpg(child, SIGKILL);		return (1);	}	*message = error;	(void) strcpy(error, "");	signal(SIGCHLD, CatchChild);	if (ValidUser(ucred->aup_machname, ucred->aup_uid,error,				defaultShell, defaultDir, rst->rst_cmd[0]))		return(1);	if (rst->rst_fsname && strlen(rst->rst_fsname)) {		fsname = rst->rst_fsname;		subdir = rst->rst_dirwithin;		wdhost = rst->rst_host;	} else {		fsname = defaultDir;		subdir = "";		wdhost = hostname;	}			gethostname(hostname, 255);	if (strcmp(wdhost, hostname) == 0) {		  /*		   * The requested directory is local to our machine,		   * so just change to it.		   */		strcpy(dirbuf,fsname);	} else {		static char wanted[1024];		static char mountedon[1024];		strcpy(wanted,wdhost);		strcat(wanted,":");		strcat(wanted,fsname);		if (AlreadyMounted(wanted,mountedon)) {		  /*		   * The requested directory is already mounted.  If the		   * mount is not by another rexd, just change to it. 		   * Otherwise, mount it again.  If just changeing to		   * the mounted directy, be careful. It might be mounted 		   * in a different place.		   * (dirbuf is modified in place!)		   */		  if (strncmp(mountedon, TempName, TempMatch) == 0) {		    /* */		    tmpdir = mktemp (TempName);		    if (mkdir (tmpdir, 0777)) {		      perror (tmpdir);		      audit_note (2, tmpdir);		      return (1);		    }		    strcpy(nfsdir, wanted);		    if (mount_nfs (wanted, tmpdir, error)) {		      audit_note (1,error);		      return (1);		    }		    strcpy (dirbuf, tmpdir);		  } else		    strcpy(dirbuf, mountedon);		}		else {		  /*		   * The requested directory is not mounted anywhere,		   * so try to mount our own copy of it.  We set nfsdir		   * so that it gets unmounted later, and tmpdir so that		   * it also gets removed when we are done.		   */			tmpdir = mktemp(TempName);			if (mkdir(tmpdir, 0777)) {				perror(tmpdir);				audit_note(1, tmpdir );				return(1);			}			strcpy(nfsdir, wanted);			if (mount_nfs(wanted, tmpdir, error)) {				audit_note(1, error);				return(1);			}			strcpy(dirbuf, tmpdir);		}	}	  /*	   * "dirbuf" now contains the local mount point, so just tack on	   * the subdirectory to get the pathname to which we "chdir"	   */	strcat(dirbuf, subdir);	len = sizeof sin;	if (getpeername(sock, &sin, &len)) {		perror("getpeername");		audit_note(1, "getpeername" );		return(1);	}	fd0 = socket(AF_INET, SOCK_STREAM, 0);	fd0 = doconnect(&sin, rst->rst_port0,fd0);	OutputSocket = fd0;	   /*	    * Arrange for fd0 to send the SIGURG signal when out-of-band data	    * arrives, which indicates that we should send the stopped child a	    * SIGCONT signal so that we can resume work.	    */	(void) fcntl(fd0, F_SETOWN, getpid());	signal(SIGURG, oob);	if (rst->rst_port0 == rst->rst_port1) {	  /*	   * use the same connection for both stdin and stdout	   */		fd1 = fd0;	}	if (rst->rst_flags & REX_INTERACTIVE) {	  /*	   * allocate a pseudo-terminal if necessary	   */	   if (AllocatePtyMaster(fd0,fd1)) {	   	errprintf(error,"sd_rexd: cannot allocate a pty\n");		audit_note(1, error);		return (1);	   }	   HasHelper = 1;	}	child = fork();	if (child < 0) {		errprintf(error, "sd_rexd: can't fork\n");		audit_note(1, error);		return (1);	}	if (child) {	    /*	     * parent sd_rexd: close network connections if needed,	     * then return to the main loop.	     */		if ((rst->rst_flags & REX_INTERACTIVE)==0) {			close(fd0);			close(fd1);		}		return (0);	}	/* child rexd */	if (rst->rst_flags & REX_INTERACTIVE)	  AllocatePtySlave();	if (rst->rst_port0 != rst->rst_port1) {		fd1 = socket(AF_INET, SOCK_STREAM, 0);		shutdown(fd0, 1);		fd1 = doconnect(&sin, rst->rst_port1,fd1);		shutdown(fd1, 0);	}	if (rst->rst_port1 == rst->rst_port2) {	  /*	   * Use the same connection for both stdout and stderr	   */		fd2 = fd1;	} else {		fd2 = socket(AF_INET, SOCK_STREAM, 0);		fd2 = doconnect(&sin, rst->rst_port2,fd2);		shutdown(fd2, 0);	}	if (rst->rst_flags & REX_INTERACTIVE) {	  /*	   * use ptys instead of sockets in interactive mode	   */	   DoHelper(&fd0, &fd1, &fd2);	}	dup2(fd0, 0);	dup2(fd1, 1);	dup2(fd2, 2);	for (fd0 = 3; fd0 < getdtablesize(); fd0++)		close(fd0);	environ = rst->rst_env;	setgid(ucred->aup_gid);	setgroups(ucred->aup_len,ucred->aup_gids);	/*	 * write audit record before making uid switch  	 */	audit_note(0, "successful"); 	setuid(ucred->aup_uid);	if (debug) {		printf("ucred->aup_machname = %s\n", ucred->aup_machname);		printf("ucred->aup_uid = %d\n", ucred->aup_uid);		printf("ucred->aup_gid = %d\n", ucred->aup_gid);	}	if (chdir(dirbuf)) {		perror("rex_start");	  	fprintf(stderr, "sd_rexd: can't chdir to %s\n", dirbuf);		exit(1);	}	signal( SIGINT, SIG_DFL);	signal( SIGHUP, SIG_DFL);	signal( SIGQUIT, SIG_DFL);	if (rst->rst_cmd[0]==NULL) {	  /*	   * Null command means execute the default shell for this user	   */	    char *args[2];	    args[0] = defaultShell;	    args[1] = NULL;	    execvp(defaultShell, args);	    fprintf(stderr, "sd_rexd: can't exec shell %s\n", defaultShell);	    exit(1);	}	if (debug) {		printf("command line:  ");		icount = 0;		while (rst->rst_cmd[icount] != NULL) {			printf("%s ", rst->rst_cmd[icount]);			icount++;		}		printf("\n");	}	execvp(rst->rst_cmd[0], rst->rst_cmd);	perror("sd_rexd: rex_start:");	fprintf(stderr, "sd_rexd: can't exec %s\n", rst->rst_cmd[0]);	exit(1);}AlreadyMounted(fsname, mountedon)    char *fsname;    char *mountedon;{  /*   * Search the mount table to see if the given file system is already   * mounted.  If so, return the place that it is mounted on.   */   FILE *table;   register struct mntent *mt;   table = setmntent(MOUNTED,"r");   if (debug)	printf("MOUNTED = %s; fsname = %s; mountedon = %s\n",		MOUNTED, fsname, mountedon);   if (table == NULL)     return (0);   while ( (mt = getmntent(table)) != NULL) {   	if (strcmp(mt->mnt_fsname,fsname) == 0) {	    if (debug)		printf("mt->mnt_fsname = %s; mt->mnt_dir = %s\n",			mt->mnt_fsname, mt->mnt_dir);	    strcpy(mountedon,mt->mnt_dir);	    endmntent(table);	    return(1);	}   }   endmntent(table);   return(0);}/* * connect to the indicated IP address/port, and return the  * resulting file descriptor.   */doconnect(sin, port, fd)	struct sockaddr_in *sin;	short port;	int fd;{	sin->sin_port = ntohs(port);	if (connect(fd, sin, sizeof *sin)) {		perror("sd_rexd: connect");		exit(1);	}	return (fd);}/**  SETPROCTITLE -- set the title of this process for "ps"**	Does nothing if there were not enough arguments on the command* 	line for the information.**	Side Effects:*		Clobbers argv[] of our main procedure.*/setproctitle(user, host)	char *user, *host;{	register char *tohere;	tohere = Argv[0];	if (LastArgv == NULL || 	    strlen(user)+strlen(host)+3 > (LastArgv - tohere))		return;	*tohere++ = '-';	/* So ps prints (rpc.rexd) */	sprintf(tohere, "%s@%s", user, host);	while (*tohere++) ;		/* Skip to end of printf output */	while (tohere < LastArgv) *tohere++ = ' ';  /* Avoid confusing ps */}/* * Determine if a descriptor belongs to a socket or not  */issock(fd)	int fd;{	struct stat st;	if (fstat(fd, &st) < 0) {		return (0);	}	/*	 * SunOS returns S_IFIFO for sockets, while 4.3 returns 0 and does not	 * even have an S_IFIFO mode.  Since there is confusion about what the	 * mode is, we check for what it is not instead of what it is. 	 */	switch (st.st_mode & S_IFMT) {	case S_IFCHR:	case S_IFREG:	case S_IFLNK:	case S_IFDIR:	case S_IFBLK:		return (0);	default:		return (1);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -