xref: /plan9/sys/src/cmd/aquarela/smbrap2client.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1 #include "headers.h"
2 
3 static SmbTransactionMethod smbtransactionmethodrap = {
4 	.encodeprimary = smbtransactionencodeprimary,
5 	.sendrequest = smbtransactionclientsend,
6 	.receiveresponse = smbtransactionclientreceive,
7 	.decoderesponse = smbtransactiondecoderesponse,
8 };
9 
10 int
smbclientrap(SmbClient * c,SmbBuffer * inparam,SmbBuffer * outparam,SmbBuffer * outdata,char ** errmsgp)11 smbclientrap(SmbClient *c, SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata, char **errmsgp)
12 {
13 	SmbTransaction transaction;
14 	SmbHeader h;
15 	memset(&transaction, 0, sizeof(transaction));
16 	transaction.in.name = smbglobals.pipelanman;
17 	transaction.in.parameters = smbbufferreadpointer(inparam);
18 	transaction.in.tpcount = smbbufferreadspace(inparam);
19 	transaction.in.maxpcount = smbbufferwritespace(outparam);
20 	transaction.in.maxdcount = smbbufferwritespace(outdata);
21 	transaction.out.parameters = outparam;
22 	transaction.out.data = outdata;
23 	h = c->protoh;
24 	h.tid = c->ipctid;
25 	h.mid = 0;
26 	return smbtransactionexecute(&transaction, &h, &c->peerinfo, c->b, &smbtransactionmethodrap, c, nil, errmsgp);
27 }
28 
29 int
smbnetserverenum2(SmbClient * c,ulong stype,char * domain,int * entriesp,SmbRapServerInfo1 ** sip,char ** errmsgp)30 smbnetserverenum2(SmbClient *c, ulong stype, char *domain, int *entriesp, SmbRapServerInfo1 **sip, char **errmsgp)
31 {
32 	int rv;
33 	ushort ec, entries, total, converter;
34 	SmbRapServerInfo1 *si = nil;
35 	SmbBuffer *ipb = smbbuffernew(512);
36 	SmbBuffer *odb = smbbuffernew(65535);
37 	SmbBuffer *opb = smbbuffernew(8);
38 	smbbufferputs(ipb, 104);
39 	smbbufferputstring(ipb, nil, SMB_STRING_ASCII, "WrLehDz");
40 	smbbufferputstring(ipb, nil, SMB_STRING_ASCII, "B16BBDz");
41 	smbbufferputs(ipb, 1);
42 	smbbufferputs(ipb, smbbufferwritespace(odb));
43 	smbbufferputl(ipb, stype);
44 	smbbufferputstring(ipb, nil, SMB_STRING_ASCII, domain);
45 	rv = !smbclientrap(c, ipb, opb, odb, errmsgp);
46 	smbbufferfree(&ipb);
47 	if (rv == 0) {
48 		char *remark, *eremark;
49 		int remarkspace;
50 		int i;
51 		if (!smbbuffergets(opb, &ec)
52 			|| !smbbuffergets(opb, &converter)
53 			|| !smbbuffergets(opb, &entries)
54 			|| !smbbuffergets(opb, &total)) {
55 			smbstringprint(errmsgp, "smbnetserverenum2: not enough return parameters");
56 			rv = -1;
57 			goto done;
58 		}
59 		if (ec != 0) {
60 			rv = ec;
61 			goto done;
62 		}
63 		if (smbbufferreadspace(odb) < entries * 26) {
64 			smbstringprint(errmsgp, "smbnetserverenum2: not enough return data");
65 			rv = -1;
66 			goto done;
67 		}
68 		remarkspace = smbbufferreadspace(odb) - entries * 26;
69 		si = smbemalloc(entries * sizeof(SmbRapServerInfo1) + remarkspace);
70 		remark = (char *)&si[entries];
71 		eremark = remark + remarkspace;
72 		for (i = 0; i < entries; i++) {
73 			ulong offset;
74 			int remarklen;
75 			assert(smbbuffergetbytes(odb, si[i].name, 16));
76 			assert(smbbuffergetb(odb, &si[i].vmaj));
77 			assert(smbbuffergetb(odb, &si[i].vmin));
78 			assert(smbbuffergetl(odb, &si[i].type));
79 			assert(smbbuffergetl(odb, &offset));
80 			offset -= converter;
81 			if (!smbbufferoffsetcopystr(odb, offset, remark, eremark - remark, &remarklen)) {
82 				smbstringprint(errmsgp, "smbnetserverenum2: invalid string offset");
83 				rv = -1;
84 				goto done;
85 			}
86 			si[i].remark = remark;
87 			remark += remarklen;
88 		}
89 		*sip = si;
90 		si = nil;
91 		*entriesp = entries;
92 	}
93 	else
94 		rv = -1;
95 done:
96 	free(si);
97 	smbbufferfree(&opb);
98 	smbbufferfree(&odb);
99 	return rv;
100 }
101