]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cifs/fs.c
ip/cifsd: dont return garbage in upper 32 bit of unix extension stat fields
[plan9front.git] / sys / src / cmd / cifs / fs.c
1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 #include <fcall.h>
5 #include <thread.h>
6 #include <9p.h>
7 #include "cifs.h"
8
9 static char *period(long sec);
10
11 static char *devtypes[] = {
12         "beep", "cd", "cdfs", "datalink", "dfs", "disk", "diskfs", "fs", "inport",
13         "kbd", "mailslot", "midi-in", "midi-out", "mouse", "unc", "named-pipe", "net", "net",
14         "browser", "netfs", "null", "lpt", "nic", "lpr", "scanner", "eia-mouse",
15         "eia", "screen", "sound", "streams", "tape", "tapefs", "transport", "unknown",
16         "video", "virt-disk", "wav-in", "wav-out", "8042", "battery", "bus-exp", "modem", "vdm"
17 };
18         
19
20 static double
21 togb(uvlong n)
22 {
23         return (double)n / (1024.0 * 1024.0 * 1024.0);
24 }
25
26 int
27 shareinfo(Fmt *f)
28 {
29         int type;
30         Share *sp;
31         Shareinfo2 si2;
32         uvlong total, unused;
33
34         for(sp = Shares; sp < &Shares[Nshares]; sp++){
35                 fmtprint(f, "%-24q ", sp->name);
36
37                 if(T2fsdeviceinfo(Sess, sp, &type, nil) != -1)
38                         fmtprint(f, "%-16s ", devtypes[type]);
39
40                 if(T2fssizeinfo(Sess, sp, &total, &unused) != -1)
41                         fmtprint(f, "%6.1f/%-6.1f ", togb(total-unused), togb(total));
42
43                 if(RAPshareinfo(Sess, sp, sp->name, &si2) != -1){
44                         fmtprint(f, "%5d/%-5d %s", si2.activeusrs, si2.maxusrs, si2.comment);
45                         free(si2.name);
46                         free(si2.comment);
47                         free(si2.path);
48                         free(si2.passwd);
49                 }
50                 fmtprint(f, "\n");
51
52         }
53         return 0;
54 }
55
56 int
57 openfileinfo(Fmt *f)
58 {
59         int got,  i;
60         Fileinfo *fi;
61
62         fi = nil;
63         if((got = RAPFileenum2(Sess, &Ipc, "", "", &fi)) == -1){
64                 fmtprint(f, "RAPfileenum: %r\n");
65                 return 0;
66         }
67
68         for(i = 0; i < got; i++){
69                 fmtprint(f, "%c%c%c %-4d %-24q %q ",
70                         (fi[i].perms & 1)? 'r': '-',
71                         (fi[i].perms & 2)? 'w': '-',
72                         (fi[i].perms & 4)? 'c': '-',
73                         fi[i].locks, fi[i].user, fi[i].path);
74                 free(fi[i].path);
75                 free(fi[i].user);
76         }
77         free(fi);
78         return 0;
79 }
80
81 int
82 conninfo(Fmt *f)
83 {
84         int i;
85         typedef struct {
86                 int     val;
87                 char    *name;
88         } Tab;
89         static Tab captab[] = {
90                 { 1,            "raw-mode" },
91                 { 2,            "mpx-mode" },
92                 { 4,            "unicode" },
93                 { 8,            "large-files" },
94                 { 0x10,         "NT-smbs" },
95                 { 0x20,         "rpc-remote-APIs" },
96                 { 0x40,         "status32" },
97                 { 0x80,         "l2-oplocks" },
98                 { 0x100,        "lock-read" },
99                 { 0x200,        "NT-find" },
100                 { 0x1000,       "Dfs" },
101                 { 0x2000,       "info-passthru" },
102                 { 0x4000,       "large-readx" },
103                 { 0x8000,       "large-writex" },
104                 { 0x800000,     "Unix" },
105                 { 0x20000000,   "bulk-transfer" },
106                 { 0x40000000,   "compressed" },
107                 { 0x80000000,   "extended-security" },
108         };
109         static Tab sectab[] = {
110                 { 1,            "user-auth" },
111                 { 2,            "challange-response" },
112                 { 4,            "signing-available" },
113                 { 8,            "signing-required" },
114         };
115
116         fmtprint(f, "%q %q %q %q %+ldsec %dmtu %s\n",
117                 Sess->auth->user, Sess->cname,
118                 Sess->auth->windom, Sess->remos,
119                 Sess->slip, Sess->mtu, Sess->isguest? "as guest": "");
120
121         fmtprint(f, "caps: ");
122         for(i = 0; i < nelem(captab); i++)
123                 if(Sess->caps & captab[i].val)
124                         fmtprint(f, "%s ", captab[i].name);
125         fmtprint(f, "\n");
126
127         fmtprint(f, "security: ");
128         for(i = 0; i < nelem(sectab); i++)
129                 if(Sess->secmode & sectab[i].val)
130                         fmtprint(f, "%s ", sectab[i].name);
131         fmtprint(f, "\n");
132
133         if(Sess->nbt)
134                 fmtprint(f, "transport: cifs over netbios\n");
135         else
136                 fmtprint(f, "transport: cifs\n");
137         return 0;
138 }
139
140 int
141 sessioninfo(Fmt *f)
142 {
143         int got,  i;
144         Sessinfo *si;
145
146         si = nil;
147         if((got = RAPsessionenum(Sess, &Ipc, &si)) == -1){
148                 fmtprint(f, "RAPsessionenum: %r\n");
149                 return 0;
150         }
151
152         for(i = 0; i < got; i++){
153                 fmtprint(f, "%-24q %-24q ", si[i].user, si[i].wrkstn);
154                 fmtprint(f, "%12s ", period(si[i].sesstime));
155                 fmtprint(f, "%12s\n", period(si[i].idletime));
156                 free(si[i].wrkstn);
157                 free(si[i].user);
158         }
159         free(si);
160         return 0;
161 }
162
163 /*
164  * We request the domain referral for "" which gives the
165  * list of all the trusted domains in the clients forest, and
166  * other trusted forests.
167  *
168  * We then sumbit each of these names in turn which gives the
169  * names of the domain controllers for that domain.
170  *
171  * We get a DNS domain name for each domain controller as well as a
172  * netbios name.  I THINK I am correct in saying that a name
173  * containing a dot ('.') must be a DNS name, as the NetBios
174  * name munging cannot encode one.  Thus names which contain no
175  * dots must be netbios names.
176  *
177  */
178 static void
179 dfsredir(Fmt *f, char *path, int depth)
180 {
181         Refer *re, retab[128];
182         int n, used, flags;
183
184         n = T2getdfsreferral(Sess, &Ipc, path, &flags, &used, retab, nelem(retab));
185         if(n == -1)
186                 return;
187         for(re = retab; re < retab+n; re++){
188                 if(strcmp(path, re->path) != 0)
189                         dfsredir(f, re->path, depth+1);
190                 else
191                         fmtprint(f, "%-32q %q\n", re->path, re->addr);
192
193                 free(re->addr);
194                 free(re->path);
195         }
196 }
197
198 int
199 dfsrootinfo(Fmt *f)
200 {
201         dfsredir(f, "", 0);
202         return 0;
203 }
204
205
206 int
207 userinfo(Fmt *f)
208 {
209         int got, i;
210         Namelist *nl;
211         Userinfo ui;
212
213         nl = nil;
214         if((got = RAPuserenum2(Sess, &Ipc, &nl)) == -1)
215                 if((got = RAPuserenum(Sess, &Ipc, &nl)) == -1){
216                         fmtprint(f, "RAPuserenum: %r\n");
217                         return 0;
218                 }
219
220         for(i = 0; i < got; i++){
221                 fmtprint(f, "%-24q ", nl[i].name);
222
223                 if(RAPuserinfo(Sess, &Ipc, nl[i].name, &ui) != -1){
224                         fmtprint(f, "%-48q %q", ui.fullname, ui.comment);
225                         free(ui.user);
226                         free(ui.comment);
227                         free(ui.fullname);
228                         free(ui.user_comment);
229                 }
230                 free(nl[i].name);
231                 fmtprint(f, "\n");
232         }
233         free(nl);
234         return 0;
235 }
236
237 int
238 groupinfo(Fmt *f)
239 {
240         int got1, got2, i, j;
241         Namelist *grps, *usrs;
242
243         grps = nil;
244         if((got1 = RAPgroupenum(Sess, &Ipc, &grps)) == -1){
245                 fmtprint(f, "RAPgroupenum: %r\n");
246                 return 0;
247         }
248
249         for(i = 0; i < got1; i++){
250                 fmtprint(f, "%q ", grps[i].name);
251                 usrs = nil;
252                 if((got2 = RAPgroupusers(Sess, &Ipc, grps[i].name, &usrs)) != -1){
253                         for(j = 0; j < got2; j++){
254                                 fmtprint(f, "%q ", usrs[j].name);
255                                 free(usrs[j].name);
256                         }
257                         free(usrs);
258                 }
259                 free(grps[i].name);
260                 fmtprint(f, "\n");
261         }
262         free(grps);
263         return 0;
264 }
265
266 static int
267 nodelist(Fmt *f, int type)
268 {
269         int more, got, i, j;
270         Serverinfo *si;
271         static char *types[] = {
272                 [0]     "workstation",
273                 [1]     "server",
274                 [2]     "SQL server",
275                 [3]     "DC",
276                 [4]     "backup DC",
277                 [5]     "time source",
278                 [6]     "Apple server",
279                 [7]     "Novell server",
280                 [8]     "domain member",
281                 [9]     "printer server",
282                 [10]    "dial-up server",
283                 [11]    "Unix",
284                 [12]    "NT",
285                 [13]    "WFW",
286                 [14]    "MFPN (?)",
287                 [15]    "NT server",
288                 [16]    "potential browser",
289                 [17]    "backup browser",
290                 [18]    "LMB",
291                 [19]    "DMB",
292                 [20]    "OSF Unix",
293                 [21]    "VMS",
294                 [22]    "Win95",
295                 [23]    "DFS",
296                 [24]    "NT cluster",
297                 [25]    "Terminal server",
298                 [26]    "[26]",
299                 [27]    "[27]",
300                 [28]    "IBM DSS",
301         };
302
303         si = nil;
304         if((got = RAPServerenum2(Sess, &Ipc, Sess->auth->windom, type, &more,
305             &si)) == -1){
306                 fmtprint(f, "RAPServerenum2: %r\n");
307                 return 0;
308         }
309         if(more)
310                 if((got = RAPServerenum3(Sess, &Ipc, Sess->auth->windom, type,
311                     got-1, si)) == -1){
312                         fmtprint(f, "RAPServerenum3: %r\n");
313                         return 0;
314                 }
315
316         for(i = 0; i < got; i++){
317                 fmtprint(f, "%-16q %-16q ", si[i].name, si[i].comment);
318                 if(type != LIST_DOMAINS_ONLY){
319                         fmtprint(f, "v%d.%d ", si[i].major, si[i].minor);
320                         for(j = 0; j < nelem(types); j++)
321                                 if(si[i].type & (1 << j) && types[j])
322                                         fmtprint(f, "%s,", types[j]);
323                 }
324                 fmtprint(f, "\n");
325                 free(si[i].name);
326                 free(si[i].comment);
327         }
328         free(si);
329         return 0;
330 }
331
332 int
333 domaininfo(Fmt *f)
334 {
335         return nodelist(f, LIST_DOMAINS_ONLY);
336 }
337
338 int
339 workstationinfo(Fmt *f)
340 {
341         return nodelist(f, ALL_LEARNT_IN_DOMAIN);
342 }
343
344 static char *
345 period(long sec)
346 {
347         int days, hrs, min;
348         static char when[32];
349
350         days = sec  / (60L * 60L * 24L);
351         sec -= days * (60L * 60L * 24L);
352         hrs  = sec / (60L * 60L);
353         sec -= hrs * (60L * 60L);
354         min  = sec / 60L;
355         sec -= min * 60L;
356         if(days)
357                 snprint(when, sizeof(when), "%d,%d:%d:%ld ", days, hrs, min, sec);
358         else
359                 snprint(when, sizeof(when), "%d:%d:%ld ", hrs, min, sec);
360         return when;
361 }