xref: /plan9-contrib/sys/src/cmd/aquarela/cifscmd.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1*8ccd4a63SDavid du Colombier #include "headers.h"
2*8ccd4a63SDavid du Colombier #include <bio.h>
3*8ccd4a63SDavid du Colombier 
4*8ccd4a63SDavid du Colombier SmbClient *c;
5*8ccd4a63SDavid du Colombier Biobuf bin, bout;
6*8ccd4a63SDavid du Colombier static int verbose = 1;
7*8ccd4a63SDavid du Colombier 
8*8ccd4a63SDavid du Colombier #define	SEP(c)	(((c)==' ')||((c)=='\t')||((c)=='\n'))
9*8ccd4a63SDavid du Colombier 
10*8ccd4a63SDavid du Colombier typedef struct Slut {
11*8ccd4a63SDavid du Colombier 	char *name;
12*8ccd4a63SDavid du Colombier 	int val;
13*8ccd4a63SDavid du Colombier } Slut;
14*8ccd4a63SDavid du Colombier 
15*8ccd4a63SDavid du Colombier static char *
tokenise(char * s,char ** start,char ** end)16*8ccd4a63SDavid du Colombier tokenise(char *s, char **start, char **end)
17*8ccd4a63SDavid du Colombier {
18*8ccd4a63SDavid du Colombier 	char *to;
19*8ccd4a63SDavid du Colombier 	Rune r;
20*8ccd4a63SDavid du Colombier 	int n;
21*8ccd4a63SDavid du Colombier 
22*8ccd4a63SDavid du Colombier 	while(*s && SEP(*s))				/* skip leading white space */
23*8ccd4a63SDavid du Colombier 		s++;
24*8ccd4a63SDavid du Colombier 	to = *start = s;
25*8ccd4a63SDavid du Colombier 	while(*s){
26*8ccd4a63SDavid du Colombier 		n = chartorune(&r, s);
27*8ccd4a63SDavid du Colombier 		if(SEP(r)){
28*8ccd4a63SDavid du Colombier 			if(to != *start)		/* we have data */
29*8ccd4a63SDavid du Colombier 				break;
30*8ccd4a63SDavid du Colombier 			s += n;				/* null string - keep looking */
31*8ccd4a63SDavid du Colombier 			while(*s && SEP(*s))
32*8ccd4a63SDavid du Colombier 				s++;
33*8ccd4a63SDavid du Colombier 			to = *start = s;
34*8ccd4a63SDavid du Colombier 		}
35*8ccd4a63SDavid du Colombier 		else if(r == '\''){
36*8ccd4a63SDavid du Colombier 			s += n;				/* skip leading quote */
37*8ccd4a63SDavid du Colombier 			while(*s){
38*8ccd4a63SDavid du Colombier 				n = chartorune(&r, s);
39*8ccd4a63SDavid du Colombier 				if(r == '\''){
40*8ccd4a63SDavid du Colombier 					if(s[1] != '\'')
41*8ccd4a63SDavid du Colombier 						break;
42*8ccd4a63SDavid du Colombier 					s++;		/* embedded quote */
43*8ccd4a63SDavid du Colombier 				}
44*8ccd4a63SDavid du Colombier 				while (n--)
45*8ccd4a63SDavid du Colombier 					*to++ = *s++;
46*8ccd4a63SDavid du Colombier 			}
47*8ccd4a63SDavid du Colombier 			if(!*s)				/* no trailing quote */
48*8ccd4a63SDavid du Colombier 				break;
49*8ccd4a63SDavid du Colombier 			s++;				/* skip trailing quote */
50*8ccd4a63SDavid du Colombier 		}
51*8ccd4a63SDavid du Colombier 		else  {
52*8ccd4a63SDavid du Colombier 			while(n--)
53*8ccd4a63SDavid du Colombier 				*to++ = *s++;
54*8ccd4a63SDavid du Colombier 		}
55*8ccd4a63SDavid du Colombier 	}
56*8ccd4a63SDavid du Colombier 	*end = to;
57*8ccd4a63SDavid du Colombier 	return s;
58*8ccd4a63SDavid du Colombier }
59*8ccd4a63SDavid du Colombier 
60*8ccd4a63SDavid du Colombier static int
parse(char * s,char * fields[],int nfields)61*8ccd4a63SDavid du Colombier parse(char *s, char *fields[], int nfields)
62*8ccd4a63SDavid du Colombier {
63*8ccd4a63SDavid du Colombier 	int c, argc;
64*8ccd4a63SDavid du Colombier 	char *start, *end;
65*8ccd4a63SDavid du Colombier 
66*8ccd4a63SDavid du Colombier 	argc = 0;
67*8ccd4a63SDavid du Colombier 	c = *s;
68*8ccd4a63SDavid du Colombier 	while(c){
69*8ccd4a63SDavid du Colombier 		s = tokenise(s, &start, &end);
70*8ccd4a63SDavid du Colombier 		c = *s++;
71*8ccd4a63SDavid du Colombier 		if(*start == 0)
72*8ccd4a63SDavid du Colombier 			break;
73*8ccd4a63SDavid du Colombier 		if(argc >= nfields-1)
74*8ccd4a63SDavid du Colombier 			return -1;
75*8ccd4a63SDavid du Colombier 		*end = 0;
76*8ccd4a63SDavid du Colombier 		fields[argc++] = start;
77*8ccd4a63SDavid du Colombier 	}
78*8ccd4a63SDavid du Colombier 	fields[argc] = 0;
79*8ccd4a63SDavid du Colombier Bprint(&bout, "parse returns %d\n", argc);
80*8ccd4a63SDavid du Colombier 	return argc;
81*8ccd4a63SDavid du Colombier }
82*8ccd4a63SDavid du Colombier 
83*8ccd4a63SDavid du Colombier typedef struct {
84*8ccd4a63SDavid du Colombier 	char *name;
85*8ccd4a63SDavid du Colombier 	long (*f)(SmbClient *, int, char *[]);
86*8ccd4a63SDavid du Colombier 	int connected;
87*8ccd4a63SDavid du Colombier 	char *help;
88*8ccd4a63SDavid du Colombier } Cmd;
89*8ccd4a63SDavid du Colombier static Cmd cmd[];
90*8ccd4a63SDavid du Colombier 
91*8ccd4a63SDavid du Colombier static long
cmdhelp(SmbClient *,int argc,char * argv[])92*8ccd4a63SDavid du Colombier cmdhelp(SmbClient *, int argc, char *argv[])
93*8ccd4a63SDavid du Colombier {
94*8ccd4a63SDavid du Colombier 	Cmd *cp;
95*8ccd4a63SDavid du Colombier 	char *p;
96*8ccd4a63SDavid du Colombier 
97*8ccd4a63SDavid du Colombier 	if(argc)
98*8ccd4a63SDavid du Colombier 		p = argv[0];
99*8ccd4a63SDavid du Colombier 	else
100*8ccd4a63SDavid du Colombier 		p = 0;
101*8ccd4a63SDavid du Colombier 	for (cp = cmd; cp->name; cp++) {
102*8ccd4a63SDavid du Colombier 		if (p == 0 || strcmp(p, cp->name) == 0)
103*8ccd4a63SDavid du Colombier 			Bprint(&bout, "%s\n", cp->help);
104*8ccd4a63SDavid du Colombier 	}
105*8ccd4a63SDavid du Colombier 	return 0;
106*8ccd4a63SDavid du Colombier }
107*8ccd4a63SDavid du Colombier 
108*8ccd4a63SDavid du Colombier static Slut sharemodeslut[] = {
109*8ccd4a63SDavid du Colombier 	{ "compatibility", SMB_OPEN_MODE_SHARE_COMPATIBILITY },
110*8ccd4a63SDavid du Colombier 	{ "exclusive", SMB_OPEN_MODE_SHARE_EXCLUSIVE },
111*8ccd4a63SDavid du Colombier 	{ "denywrite", SMB_OPEN_MODE_SHARE_DENY_WRITE },
112*8ccd4a63SDavid du Colombier 	{ "denyread", SMB_OPEN_MODE_SHARE_DENY_READOREXEC },
113*8ccd4a63SDavid du Colombier 	{ "denynone", SMB_OPEN_MODE_SHARE_DENY_NONE },
114*8ccd4a63SDavid du Colombier 	{ 0 }
115*8ccd4a63SDavid du Colombier };
116*8ccd4a63SDavid du Colombier 
117*8ccd4a63SDavid du Colombier static Slut openmodeslut[] = {
118*8ccd4a63SDavid du Colombier 	{ "oread", OREAD },
119*8ccd4a63SDavid du Colombier 	{ "owrite", OWRITE },
120*8ccd4a63SDavid du Colombier 	{ "ordwr", ORDWR },
121*8ccd4a63SDavid du Colombier 	{ "oexec", OEXEC },
122*8ccd4a63SDavid du Colombier 	{ 0 }
123*8ccd4a63SDavid du Colombier };
124*8ccd4a63SDavid du Colombier 
125*8ccd4a63SDavid du Colombier static int
slut(Slut * s,char * pat)126*8ccd4a63SDavid du Colombier slut(Slut *s, char *pat)
127*8ccd4a63SDavid du Colombier {
128*8ccd4a63SDavid du Colombier 	while (s->name) {
129*8ccd4a63SDavid du Colombier 		if (cistrcmp(s->name, pat) == 0)
130*8ccd4a63SDavid du Colombier 			return s->val;
131*8ccd4a63SDavid du Colombier 		s++;
132*8ccd4a63SDavid du Colombier 	}
133*8ccd4a63SDavid du Colombier 	Bprint(&bout, "%s unrecognised\n", pat);
134*8ccd4a63SDavid du Colombier 	return -1;
135*8ccd4a63SDavid du Colombier }
136*8ccd4a63SDavid du Colombier 
137*8ccd4a63SDavid du Colombier static long
cmdopen(SmbClient * c,int argc,char * argv[])138*8ccd4a63SDavid du Colombier cmdopen(SmbClient *c, int argc, char *argv[])
139*8ccd4a63SDavid du Colombier {
140*8ccd4a63SDavid du Colombier 	char *errmsg;
141*8ccd4a63SDavid du Colombier 	int sm, om;
142*8ccd4a63SDavid du Colombier 	int rv;
143*8ccd4a63SDavid du Colombier 	uchar errclass;
144*8ccd4a63SDavid du Colombier 	ushort error;
145*8ccd4a63SDavid du Colombier 	ushort fid, attr;
146*8ccd4a63SDavid du Colombier 	ulong mtime, size;
147*8ccd4a63SDavid du Colombier 	ushort accessallowed;
148*8ccd4a63SDavid du Colombier 
149*8ccd4a63SDavid du Colombier 	if (argc != 3) {
150*8ccd4a63SDavid du Colombier 		Bprint(&bout, "wrong number of arguments\n");
151*8ccd4a63SDavid du Colombier 		return -1;
152*8ccd4a63SDavid du Colombier 	}
153*8ccd4a63SDavid du Colombier 	sm = slut(sharemodeslut, argv[1]);
154*8ccd4a63SDavid du Colombier 	if (sm < 0)
155*8ccd4a63SDavid du Colombier 		return -1;
156*8ccd4a63SDavid du Colombier 	om = slut(openmodeslut, argv[2]);
157*8ccd4a63SDavid du Colombier 	if (om < 0)
158*8ccd4a63SDavid du Colombier 		return -1;
159*8ccd4a63SDavid du Colombier 	errmsg = nil;
160*8ccd4a63SDavid du Colombier 	rv = smbclientopen(c, (sm << 3) | om, argv[0], &errclass, &error, &fid, &attr, &mtime, &size, &accessallowed, &errmsg);
161*8ccd4a63SDavid du Colombier 	if (rv == 0) {
162*8ccd4a63SDavid du Colombier 		if (errmsg) {
163*8ccd4a63SDavid du Colombier 			print("local error %s\n", errmsg);
164*8ccd4a63SDavid du Colombier 			free(errmsg);
165*8ccd4a63SDavid du Colombier 			return -1;
166*8ccd4a63SDavid du Colombier 		}
167*8ccd4a63SDavid du Colombier 		return (errclass << 16) | error;
168*8ccd4a63SDavid du Colombier 	}
169*8ccd4a63SDavid du Colombier 	print("fid 0x%.4ux attr 0x%.4ux time %ld size %lud accessallowed %ud\n",
170*8ccd4a63SDavid du Colombier 		fid, attr, mtime, size, accessallowed);
171*8ccd4a63SDavid du Colombier 	return 0;
172*8ccd4a63SDavid du Colombier }
173*8ccd4a63SDavid du Colombier 
174*8ccd4a63SDavid du Colombier static Cmd cmd[] = {
175*8ccd4a63SDavid du Colombier 	{ "help",	cmdhelp,	0, "help" },
176*8ccd4a63SDavid du Colombier 	{ "open", cmdopen, 1, "open name sharemode openmode" },
177*8ccd4a63SDavid du Colombier 	{ 0, 0 },
178*8ccd4a63SDavid du Colombier };
179*8ccd4a63SDavid du Colombier 
180*8ccd4a63SDavid du Colombier void
threadmain(int argc,char * argv[])181*8ccd4a63SDavid du Colombier threadmain(int argc, char *argv[])
182*8ccd4a63SDavid du Colombier {
183*8ccd4a63SDavid du Colombier 	char *errmsg;
184*8ccd4a63SDavid du Colombier 	int ac;
185*8ccd4a63SDavid du Colombier 	char *ap, *av[256];
186*8ccd4a63SDavid du Colombier 	Cmd *cp;
187*8ccd4a63SDavid du Colombier 	long status;
188*8ccd4a63SDavid du Colombier 
189*8ccd4a63SDavid du Colombier 	if (argc > 3) {
190*8ccd4a63SDavid du Colombier 		print("usage: cifscmd [to [share]]\n");
191*8ccd4a63SDavid du Colombier 		exits("args");
192*8ccd4a63SDavid du Colombier 	}
193*8ccd4a63SDavid du Colombier 	smbglobalsguess(1);
194*8ccd4a63SDavid du Colombier 	errmsg = nil;
195*8ccd4a63SDavid du Colombier 
196*8ccd4a63SDavid du Colombier 	if (Binit(&bin, 0, OREAD) == Beof || Binit(&bout, 1, OWRITE) == Beof) {
197*8ccd4a63SDavid du Colombier 		fprint(2, "%s: can't init bio: %r\n", argv0);
198*8ccd4a63SDavid du Colombier 		threadexits("Binit");
199*8ccd4a63SDavid du Colombier 	}
200*8ccd4a63SDavid du Colombier 
201*8ccd4a63SDavid du Colombier 	if (argc > 1) {
202*8ccd4a63SDavid du Colombier 		c = smbconnect(argv[1], argc == 3 ? argv[2] : nil, &errmsg);
203*8ccd4a63SDavid du Colombier 		if (c == nil)
204*8ccd4a63SDavid du Colombier 			fprint(2, "failed to connect: %s\n", errmsg);
205*8ccd4a63SDavid du Colombier 	}
206*8ccd4a63SDavid du Colombier 	while (ap = Brdline(&bin, '\n')) {
207*8ccd4a63SDavid du Colombier 		ap[Blinelen(&bin) - 1] = 0;
208*8ccd4a63SDavid du Colombier 		switch (ac = parse(ap, av, nelem(av))) {
209*8ccd4a63SDavid du Colombier 		default:
210*8ccd4a63SDavid du Colombier 			for (cp = cmd; cp->name; cp++) {
211*8ccd4a63SDavid du Colombier 				if (strcmp(cp->name, av[0]) == 0)
212*8ccd4a63SDavid du Colombier 					break;
213*8ccd4a63SDavid du Colombier 			}
214*8ccd4a63SDavid du Colombier 			if (cp->name == 0) {
215*8ccd4a63SDavid du Colombier 				Bprint(&bout, "eh?\n");
216*8ccd4a63SDavid du Colombier 				break;
217*8ccd4a63SDavid du Colombier 			}
218*8ccd4a63SDavid du Colombier 			if (c == 0 && cp->connected) {
219*8ccd4a63SDavid du Colombier 				Bprint(&bout, "not currently connected\n");
220*8ccd4a63SDavid du Colombier 				break;
221*8ccd4a63SDavid du Colombier 			}
222*8ccd4a63SDavid du Colombier 			if ((status = (*cp->f)(c, ac - 1, &av[1])) != -1) {
223*8ccd4a63SDavid du Colombier 				if(verbose)
224*8ccd4a63SDavid du Colombier 					Bprint(&bout, "ok %ld/%ld\n", status >> 16, status & 0xffff);
225*8ccd4a63SDavid du Colombier 				break;
226*8ccd4a63SDavid du Colombier 			}
227*8ccd4a63SDavid du Colombier 			break;
228*8ccd4a63SDavid du Colombier 
229*8ccd4a63SDavid du Colombier 		case -1:
230*8ccd4a63SDavid du Colombier 			Bprint(&bout, "eh?\n");
231*8ccd4a63SDavid du Colombier 			break;
232*8ccd4a63SDavid du Colombier 
233*8ccd4a63SDavid du Colombier 		case 0:
234*8ccd4a63SDavid du Colombier 			break;
235*8ccd4a63SDavid du Colombier 		}
236*8ccd4a63SDavid du Colombier 		Bflush(&bout);
237*8ccd4a63SDavid du Colombier 	}
238*8ccd4a63SDavid du Colombier 	threadexits(0);
239*8ccd4a63SDavid du Colombier }
240