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

📄 session.c

📁 嵌入式TCP/IP协议栈。 C 源码
💻 C
字号:
/* NOS User Session control
 */
#include <stdio.h>
#include "global.h"
#include "mbuf.h"
#include "proc.h"
#include "ftpcli.h"
#include "icmp.h"
#include "telnet.h"
#include "tty.h"
#include "session.h"
#include "hardware.h"
#include "socket.h"
#include "cmdparse.h"
#include "commands.h"
#include "main.h"

struct session **Sessions;
struct session *Command;
struct session *Current;
struct session *Lastcurr;
char Notval[] = "Not a valid control block\n";
static char Badsess[] = "Invalid session\n";
char *Sestypes[] = {
	"",
	"Telnet",
	"FTP",
	"AX25",
	"Finger",
	"Ping",
	"NET/ROM",
	"Command",
	"More",
	"Hopcheck",
	"Tip",
	"PPP PAP",
	"Dial",
	"Query",
	"Cache",
	"Trace",
	"Repeat",
};

/* Convert a character string containing a decimal session index number
 * into a pointer. If the arg is NULL, use the current default session.
 * If the index is out of range or unused, return NULL.
 */
struct session *
sessptr(cp)
char *cp;
{
	unsigned int i;

	if(cp == NULL)
		return Lastcurr;

	i = (unsigned)atoi(cp);
	if(i >= Nsessions)
		return NULL;
	else
		return Sessions[i];
}

/* Select and display sessions */
int
dosession(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	struct session *sp;
	struct sockaddr fsocket;
	int i,k,s,ses;
	int t;
	char *cp;

	sp = (struct session *)p;

	if(argc > 1){
		if((sp = sessptr(argv[1])) != NULL){
			go(0,NULL,sp);
		} else
			printf("Session %s not active\n",argv[1]);
		return 0;
	}
	printf(" #  S#  Snd-Q State     Remote socket         Command\n");
	for(ses=0;ses<Nsessions;ses++){
		sp = Sessions[ses];
		if(sp == NULL || sp->type == COMMAND)
			continue;

		t = 0;
		cp = NULL;
		if(sp->network != NULL && (s = fileno(sp->network)) != -1){
			i = SOCKSIZE;
			k = getpeername(s,&fsocket,&i);
			t += socklen(s,1);
			cp = sockstate(s);
		} else {
			k = s = -1;
			t = 0;
			cp = NULL;
		}
		printf("%c", (Lastcurr == sp)? '*':' ');
		printf("%-3u",sp->index);
		printf("%-4d%5d %-10s",s,t,(cp != NULL) ? cp : "");
		printf("%-22s",(k == 0) ? psocket(&fsocket) : "");
		if(sp->name != NULL)
			printf("%s",sp->name);
		printf("\n");

		/* Display FTP data channel, if any */
		if(sp->type == FTP && (s = fileno(sp->cb.ftp->data)) != -1){
			i = SOCKSIZE;
			k = getpeername(s,&fsocket,&i);
			t += socklen(s,1);
			cp = sockstate(s);
			printf("    %-4d%5d %-10s",s,t,(cp != NULL) ? cp : "");
			printf("%-22s\n",(k == 0) ? psocket(&fsocket) : "");
		}
		if(sp->record != NULL)
			printf("    Record: %s\n",fpname(sp->record));
		if(sp->upload != NULL)
			printf("    Upload: %s\n",fpname(sp->upload));
	}
	return 0;
}
/* Resume current session, and wait for it */
int
go(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	struct session *sp;

	sp = (struct session *)p;
	if(sp == NULL || sp->type == COMMAND)
		return 0;
	if(Current != Command)
		Lastcurr = Current;
	Current = sp;
	alert(Display,1);
	return 0;
}
int
doclose(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	struct session *sp;

	sp = (struct session *)p;
	if(argc > 1)
		sp = sessptr(argv[1]);

	if(sp == NULL){
		printf(Badsess);
		return -1;
	}
	shutdown(fileno(sp->network),1);
	return 0;
}
int
doreset(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	struct session *sp;

	sp = (struct session *)p;
	if(argc > 1)
		sp = sessptr(argv[1]);

	if(sp == NULL){
		printf(Badsess);
		return -1;
	}
	/* Unwedge anyone waiting for a domain resolution, etc */
	alert(sp->proc,EABORT);
	shutdown(fileno(sp->network),2);
	if(sp->type == FTP)
		shutdown(fileno(sp->cb.ftp->data),2);
	return 0;
}
int
dokick(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	struct session *sp;

	sp = (struct session *)p;
	if(argc > 1)
		sp = sessptr(argv[1]);

	if(sp == NULL){
		printf(Badsess);
		return -1;
	}
	sockkick(fileno(sp->network));
	if(sp->type == FTP)
		sockkick(fileno(sp->cb.ftp->data));
	return 0;
}

int
dosfsize(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	return setlong(&Sfsize,"Scroll file size",argc,argv);	
}

