summaryrefslogtreecommitdiff
path: root/sys/src/cmd/aquarela/smbtree.c
blob: da4c3ba0fb37d774be9f8096c9afdd4897445a7a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include "headers.h"

typedef struct DisconnectData {
	SmbSession *s;
	SmbTree *t;
} DisconnectData;

static void
smbtreefree(SmbTree **tp)
{
	SmbTree *t = *tp;
	if (t) {
		smbserviceput(t->serv);
		free(t);
		*tp = nil;
	}
}

static void
closesearch(void *magic, void *a)
{
	SmbSearch *search = a;
	DisconnectData *d = magic;
	if (search->t == d->t)
		smbsearchclose(d->s, search);
}

static void
closefile(void *magic, void *a)
{
	SmbFile *f = a;
	DisconnectData *d = magic;
	if (f->t == d->t)
		smbfileclose(d->s, f);
}

void
smbtreedisconnect(SmbSession *s, SmbTree *t)
{
	if (t) {
		DisconnectData data;
		smblogprintif(smbglobals.log.tids, "smbtreedisconnect: 0x%.4ux\n", t->id);
		data.s = s;
		data.t = t;
		smbserviceput(t->serv);
		smbidmapapply(s->sidmap, closesearch, &data);
		smbidmapapply(s->fidmap, closefile, &data);
		smbidmapremove(s->tidmap, t);
		smbtreefree(&t);
	}
}

void
smbtreedisconnectbyid(SmbSession *s, ushort id)
{
	smbtreedisconnect(s, smbidmapfind(s->tidmap, id));
}

SmbTree *
smbtreeconnect(SmbSession *s, SmbService *serv)
{
	SmbTree *t;

	if (s->tidmap == nil)
		s->tidmap = smbidmapnew();

	t = smbemallocz(sizeof(*t), 1);
	smbidmapadd(s->tidmap, t);
	t->serv = serv;
	smbserviceget(serv);
	smblogprintif(smbglobals.log.tids, "smbtreeconnect: 0x%.4ux\n", t->id);
	return t;
}