#include "headers.h" static SmbService local = { .name = "local", .type = "A:", .stype = STYPE_DISKTREE, .remark = "The standard namespace", .path = "/n/local", }; static SmbService ipc = { .name = "IPC$", .type = "IPC", .stype = STYPE_IPC, .remark = "The aquarela IPC service", .path = nil, .next = &local, }; SmbService *smbservices = &ipc; static int run9fs(char *arg) { int rv; Waitmsg *w; rv = fork(); if (rv < 0) return -1; if (rv == 0) { char *argv[3]; argv[0] = "/rc/bin/9fs"; argv[1] = arg; argv[2] = 0; exec(argv[0], argv); exits("failed to exec 9fs"); } for (;;) { w = wait(); if (w == nil) return -1; if (w->pid == rv) break; free(w); } if (w->msg[0]) { smblogprint(SMB_COM_TREE_CONNECT_ANDX, "smbservicefind: %s\n", w->msg); free(w); return -1; } free(w); smblogprint(SMB_COM_TREE_CONNECT_ANDX, "smbservicefind: 9fs %s executed successfully\n", arg); return 0; } SmbService * smbservicefind(SmbSession *s, char *uncpath, char *servicetype, uchar *errclassp, ushort *errorp) { char *p, *q; if ((uncpath[0] == '/' && uncpath[1] == '/') || (uncpath[0] == '\\' && uncpath[1] == '\\')) { /* check that the server name matches mine */ p = uncpath + 2; q = strchr(p, uncpath[0]); if (q == nil) goto bad; *q++ = 0; // if (cistrcmp(p, smbglobals.serverinfo.name) != 0) // goto bad; } else q = uncpath + 1; if (strcmp(servicetype, "?????") == 0 && strcmp(q, "IPC$") == 0) return &ipc; if ((strcmp(servicetype, "?????") == 0 || strcmp(servicetype, "A:") == 0)) { SmbService *serv; if (cistrcmp(q, local.name) == 0) return &local; /* try the session specific list */ for (serv = s->serv; serv; serv = serv->next) if (cistrcmp(q, serv->name) == 0) return serv; /* exec "9fs q" in case it invents /n/q */ for (p = q; *p; p++) if (*p >= 'A' && *p <= 'Z') *p = tolower(*p); if (run9fs(q) >= 0) { serv = smbemallocz(sizeof(*serv), 1); serv->name = smbestrdup(q); serv->type = smbestrdup("A:"); serv->stype = STYPE_DISKTREE; smbstringprint(&serv->remark, "9fs %s", q); smbstringprint(&serv->path, "/n/%s", q); serv->next = s->serv; s->serv = serv; return serv; } } bad: *errclassp = ERRDOS; *errorp = ERRbadpath; return nil; } void smbserviceget(SmbService *serv) { incref(serv); } void smbserviceput(SmbService *serv) { decref(serv); }