1/* $FreeBSD$ */
2
3#include <sys/param.h>
4#include <sys/time.h>
5#include <grp.h>
6#include <pwd.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <unistd.h>
11#ifdef APPLE
12#include <err.h>
13#include <sysexits.h>
14#endif
15
16#include <netsmb/smb_lib.h>
17#include <netsmb/smb_conn.h>
18
19#include "common.h"
20
21#define	DEFBIT(bit)	{bit, #bit}
22
23static struct smb_bitname conn_caps[] = {
24	DEFBIT(SMB_CAP_RAW_MODE),
25	DEFBIT(SMB_CAP_MPX_MODE),
26	DEFBIT(SMB_CAP_UNICODE),
27	DEFBIT(SMB_CAP_LARGE_FILES),
28	DEFBIT(SMB_CAP_NT_SMBS),
29	DEFBIT(SMB_CAP_NT_FIND),
30	DEFBIT(SMB_CAP_EXT_SECURITY),
31	{0, NULL}
32};
33
34static struct smb_bitname vc_flags[] = {
35	DEFBIT(SMBV_PERMANENT),
36	{SMBV_PRIVATE,	"private"},
37	{SMBV_SINGLESHARE, "singleshare"},
38	{SMBV_ENCRYPT,	"encpwd"},
39	{SMBV_WIN95,	"win95"},
40	{SMBV_LONGNAMES,"longnames"},
41	{0, NULL}
42};
43
44static struct smb_bitname ss_flags[] = {
45	DEFBIT(SMBS_PERMANENT),
46	{0, NULL}
47};
48
49static char *conn_proto[] = {
50	"unknown",
51	"PC NETWORK PROGRAM 1.0, PCLAN1.0",
52	"MICROSOFT NETWORKS 1.03",
53	"MICROSOFT NETWORKS 3.0, LANMAN1.0",
54	"LM1.2X002, DOS LM1.2X002",
55	"DOS LANMAN2.1, LANMAN2.1",
56	"NT LM 0.12, Windows for Workgroups 3.1a, NT LANMAN 1.0"
57};
58
59static char *iod_state[] = {
60	"Not connected",
61	"Reconnecting",
62	"Transport activated",
63	"Session active",
64	"Session dead"
65};
66
67static void
68print_vcinfo(struct smb_vc_info *vip)
69{
70	char buf[200];
71
72	printf("VC: \\\\%s\\%s\n", vip->srvname, vip->vcname);
73	printf("(%s:%s) %o", user_from_uid(vip->uid, 0),
74	    group_from_gid(vip->gid, 0), vip->mode);
75	printf("\n");
76	if (!verbose)
77		return;
78	iprintf(4, "state:    %s\n", iod_state[vip->iodstate]);
79	iprintf(4, "flags:    0x%04x %s\n", vip->flags,
80	    smb_printb(buf, vip->flags, vc_flags));
81	iprintf(4, "usecount: %d\n", vip->usecount);
82	iprintf(4, "dialect:  %d (%s)\n", vip->sopt.sv_proto, conn_proto[vip->sopt.sv_proto]);
83	iprintf(4, "smode:    %d\n", vip->sopt.sv_sm);
84	iprintf(4, "caps:     0x%04x %s\n", vip->sopt.sv_caps,
85	    smb_printb(buf, vip->sopt.sv_caps, conn_caps));
86	iprintf(4, "maxmux:   %d\n", vip->sopt.sv_maxmux);
87	iprintf(4, "maxvcs:   %d\n", vip->sopt.sv_maxvcs);
88}
89
90static void
91print_shareinfo(struct smb_share_info *sip)
92{
93	char buf[200];
94
95	iprintf(4, "Share:    %s", sip->sname);
96	printf("(%s:%s) %o", user_from_uid(sip->uid, 0),
97	    group_from_gid(sip->gid, 0), sip->mode);
98	printf("\n");
99	if (!verbose)
100		return;
101	iprintf(8, "flags:    0x%04x %s\n", sip->flags,
102	    smb_printb(buf, sip->flags, ss_flags));
103	iprintf(8, "usecount: %d\n", sip->usecount);
104}
105
106int
107cmd_dumptree(int argc, char *argv[])
108{
109	void *p, *op;
110	int *itype;
111
112	printf("SMB connections:\n");
113#ifdef APPLE
114	if (loadsmbvfs())
115		errx(EX_OSERR, "SMB filesystem is not available");
116#endif
117	p = smb_dumptree();
118	if (p == NULL) {
119		printf("None\n");
120		return 0;
121	}
122	op = p;
123	for (;;) {
124		itype = p;
125		if (*itype == SMB_INFO_NONE)
126			break;
127		switch (*itype) {
128		    case SMB_INFO_VC:
129			print_vcinfo(p);
130			p = (struct smb_vc_info*)p + 1;
131			break;
132		    case SMB_INFO_SHARE:
133			print_shareinfo(p);
134			p = (struct smb_share_info*)p + 1;
135			break;
136		    default:
137			printf("Out of sync\n");
138			free(op);
139			return 1;
140
141		}
142	}
143	free(op);
144	printf("\n");
145	return 0;
146}
147