xref: /plan9/sys/src/cmd/aquarela/smbservice.c (revision b698dcfadb276a6209fd40d3fd699dab70955a1b)
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