1 #include "headers.h"
2
3 static SmbService local = {
4 .name = "local",
5 .type = "A:",
6 .stype = STYPE_DISKTREE,
7 .remark = "The standard namespace",
8 .path = "/n/local",
9 };
10
11 static SmbService ipc = {
12 .name = "IPC$",
13 .type = "IPC",
14 .stype = STYPE_IPC,
15 .remark = "The aquarela IPC service",
16 .path = nil,
17 .next = &local,
18 };
19
20 SmbService *smbservices = &ipc;
21
22 static int
run9fs(char * arg)23 run9fs(char *arg)
24 {
25 int rv;
26 Waitmsg *w;
27
28 rv = fork();
29 if (rv < 0)
30 return -1;
31 if (rv == 0) {
32 char *argv[3];
33 argv[0] = "/rc/bin/9fs";
34 argv[1] = arg;
35 argv[2] = 0;
36 exec(argv[0], argv);
37 exits("failed to exec 9fs");
38 }
39 for (;;) {
40 w = wait();
41 if (w == nil)
42 return -1;
43 if (w->pid == rv)
44 break;
45 free(w);
46 }
47 if (w->msg[0]) {
48 smblogprint(SMB_COM_TREE_CONNECT_ANDX, "smbservicefind: %s\n", w->msg);
49 free(w);
50 return -1;
51 }
52 free(w);
53 smblogprint(SMB_COM_TREE_CONNECT_ANDX, "smbservicefind: 9fs %s executed successfully\n", arg);
54 return 0;
55 }
56
57 SmbService *
smbservicefind(SmbSession * s,char * uncpath,char * servicetype,uchar * errclassp,ushort * errorp)58 smbservicefind(SmbSession *s, char *uncpath, char *servicetype, uchar *errclassp, ushort *errorp)
59 {
60 char *p, *q;
61 if ((uncpath[0] == '/' && uncpath[1] == '/')
62 || (uncpath[0] == '\\' && uncpath[1] == '\\')) {
63 /* check that the server name matches mine */
64 p = uncpath + 2;
65 q = strchr(p, uncpath[0]);
66 if (q == nil)
67 goto bad;
68 *q++ = 0;
69 // if (cistrcmp(p, smbglobals.serverinfo.name) != 0)
70 // goto bad;
71 }
72 else
73 q = uncpath + 1;
74 if (strcmp(servicetype, "?????") == 0 && strcmp(q, "IPC$") == 0)
75 return &ipc;
76 if ((strcmp(servicetype, "?????") == 0 || strcmp(servicetype, "A:") == 0)) {
77 SmbService *serv;
78 if (cistrcmp(q, local.name) == 0)
79 return &local;
80 /* try the session specific list */
81 for (serv = s->serv; serv; serv = serv->next)
82 if (cistrcmp(q, serv->name) == 0)
83 return serv;
84 /* exec "9fs q" in case it invents /n/q */
85 for (p = q; *p; p++)
86 if (*p >= 'A' && *p <= 'Z')
87 *p = tolower(*p);
88 if (run9fs(q) >= 0) {
89 serv = smbemallocz(sizeof(*serv), 1);
90 serv->name = smbestrdup(q);
91 serv->type = smbestrdup("A:");
92 serv->stype = STYPE_DISKTREE;
93 smbstringprint(&serv->remark, "9fs %s", q);
94 smbstringprint(&serv->path, "/n/%s", q);
95 serv->next = s->serv;
96 s->serv = serv;
97 return serv;
98 }
99 }
100 bad:
101 *errclassp = ERRDOS;
102 *errorp = ERRbadpath;
103 return nil;
104 }
105
106 void
smbserviceget(SmbService * serv)107 smbserviceget(SmbService *serv)
108 {
109 incref(serv);
110 }
111
112 void
smbserviceput(SmbService * serv)113 smbserviceput(SmbService *serv)
114 {
115 decref(serv);
116 }
117