123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #include "headers.h"
- static struct {
- int thread;
- QLock;
- char adir[NETPATHLEN];
- int acfd;
- char ldir[NETPATHLEN];
- int lcfd;
- SMBCIFSACCEPTFN *accept;
- } tcp = { -1 };
- typedef struct Session Session;
- enum { Connected, Dead };
- struct Session {
- SmbCifsSession;
- int thread;
- Session *next;
- int state;
- SMBCIFSWRITEFN *write;
- };
- static struct {
- QLock;
- Session *head;
- } sessions;
- typedef struct Listen Listen;
- static void
- deletesession(Session *s)
- {
- Session **sp;
- close(s->fd);
- qlock(&sessions);
- for (sp = &sessions.head; *sp && *sp != s; sp = &(*sp)->next)
- ;
- if (*sp)
- *sp = s->next;
- qunlock(&sessions);
- free(s);
- }
- static void
- tcpreader(void *a)
- {
- Session *s = a;
- uint8_t *buf;
- int buflen = smbglobals.maxreceive + 4;
- buf = nbemalloc(buflen);
- for (;;) {
- int n;
- uint8_t flags;
- uint16_t length;
- n = readn(s->fd, buf, 4);
- if (n != 4) {
- die:
- free(buf);
- if (s->state == Connected)
- (*s->write)(s, nil, -1);
- deletesession(s);
- return;
- }
- flags = buf[1];
- length = nhgets(buf + 2) | ((flags & 1) << 16);
- if (length > buflen - 4) {
- print("nbss: too much data (%u)\n", length);
- goto die;
- }
- n = readn(s->fd, buf + 4, length);
- if (n != length)
- goto die;
- if (s->state == Connected) {
- if ((*s->write)(s, buf + 4, length) != 0) {
- s->state = Dead;
- goto die;
- }
- }
- }
- }
- static Session *
- createsession(int fd)
- {
- Session *s;
- s = smbemalloc(sizeof(Session));
- s->fd = fd;
- s->state = Connected;
- qlock(&sessions);
- if (!(*tcp.accept)(s, &s->write)) {
- qunlock(&sessions);
- free(s);
- return nil;
- }
- s->thread = procrfork(tcpreader, s, 32768, RFNAMEG);
- if (s->thread < 0) {
- qunlock(&sessions);
- (*s->write)(s, nil, -1);
- free(s);
- return nil;
- }
- s->next = sessions.head;
- sessions.head = s;
- qunlock(&sessions);
- return s;
- }
- static void
- tcplistener(void *)
- {
- for (;;) {
- int dfd;
- char ldir[NETPATHLEN];
- int lcfd;
- //print("cifstcplistener: listening\n");
- lcfd = listen(tcp.adir, ldir);
- //print("cifstcplistener: contact\n");
- if (lcfd < 0) {
- die:
- qlock(&tcp);
- close(tcp.acfd);
- tcp.thread = -1;
- qunlock(&tcp);
- return;
- }
- dfd = accept(lcfd, ldir);
- close(lcfd);
- if (dfd < 0)
- goto die;
- if (createsession(dfd) == nil)
- close(dfd);
- }
- }
- int
- smblistencifs(SMBCIFSACCEPTFN *accept)
- {
- qlock(&tcp);
- if (tcp.thread < 0) {
- tcp.acfd = announce("tcp!*!cifs", tcp.adir);
- if (tcp.acfd < 0) {
- print("smblistentcp: can't announce: %r\n");
- qunlock(&tcp);
- return -1;
- }
- tcp.thread = proccreate(tcplistener, nil, 16384);
- }
- tcp.accept = accept;
- qunlock(&tcp);
- return 0;
- }
-
|