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

📄 sshnet.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * SSH network file system. * Presents remote TCP stack as /net-style file system. */#include "ssh.h"#include <bio.h>#include <ndb.h>#include <thread.h>#include <fcall.h>#include <9p.h>int rawhack = 1;Conn *conn;char *remoteip	= "<remote>";char *mtpt;Cipher *allcipher[] = {	&cipherrc4,	&cipherblowfish,	&cipher3des,	&cipherdes,	&ciphernone,	&ciphertwiddle,};Auth *allauth[] = {	&authpassword,	&authrsa,	&authtis,};char *cipherlist = "rc4 3des";char *authlist = "rsa password tis";Cipher*findcipher(char *name, Cipher **list, int nlist){	int i;	for(i=0; i<nlist; i++)		if(strcmp(name, list[i]->name) == 0)			return list[i];	error("unknown cipher %s", name);	return nil;}Auth*findauth(char *name, Auth **list, int nlist){	int i;	for(i=0; i<nlist; i++)		if(strcmp(name, list[i]->name) == 0)			return list[i];	error("unknown auth %s", name);	return nil;}voidusage(void){	fprint(2, "usage: sshnet [-A authlist] [-c cipherlist] [-m mtpt] [user@]hostname\n");	exits("usage");}intisatty(int fd){	char buf[64];	buf[0] = '\0';	fd2path(fd, buf, sizeof buf);	if(strlen(buf)>=9 && strcmp(buf+strlen(buf)-9, "/dev/cons")==0)		return 1;	return 0;}enum{	Qroot,	Qcs,	Qtcp,	Qclone,	Qn,	Qctl,	Qdata,	Qlocal,	Qremote,	Qstatus,};#define PATH(type, n)		((type)|((n)<<8))#define TYPE(path)			((int)(path) & 0xFF)#define NUM(path)			((uint)(path)>>8)Channel *sshmsgchan;		/* chan(Msg*) */Channel *fsreqchan;			/* chan(Req*) */Channel *fsreqwaitchan;		/* chan(nil) */Channel *fsclunkchan;		/* chan(Fid*) */Channel *fsclunkwaitchan;	/* chan(nil) */ulong time0;enum{	Closed,	Dialing,	Established,	Teardown,};char *statestr[] = {	"Closed",	"Dialing",	"Established",	"Teardown",};typedef struct Client Client;struct Client{	int ref;	int state;	int num;	int servernum;	char *connect;	Req *rq;	Req **erq;	Msg *mq;	Msg **emq;};int nclient;Client **client;intnewclient(void){	int i;	Client *c;	for(i=0; i<nclient; i++)		if(client[i]->ref==0 && client[i]->state == Closed)			return i;	if(nclient%16 == 0)		client = erealloc9p(client, (nclient+16)*sizeof(client[0]));	c = emalloc9p(sizeof(Client));	memset(c, 0, sizeof(*c));	c->num = nclient;	client[nclient++] = c;	return c->num;}voidqueuereq(Client *c, Req *r){	if(c->rq==nil)		c->erq = &c->rq;	*c->erq = r;	r->aux = nil;	c->erq = (Req**)&r->aux;}voidqueuemsg(Client *c, Msg *m){	if(c->mq==nil)		c->emq = &c->mq;	*c->emq = m;	m->link = nil;	c->emq = (Msg**)&m->link;}voidmatchmsgs(Client *c){	Req *r;	Msg *m;	int n, rm;	while(c->rq && c->mq){		r = c->rq;		c->rq = r->aux;		rm = 0;		m = c->mq;		n = r->ifcall.count;		if(n >= m->ep - m->rp){			n = m->ep - m->rp;			c->mq = m->link;			rm = 1;		}		memmove(r->ofcall.data, m->rp, n);		if(rm)			free(m);		else			m->rp += n;		r->ofcall.count = n;		respond(r, nil);	}}Req*findreq(Client *c, Req *r){	Req **l;	for(l=&c->rq; *l; l=(Req**)&(*l)->aux){		if(*l == r){			*l = r->aux;			if(*l == nil)				c->erq = l;			return r;		}	}	return nil;}voiddialedclient(Client *c){	Req *r;	if(r=c->rq){		if(r->aux != nil)			sysfatal("more than one outstanding dial request (BUG)");		if(c->state == Established)			respond(r, nil);		else			respond(r, "connect failed");	}	c->rq = nil;}voidteardownclient(Client *c){	Msg *m;	c->state = Teardown;	m = allocmsg(conn, SSH_MSG_CHANNEL_INPUT_EOF, 4);	putlong(m, c->servernum);	sendmsg(m);}voidhangupclient(Client *c){	Req *r, *next;	Msg *m, *mnext;	c->state = Closed;	for(m=c->mq; m; m=mnext){		mnext = m->link;		free(m);	}	c->mq = nil;	for(r=c->rq; r; r=next){		next = r->aux;		respond(r, "hangup on network connection");	}	c->rq = nil;}voidcloseclient(Client *c){	Msg *m, *next;	if(--c->ref)		return;	if(c->rq != nil)		sysfatal("ref count reached zero with requests pending (BUG)");	for(m=c->mq; m; m=next){		next = m->link;		free(m);	}	c->mq = nil;	if(c->state != Closed)		teardownclient(c);}	voidsshreadproc(void *a){	Conn *c;	Msg *m;	c = a;	for(;;){		m = recvmsg(c, -1);		if(m == nil)			sysfatal("eof on ssh connection");		sendp(sshmsgchan, m);	}}typedef struct Tab Tab;struct Tab{	char *name;	ulong mode;};Tab tab[] ={	"/",		DMDIR|0555,	"cs",		0666,	"tcp",	DMDIR|0555,		"clone",	0666,	nil,		DMDIR|0555,	"ctl",		0666,	"data",	0666,	"local",	0444,	"remote",	0444,	"status",	0444,};static voidfillstat(Dir *d, uvlong path){	Tab *t;	memset(d, 0, sizeof(*d));	d->uid = estrdup9p("ssh");	d->gid = estrdup9p("ssh");	d->qid.path = path;	d->atime = d->mtime = time0;	t = &tab[TYPE(path)];	if(t->name)		d->name = estrdup9p(t->name);	else{		d->name = smprint("%ud", NUM(path));		if(d->name == nil)			sysfatal("out of memory");	}	d->qid.type = t->mode>>24;	d->mode = t->mode;}static voidfsattach(Req *r){	if(r->ifcall.aname && r->ifcall.aname[0]){		respond(r, "invalid attach specifier");		return;	}	r->fid->qid.path = PATH(Qroot, 0);	r->fid->qid.type = QTDIR;	r->fid->qid.vers = 0;	r->ofcall.qid = r->fid->qid;	respond(r, nil);}static voidfsstat(Req *r){	fillstat(&r->d, r->fid->qid.path);	respond(r, nil);}static introotgen(int i, Dir *d, void*){	i += Qroot+1;	if(i <= Qtcp){		fillstat(d, i);		return 0;	}	return -1;}static inttcpgen(int i, Dir *d, void*){	i += Qtcp+1;	if(i < Qn){		fillstat(d, i);		return 0;	}	i -= Qn;	if(i < nclient){		fillstat(d, PATH(Qn, i));		return 0;	}	return -1;}static intclientgen(int i, Dir *d, void *aux){	Client *c;	c = aux;	i += Qn+1;	if(i <= Qstatus){		fillstat(d, PATH(i, c->num));		return 0;	}	return -1;}static char*fswalk1(Fid *fid, char *name, Qid *qid){	int i, n;	char buf[32];	ulong path;	path = fid->qid.path;	if(!(fid->qid.type&QTDIR))		return "walk in non-directory";	if(strcmp(name, "..") == 0){		switch(TYPE(path)){		case Qn:			qid->path = PATH(Qtcp, NUM(path));			qid->type = tab[Qtcp].mode>>24;			return nil;		case Qtcp:			qid->path = PATH(Qroot, 0);			qid->type = tab[Qroot].mode>>24;			return nil;		case Qroot:			return nil;		default:			return "bug in fswalk1";		}	}	i = TYPE(path)+1;	for(; i<nelem(tab); i++){		if(i==Qn){			n = atoi(name);			snprint(buf, sizeof buf, "%d", n);			if(n < nclient && strcmp(buf, name) == 0){				qid->path = PATH(i, n);				qid->type = tab[i].mode>>24;				return nil;			}			break;		}		if(strcmp(name, tab[i].name) == 0){			qid->path = PATH(i, NUM(path));			qid->type = tab[i].mode>>24;			return nil;		}		if(tab[i].mode&DMDIR)			break;	}	return "directory entry not found";}typedef struct Cs Cs;struct Cs{	char *resp;	int isnew;};static intndbfindport(char *p){	char *s, *port;	int n;	static Ndb *db;	if(*p == '\0')		return -1;	n = strtol(p, &s, 0);	if(*s == '\0')		return n;	if(db == nil){		db = ndbopen("/lib/ndb/common");		if(db == nil)			return -1;	}	port = ndbgetvalue(db, nil, "tcp", p, "port", nil);	if(port == nil)		return -1;	n = atoi(port);	free(port);	return n;}	static voidcsread(Req *r){	Cs *cs;	cs = r->fid->aux;	if(cs->resp==nil){		respond(r, "cs read without write");		return;	}	if(r->ifcall.offset==0){		if(!cs->isnew){			r->ofcall.count = 0;			respond(r, nil);			return;		}		cs->isnew = 0;	}	readstr(r, cs->resp);	respond(r, nil);}static voidcswrite(Req *r){	int port, nf;	char err[ERRMAX], *f[4], *s, *ns;	Cs *cs;	cs = r->fid->aux;	s = emalloc(r->ifcall.count+1);	memmove(s, r->ifcall.data, r->ifcall.count);	s[r->ifcall.count] = '\0';	nf = getfields(s, f, nelem(f), 0, "!");	if(nf != 3){		free(s);		respond(r, "can't translate");		return;	}	if(strcmp(f[0], "tcp") != 0 && strcmp(f[0], "net") != 0){		free(s);		respond(r, "unknown protocol");		return;	}	port = ndbfindport(f[2]);	if(port <= 0){		free(s);		respond(r, "no translation found");		return;	}	ns = smprint("%s/tcp/clone %s!%d", mtpt, f[1], port);	if(ns == nil){		free(s);		rerrstr(err, sizeof err);		respond(r, err);		return;	}	free(s);	free(cs->resp);

⌨️ 快捷键说明

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