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

📄 system.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	return;    }    getstorage(where, length, 1);    memcpy(local, (char *)(storage+((where-storage_location))), length);    if (apitrace) {	Dump('(', local, length);    }}/*ARGSUSED*/voidmovetothem(es, di, local, length)unsigned int    es,    di;char    *local;int    length;{    long where = SEG_OFF_BACK(es, di);    if (length > sizeof storage) {	fprintf(stderr, "Internal API error - movetothem() length too long.\n");	fprintf(stderr, "(detected in file %s, line %d)\n", __FILE__, __LINE__);	quit();    } else if (length == 0) {	return;    }    freestorage();    memcpy((char *)storage, local, length);    if (apitrace) {	Dump(')', local, length);    }    storage_length = length;    storage_location = where;    storage_must_send = 1;}char *access_api(location, length, copyin)char *    location;int    length,    copyin;			/* Do we need to copy in initially? */{    if (storage_accessed) {	fprintf(stderr, "Internal error - storage accessed twice\n");	fprintf(stderr, "(Encountered in file %s, line %d.)\n",				__FILE__, __LINE__);	quit();    } else if (length != 0) {	freestorage();	getstorage((long)location, length, copyin);	storage_accessed = 1;    }    return (char *) storage;}/*ARGSUSED*/voidunaccess_api(location, local, length, copyout)char 	*location;char	*local;int	length;int	copyout;{    if (storage_accessed == 0) {	fprintf(stderr, "Internal error - unnecessary unaccess_api call.\n");	fprintf(stderr, "(Encountered in file %s, line %d.)\n",			__FILE__, __LINE__);	quit();    }    storage_accessed = 0;    storage_must_send = copyout;	/* if needs to go back */}/* * Accept a connection from an API client, aborting if the child dies. */static intdoconnect(){    fd_set fdset;    int i;    sock = -1;    FD_ZERO(&fdset);    while (shell_active && (sock == -1)) {	FD_SET(serversock, &fdset);	if ((i = select(serversock+1, &fdset,		    (fd_set *)0, (fd_set *)0, (struct timeval *)0)) < 0) {	    if (errno = EINTR) {		continue;	    } else {		perror("in select waiting for API connection");		return -1;	    }	} else {	    i = accept(serversock, (struct sockaddr *)0, (int *)0);	    if (i == -1) {		perror("accepting API connection");		return -1;	    }	    sock = i;	}    }    /* If the process has already exited, we may need to close */    if ((shell_active == 0) && (sock != -1)) {	extern void setcommandmode();	(void) close(sock);	sock = -1;	setcommandmode();	/* In case child_died sneaked in */    }    return 0;}/* * shell_continue() actually runs the command, and looks for API * requests coming back in. * * We are called from the main loop in telnet.c. */intshell_continue(){    int i;    switch (state) {    case DEAD:	pause();			/* Nothing to do */	break;    case UNCONNECTED:	if (doconnect() == -1) {	    kill_connection();	    return -1;	}	/* At this point, it is possible that we've gone away */	if (shell_active == 0) {	    kill_connection();	    return -1;	}	if (api_exch_init(sock, "server") == -1) {	    return -1;	}	while (state == UNCONNECTED) {	    if (api_exch_incommand(EXCH_CMD_ASSOCIATE) == -1) {		kill_connection();		return -1;	    } else {		switch (doassociate()) {		case -1:		    kill_connection();		    return -1;		case 0:		    break;		case 1:		    state = CONNECTED;		}	    }	}	break;    case CONNECTED:	switch (i = api_exch_nextcommand()) {	case EXCH_CMD_REQUEST:	    if (api_exch_intype(EXCH_TYPE_REGS, sizeof inputRegs,				    (char *)&inputRegs) == -1) {		kill_connection();	    } else if (api_exch_intype(EXCH_TYPE_SREGS, sizeof inputSregs,				    (char *)&inputSregs) == -1) {		kill_connection();	    } else if (nextstore() == -1) {		kill_connection();	    } else {		handle_api(&inputRegs, &inputSregs);		freestorage();			/* Send any storage back */		if (api_exch_outcommand(EXCH_CMD_REPLY) == -1) {		    kill_connection();		} else if (api_exch_outtype(EXCH_TYPE_REGS, sizeof inputRegs,				    (char *)&inputRegs) == -1) {		    kill_connection();		} else if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof inputSregs,				    (char *)&inputSregs) == -1) {		    kill_connection();		}		/* Done, and it all worked! */	    }	    break;	case EXCH_CMD_DISASSOCIATE:	    kill_connection();	    break;	default:	    if (i != -1) {		fprintf(stderr,			"Looking for a REQUEST or DISASSOCIATE command\n");		fprintf(stderr, "\treceived 0x%02x.\n", i);	    }	    kill_connection();	    break;	}    }    return shell_active;}static voidchild_died(code){    union wait status;    register int pid;    while ((pid = wait3((int *)&status, WNOHANG, (struct rusage *)0)) > 0) {	if (pid == shell_pid) {	    char inputbuffer[100];	    extern void setconnmode();	    extern void ConnectScreen();	    shell_active = 0;	    if (sock != -1) {		(void) close(sock);		sock = -1;	    }	    printf("[Hit return to continue]");	    fflush(stdout);	    (void) gets(inputbuffer);	    setconnmode();	    ConnectScreen();	/* Turn screen on (if need be) */	    (void) close(serversock);	    (void) unlink(keyname);	}    }    signal(SIGCHLD, child_died);}/* * Called from telnet.c to fork a lower command.com.  We * use the spint... routines so that we can pick up * interrupts generated by application programs. */intshell(argc,argv)int	argc;char	*argv[];{    int length;    struct sockaddr_in server;    char sockNAME[100];    static char **whereAPI = 0;    int fd;    struct timeval tv;    long ikey;    extern long random();    extern char *mktemp();    extern char *strcpy();    /* First, create verification file. */    do {	keyname = mktemp(strdup("/tmp/apiXXXXXX"));	fd = open(keyname, O_RDWR|O_CREAT|O_EXCL, IREAD|IWRITE);    } while ((fd == -1) && (errno == EEXIST));    if (fd == -1) {	perror("open");	return 0;    }    /* Now, get seed for random */    if (gettimeofday(&tv, (struct timezone *)0) == -1) {	perror("gettimeofday");	return 0;    }    srandom(tv.tv_usec);		/* seed random number generator */    do {	ikey = random();    } while (ikey == 0);    sprintf(key, "%lu\n", (unsigned long) ikey);    if (write(fd, key, strlen(key)) != strlen(key)) {	perror("write");	return 0;    }    key[strlen(key)-1] = 0;		/* Get rid of newline */    if (close(fd) == -1) {	perror("close");	return 0;    }    /* Next, create the socket which will be connected to */    serversock = socket(AF_INET, SOCK_STREAM, 0);    if (serversock < 0) {	perror("opening API socket");	return 0;    }    server.sin_family = AF_INET;    server.sin_addr.s_addr = INADDR_ANY;    server.sin_port = 0;    if (bind(serversock, (struct sockaddr *)&server, sizeof server) < 0) {	perror("binding API socket");	return 0;    }    length = sizeof server;    if (getsockname(serversock, (struct sockaddr *)&server, &length) < 0) {	perror("getting API socket name");	(void) close(serversock);    }    listen(serversock, 1);    /* Get name to advertise in address list */    strcpy(sockNAME, "API3270=");    gethostname(sockNAME+strlen(sockNAME), sizeof sockNAME-strlen(sockNAME));    if (strlen(sockNAME) > (sizeof sockNAME-(10+strlen(keyname)))) {	fprintf(stderr, "Local hostname too large; using 'localhost'.\n");	strcpy(sockNAME, "localhost");    }    sprintf(sockNAME+strlen(sockNAME), ":%u", ntohs(server.sin_port));    sprintf(sockNAME+strlen(sockNAME), ":%s", keyname);    if (whereAPI == 0) {	char **ptr, **nextenv;	extern char **environ;	ptr = environ;	nextenv = ourENVlist;	while (*ptr) {	    if (nextenv >= &ourENVlist[highestof(ourENVlist)-1]) {		fprintf(stderr, "Too many environmental variables\n");		break;	    }	    *nextenv++ = *ptr++;	}	whereAPI = nextenv++;	*nextenv++ = 0;	environ = ourENVlist;		/* New environment */    }    *whereAPI = sockNAME;    child_died();			/* Start up signal handler */    shell_active = 1;			/* We are running down below */    if (shell_pid = vfork()) {	if (shell_pid == -1) {	    perror("vfork");	    (void) close(serversock);	} else {	    state = UNCONNECTED;	}    } else {				/* New process */	register int i;	for (i = 3; i < 30; i++) {	    (void) close(i);	}	if (argc == 1) {		/* Just get a shell */	    char *cmdname;	    extern char *getenv();	    cmdname = getenv("SHELL");	    execlp(cmdname, cmdname, 0);	    perror("Exec'ing new shell...\n");	    exit(1);	} else {	    execvp(argv[1], &argv[1]);	    perror("Exec'ing command.\n");	    exit(1);	}	/*NOTREACHED*/    }    return shell_active;		/* Go back to main loop */}

⌨️ 快捷键说明

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