struct session *
newsession(name,type,makecur)
char *name;
int type;
int makecur;
{
	register struct session *sp;
	int i;

	/* Search for a free slot in the session table */
	for(i=0;i < Nsessions;i++)
		if(Sessions[i] == NULL)
			break;
	if(i == Nsessions)
		return NULL;	/* All full */

	sp = Sessions[i] = (struct session *)calloc(1,sizeof(struct session));
	sp->index = i;
	sp->type = type;
	if(name != NULL)
		sp->name = strdup(name);
	sp->proc = Curproc;
	/* Create standard input and output sockets. Output is
	 * in text mode by default
	 */
	fclose(stdin);
	stdin =  sp->input = pipeopen();
	setvbuf(stdin,NULL,_IONBF,0);
	fclose(stdout);
	stdout = sp->output = displayopen("wt",0,Sfsize);

	/* on by default */
	sp->ttystate.crnl = sp->ttystate.edit = sp->ttystate.echo = 1;
	sp->parent = Current;
	if(makecur){
		Current = sp;
		alert(Display,1);
	}
	return sp;
}
void
freesession(sp)
struct session *sp;
{
	int i;

	if(sp == NULL || sp != Sessions[sp->index])
		return;	/* Not on session list */
	kwait(NULL);	/* Wait for any pending output to go */

	for(i=0;i<Nsessions;i++){
		if(Sessions[i]->parent == sp)
			Sessions[i]->parent = sp->parent;
	}
	Sessions[sp->index] = NULL;
	if(sp->proc1 != NULL)
		killproc(sp->proc1);
	if(sp->proc2 != NULL)
		killproc(sp->proc2);

	free(sp->ttystate.line);
	if(sp->network != NULL)
		fclose(sp->network);

	if(sp->record != NULL)
		fclose(sp->record);

	if(sp->upload != NULL)
		fclose(sp->upload);

	free(sp->name);

	if(Lastcurr == sp)
		Lastcurr = sp->parent;
	if(Current == sp){
		Current = sp->parent;
		alert(Display,1);
	}
	free(sp);
}
/* Control session recording */
int
dorecord(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	struct session *sp;
	char *mode;

	sp = (struct session *)p;
	if(sp == NULL){
		printf("No current session\n");
		return 1;
	}
	if(argc > 1){
		if(sp->record != NULL){
			fclose(sp->record);
			sp->record = NULL;
		}
		/* Open new record file, unless file name is "off", which means
		 * disable recording
		 */
		if(strcmp(argv[1],"off") != 0){
			if(fmode(sp->output,-1) == STREAM_ASCII)
				mode = APPEND_TEXT;
			else
				mode = APPEND_BINARY;

			if((sp->record = fopen(argv[1],mode)) == NULL)
				printf("Can't open %s: %s\n",argv[1],sys_errlist[errno]);
		}
	}
	if(sp->record != NULL)
		printf("Recording into %s\n",fpname(sp->record));
	else
		printf("Recording off\n");
	return 0;
}
/* Control file transmission */
int
doupload(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	register struct session *sp;

	sp = (struct session *)p;
	if(sp == NULL){
		printf("No current session\n");
		return 1;
	}
	if(argc < 2){
		if(sp->upload != NULL)
			printf("Uploading %s\n",fpname(sp->upload));
		else
			printf("Uploading off\n");
		return 0;
	}
	if(strcmp(argv[1],"stop") == 0 && sp->upload != NULL){
		/* Abort upload */
		fclose(sp->upload);
		sp->upload = NULL;
		killproc(sp->proc2);
		sp->proc2 = NULL;
		return 0;
	}
	/* Open upload file */
	if((sp->upload = fopen(argv[1],READ_TEXT)) == NULL){
		printf("Can't read %s: %s\n",argv[1],sys_errlist[errno]);
		return 1;
	}
	/* All set, invoke the upload process */
	sp->proc2 = newproc("upload",1024,upload,0,sp,NULL,0);
	return 0;
}
/* File uploading task */
void
upload(unused,sp1,p)
int unused;
void *sp1;
void *p;
{
	struct session *sp;
	char *buf;

	sp = (struct session *)sp1;

	buf = mallocw(BUFSIZ);
	while(fgets(buf,BUFSIZ,sp->upload) != NULL)
		if(fputs(buf,sp->network) == EOF)
			break;

	free(buf);
	fflush(sp->network);
	fclose(sp->upload);
	sp->upload = NULL;
	sp->proc2 = NULL;
}

/* Print prompt and read one character */
int
keywait(prompt,flush)
char *prompt;	/* Optional prompt */
int flush;	/* Flush queued input? */
{
	int c;
	int i;

	if(prompt == NULL)
		prompt = "Hit enter to continue"; 
	printf(prompt);
	fflush(stdout);
	c = _fgetc(stdin);
	/* Get rid of the prompt */
	for(i=strlen(prompt);i != 0;i--)
		putchar('\b');
	for(i=strlen(prompt);i != 0;i--)
		putchar(' ');
	for(i=strlen(prompt);i != 0;i--)
		putchar('\b');
	fflush(stdout);
	return (int)c;
}

/* Flush the current session's standard output. Called on every clock tick */
void
sesflush()
{
	if(Current != NULL)
		fflush(Current->output);
}

⌨️ 快捷键说明

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