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

📄 smbrap2.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include "headers.h"typedef struct RapTableEntry RapTableEntry;struct RapTableEntry {	char *name;	SmbProcessResult (*procedure)(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata);};typedef int INFOSIZEFN(ushort level, void *data);typedef int INFOPUTFN(SmbBuffer *b, ushort level, void *data);typedef int INFOPUTSTRINGSFN(SmbBuffer *b, ushort level, int instance, void *data);typedef void *INFOENUMERATEFN(void *magic, int i);typedef struct InfoMethod {	INFOSIZEFN *size;	INFOPUTFN *put;	INFOPUTSTRINGSFN *putstrings;	INFOENUMERATEFN *enumerate;} InfoMethod;static intserverinfosize(ushort level, void *data){	SmbServerInfo *si = data;	switch (level) {	case 0:		return 16;	case 1:		return 26 + smbstrlen(si->remark);	default:		return 0;	}}static intserverinfoput(SmbBuffer *b, ushort level, void *data){	SmbServerInfo *si = data;	if (!smbbufferputstrn(b, si->name, 16, 1))		return 0;	if (level > 0) {		if (!smbbufferputb(b, si->vmaj)			|| !smbbufferputb(b, si->vmin)			|| !smbbufferputl(b, si->stype)			|| !smbbufferputl(b, 0))			return 0;	}	if (level > 1)		return 0;	return 1;}static intserverinfoputstrings(SmbBuffer *b, ushort level, int instance, void *data){	SmbServerInfo *si = data;	if (level == 1) {		if (!smbbufferfixupabsolutel(b, instance * 26 + 22)			|| !smbbufferputstring(b, nil, SMB_STRING_ASCII, si->remark))			return 0;	}	return 1;}static void *serverinfoenumerate(void *magic, int i){	if (magic) {		SmbServerInfo **si = magic;		return si[i];	}	if (i == 0)		return &smbglobals.serverinfo;	return nil;}InfoMethod serverinfo = {	serverinfosize,	serverinfoput,	serverinfoputstrings,	serverinfoenumerate,};static intshareinfosize(ushort level, void *data){	SmbService *serv = data;	switch (level) {	case 0:		return 13;	case 1:		return 20 + smbstrlen(serv->remark);	case 2:		return 40 + smbstrlen(serv->remark) + smbstrlen(serv->path);	default:		return 0;	}}static intshareinfoput(SmbBuffer *b, ushort level, void *data){	SmbService *serv = data;	if (!smbbufferputstrn(b, serv->name, 13, 0))		return 0;	if (level > 0) {		if (!smbbufferputb(b, 0)			|| !smbbufferputs(b, serv->stype)			|| !smbbufferputl(b, 0))			return 0;	}	if (level > 1) {		if (!smbbufferputs(b, 7)			|| !smbbufferputs(b, -1)			|| !smbbufferputs(b, serv->ref)			|| !smbbufferputl(b, 0)			|| !smbbufferfill(b, 0, 10))			return 0;	}	if (level > 2)		return 0;	return 1;}static intshareinfoputstrings(SmbBuffer *b, ushort level, int instance, void *data){	SmbService *serv = data;	switch (level) {	case 0:		break;	case 1:		if (!smbbufferfixupabsolutel(b, instance * 20 + 16)			|| !smbbufferputstring(b, nil, SMB_STRING_ASCII, serv->remark))			return 0;		break;	case 2:		if (!smbbufferfixupabsolutel(b, instance * 40 + 16)			|| !smbbufferputstring(b, nil, SMB_STRING_ASCII, serv->remark)			|| !smbbufferfixupabsolutel(b, instance * 40 + 26)			|| !smbbufferputstring(b, nil, SMB_STRING_ASCII, serv->path))			return 0;		break;	default:		return 0;	}	return 1;}static void *shareinfoenumerate(void *, int i){	SmbService *serv;	for (serv = smbservices; i-- > 0 && serv; serv = serv->next)		;	return serv;}static InfoMethod shareinfo = {	shareinfosize,	shareinfoput,	shareinfoputstrings,	shareinfoenumerate,};static SmbProcessResultthingfill(SmbBuffer *outparam, SmbBuffer *outdata, InfoMethod *m, ushort level, void *magic){	int sentthings, totalthings;	int i;	int totalbytes;	sentthings = 0;	totalbytes = 0;	for (i = 0; ; i++) {		int len;		void *thing = (*m->enumerate)(magic, i);		if (thing == nil)			break;		len = (*m->size)(level, thing);		if (totalbytes + len <= smbbufferspace(outdata)) {			assert((*m->put)(outdata, level, thing));			sentthings++;		}		totalbytes += len;	}	totalthings = i;	for (i = 0; i < sentthings; i++) {		void *thing = (*m->enumerate)(magic, i);		assert(thing);		assert((*m->putstrings)(outdata, level, i, thing));	}	if (!smbbufferputs(outparam, sentthings < totalthings ? SMB_RAP_ERROR_MORE_DATA : SMB_RAP_NERR_SUCCESS)		|| !smbbufferputs(outparam, 0)		|| !smbbufferputs(outparam, totalthings)		|| !smbbufferputs(outparam, sentthings))		return SmbProcessResultFormat;	return SmbProcessResultReply;}static SmbProcessResultonethingfill(SmbBuffer *outparam, SmbBuffer *outdata, InfoMethod *m, ushort level, void *thing){	int moredata;	int totalbytes = (*m->size)(level, thing);	if (totalbytes <= smbbufferspace(outdata)) {		assert((*m->put)(outdata, level, thing));		assert((*m->putstrings)(outdata, level, 0, thing));		moredata = 0;	}	else		moredata = 1;	if (!smbbufferputs(outparam, moredata ? SMB_RAP_ERROR_MORE_DATA : SMB_RAP_NERR_SUCCESS)		|| !smbbufferputs(outparam, 0)		|| !smbbufferputs(outparam, totalbytes))		return SmbProcessResultFormat;	return SmbProcessResultReply;}static SmbProcessResultnetshareenum(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata){	ushort level;	/* WrLeh */	/* ushort sLevel, RCVBUF pbBuffer, RCVBUFLEN cbBuffer, ENTCOUNT pcEntriesRead, ushort *pcTotalAvail */	if (!smbbuffergets(inparam, &level))		return SmbProcessResultFormat;		smblogprintif(smbglobals.log.rap2, "netshareenum(%lud, %lud)\n",		level, smbbufferwritespace(outdata));	if (level != 1)		return SmbProcessResultFormat;	return thingfill(outparam, outdata, &shareinfo, level, nil);}static SmbProcessResultnetserverenum2(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata){	ushort level, rbl;	char *domain;	ulong servertype;	SmbProcessResult pr;	SmbServerInfo *si[3];	SmbServerInfo domainsi;	int entries;	/* WrLehDz	 * ushort sLevel, RCVBUF pbBuffer, RCVBUFLEN cbBuffer, ENTCOUNT pcEntriesRead, ushort *pcTotalAvail,	 * ulong fServerType, char *pszDomain	*/	if (!smbbuffergets(inparam, &level)		|| !smbbuffergets(inparam, &rbl)		|| !smbbuffergetl(inparam, &servertype)		|| !smbbuffergetstr(inparam, 0, &domain)) {	fmtfail:		pr = SmbProcessResultFormat;		goto done;	}		smblogprintif(smbglobals.log.rap2, "netserverenum2(%lud, %lud, 0x%.8lux, %s)\n",		level, smbbufferwritespace(outdata), servertype, domain);	if (level > 1)		goto fmtfail;	if (servertype == 0xffffffff)		servertype &= ~(SV_TYPE_DOMAIN_ENUM | SV_TYPE_LOCAL_LIST_ONLY);	if ((servertype & SV_TYPE_LOCAL_LIST_ONLY) != 0 && (servertype & SV_TYPE_DOMAIN_ENUM) == 0) 		servertype = SV_TYPE_ALL & ~(SV_TYPE_DOMAIN_ENUM);	entries = 0;	if ((servertype & SV_TYPE_SERVER) != 0		&& (domain[0] == 0 || cistrcmp(domain, smbglobals.primarydomain) == 0)) {		si[entries++] = &smbglobals.serverinfo;	}	if ((servertype & SV_TYPE_DOMAIN_ENUM) != 0) {		/* there's only one that I know about */		memset(&domainsi, 0, sizeof(domainsi));		domainsi.name = smbglobals.primarydomain;		domainsi.stype = SV_TYPE_DOMAIN_ENUM;		si[entries++] = &domainsi;	}	si[entries] = 0;	pr = thingfill(outparam, outdata, &serverinfo, level, si);			done:	free(domain);	return pr;}static SmbProcessResultnetsharegetinfo(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata){	char *netname;	ushort level;	SmbProcessResult pr;	SmbService *serv;	/*	 * zWrLh	 * char *pszNetName, ushort sLevel, RCVBUF pbBuffer, RCVBUFLEN cbBuffer, ushort *pcbTotalAvail	*/	if (!smbbuffergetstrinline(inparam, &netname)		|| !smbbuffergets(inparam, &level)) {	fmtfail:		pr = SmbProcessResultFormat;		goto done;	}		smblogprintif(smbglobals.log.rap2, "netsharegetinfo(%s, %lud, %lud)\n",		netname, level, smbbufferwritespace(outdata));	if (level > 2)		goto fmtfail;	for (serv = smbservices; serv; serv = serv->next)		if (cistrcmp(serv->name, netname) == 0)			break;	if (serv == nil) {		smblogprint(-1, "netsharegetinfo: service %s unimplemented\n", netname);		pr = SmbProcessResultUnimp;		goto done;	}	pr = onethingfill(outparam, outdata, &shareinfo, level, serv);done:	return pr;}static SmbProcessResultnetservergetinfo(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata){	ushort level;	SmbProcessResult pr;	/* WrLh	 * ushort sLevel, RCVBUF pbBuffer, RCVBUFLEN cbBuffer, ushort *pcbTotalAvail	*/	if (!smbbuffergets(inparam, &level)) {	fmtfail:		pr = SmbProcessResultFormat;		goto done;	}		smblogprintif(smbglobals.log.rap2, "netservergetinfo(%lud, %lud)\n",		level, smbbufferwritespace(outdata));	if (level > 1)		goto fmtfail;	pr = onethingfill(outparam, outdata, &shareinfo, level, &smbglobals.serverinfo);			done:	return pr;}static SmbProcessResultnetwkstagetinfo(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata){	ushort level;	ushort usefulbytes;	SmbProcessResult pr;	int moredata;	/* WrLh	 * ushort sLevel, RCVBUF pbBuffer, RCVBUFLEN cbBuffer, ushort *pcbTotalAvail	*/	if (!smbbuffergets(inparam, &level)) {	fmtfail:		pr = SmbProcessResultFormat;		goto done;	}		smblogprintif(smbglobals.log.rap2, "netwkstagetinfo(%lud, %lud)\n",		level, smbbufferwritespace(outdata));	if (level != 10)		goto fmtfail;	usefulbytes = 22 + smbstrlen(smbglobals.serverinfo.name) + smbstrlen(getuser())		+ 3 * smbstrlen(smbglobals.primarydomain);	moredata = usefulbytes > smbbufferwritespace(outdata);	assert(smbbufferputl(outdata, 0));	assert(smbbufferputl(outdata, 0));	assert(smbbufferputl(outdata, 0));	assert(smbbufferputb(outdata, smbglobals.serverinfo.vmaj));	assert(smbbufferputb(outdata, smbglobals.serverinfo.vmin));	assert(smbbufferputl(outdata, 0));	assert(smbbufferputl(outdata, 0));	assert(smbbufferfixupabsolutel(outdata, 0));	assert(smbbufferputstring(outdata, nil, SMB_STRING_ASCII, smbglobals.serverinfo.name));	assert(smbbufferfixupabsolutel(outdata, 4));	assert(smbbufferputstring(outdata, nil, SMB_STRING_ASCII, getuser()));	assert(smbbufferfixupabsolutel(outdata, 8));	assert(smbbufferputstring(outdata, nil, SMB_STRING_ASCII, smbglobals.primarydomain));	assert(smbbufferfixupabsolutel(outdata, 14));	assert(smbbufferputstring(outdata, nil, SMB_STRING_ASCII, smbglobals.primarydomain));	assert(smbbufferfixupabsolutel(outdata, 18));	assert(smbbufferputstring(outdata, nil, SMB_STRING_ASCII, smbglobals.primarydomain));	if (!smbbufferputs(outparam, moredata ? SMB_RAP_ERROR_MORE_DATA : SMB_RAP_NERR_SUCCESS)		|| !smbbufferputs(outparam, 0)		|| !smbbufferputs(outparam, usefulbytes)) {		pr = SmbProcessResultFormat;		goto done;	}		pr = SmbProcessResultReply;			done:	return pr;}static RapTableEntry raptable[] = {[RapNetShareGetInfo] { "NetShareGetInfo", netsharegetinfo },[RapNetShareEnum] { "NetShareEnum", netshareenum },[RapNetServerGetInfo] {"NetServerGetInfo", netservergetinfo },[RapNetWkstaGetInfo] { "NetWkstaGetInfo", netwkstagetinfo },[RapNetServerEnum2] { "NetServerEnum2", netserverenum2 },};SmbProcessResultsmbrap2(SmbSession *s){	char *pstring;	char *dstring;	ushort pno;	RapTableEntry *e;	SmbProcessResult pr;	SmbBuffer *inparam;	inparam = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount);	if (!smbbuffergets(inparam, &pno)		|| !smbbuffergetstrinline(inparam, &pstring)		|| !smbbuffergetstrinline(inparam, &dstring)) {		smblogprintif(smbglobals.log.rap2, "smbrap2: not enough parameters\n");		pr = SmbProcessResultFormat;		goto done;	}	if (pno > nelem(raptable) || raptable[pno].name == nil) {		smblogprint(-1, "smbrap2: unsupported procedure %ud\n", pno);		pr = SmbProcessResultUnimp;		goto done;	}	e = raptable + pno;	pr = (*e->procedure)(inparam, s->transaction.out.parameters, s->transaction.out.data);done:	smbbufferfree(&inparam);	return pr;}

⌨️ 快捷键说明

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