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