Merge branch 'master' of ssh://crater.dragonflybsd.org/repository/git/dragonfly
[dragonfly.git] / usr.bin / ncplist / ncplist.c
blobbb7c81bd8b30bfab388182a9cb974411c1c5dbd7
1 /*
2 * Copyright (c) 1999, Boris Popov
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Boris Popov.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
32 * $FreeBSD: src/usr.bin/ncplist/ncplist.c,v 1.1 1999/10/20 11:31:02 bp Exp $
33 * $DragonFly: src/usr.bin/ncplist/ncplist.c,v 1.3 2008/07/10 18:29:52 swildner Exp $
35 #include <sys/param.h>
36 #include <sys/time.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include <stdlib.h>
42 #include <netncp/ncp_lib.h>
44 extern char *__progname;
46 static struct ncp_conn_stat conndesc;
48 static void help(void);
49 static void show_connlist(void);
50 static void show_serverlist(char *server);
51 static void show_userlist(char *server);
52 static void list_volumes(char *server);
53 static void str_trim_right(char *s, char c);
56 int
57 ncp_get_connid(char *server, int justattach) {
58 int connid, error;
59 struct ncp_conn_loginfo li;
61 connid = ncp_conn_find(server, NULL);
62 if (connid > 0) {
63 ncp_conn_getinfo(connid, &conndesc);
64 return connid;
66 if (!justattach) {
67 if (connid == -1) {
68 printf("You are not attached to server %s\n",server);
69 return -1;
71 printf("You are not attached to any server\n");
72 return -1;
74 ncp_li_init(&li, 0, NULL);
75 if (server) {
76 ncp_li_setserver(&li, server);
77 error = ncp_find_fileserver(&li, AF_IPX, NULL);
78 if (error) {
79 printf("Could not find server %s\n", li.server);
80 return -1;
82 } else {
83 error = ncp_find_fileserver(&li, AF_IPX, NULL);
84 if (error) {
85 printf("Can't find any file server\n");
86 return -1;
89 error = ncp_connect(&li, &connid);
90 if (error) {
91 printf("Can't attach to a nearest server\n");
92 return -1;
94 ncp_conn_getinfo(connid, &conndesc);
95 return connid;
98 static struct ncp_bitname conn_statenames [] = {
99 {NCPFL_INVALID, "invalid"},
100 {NCPFL_LOGGED, "active"},
101 {NCPFL_PERMANENT, "permanent"},
102 {NCPFL_PRIMARY, "primary"},
103 {0, NULL}
106 static void
107 str_trim_right(char *s, char c) {
108 int len;
110 for(len = strlen(s) - 1; len > 0 && s[len] == c; len--)
111 s[len] = '\0';
114 void
115 show_connlist(void) {
116 void *p;
117 int cnt;
118 char buf[200];
119 struct ncp_conn_stat *ncsp;
121 printf("Active NCP connections:\n");
122 p = ncp_conn_list();
123 if (p == NULL) {
124 printf("None\n");
125 return;
127 printf(" refid server:user(connid), owner:group(mode), refs, <state>\n");
128 cnt = *(int*)p;
129 ncsp = (struct ncp_conn_stat*)(((int*)p)+1);
130 while(cnt--) {
131 printf("%6d %s:%s(%d), %s:%s(%o), %d, %s",
132 ncsp->connRef, ncsp->li.server,ncsp->user,ncsp->connid,
133 user_from_uid(ncsp->owner, 0),
134 group_from_gid(ncsp->group, 0),
135 ncsp->li.access_mode,
136 ncsp->ref_cnt,
137 ncp_printb(buf, ncsp->flags, conn_statenames));
138 printf("\n");
139 ncsp++;
141 free(p);
142 printf("\n");
145 void
146 show_serverlist(char *server) {
147 int found = 0, connid;
148 struct ncp_bindery_object obj;
149 char *pattern = "*";
151 connid = ncp_get_connid(server, 1);
152 if (connid < 0)
153 return;
154 printf("Visible servers (from %s):\n", conndesc.li.server);
155 printf("Name Network Node Port\n");
156 printf("----------------------------------------------- -------- ------------ ----\n");
157 obj.object_id = 0xffffffff;
159 while (ncp_scan_bindery_object(connid, obj.object_id, NCP_BINDERY_FSERVER,
160 pattern, &obj) == 0) {
161 struct nw_property prop;
162 struct ipx_addr *naddr = (struct ipx_addr *) &prop;
164 found = 1;
165 printf("%-48s", obj.object_name);
167 if (ncp_read_property_value(connid, NCP_BINDERY_FSERVER,
168 obj.object_name, 1, "NET_ADDRESS",
169 &prop) == 0) {
170 ipx_print_addr(naddr);
172 printf("\n");
175 if (!found) {
176 printf("No servers found\n");
178 printf("\n");
182 void
183 show_userlist(char *server) {
184 int connid, error, i;
185 struct ncp_file_server_info info;
186 struct ncp_bindery_object user;
187 time_t login_time;
188 struct ipx_addr addr;
189 u_int8_t conn_type;
191 connid = ncp_get_connid(server, 0);
192 if (connid < 0) return;
193 if (ncp_get_file_server_information(connid, &info) != 0) {
194 perror("Could not get server information");
195 return;
197 printf("User information for server %s\n",info.ServerName);
198 printf("\n%-6s%-21s%-27s%-12s\n"
199 "---------------------------------------------"
200 "---------------------------------\n",
201 "Conn",
202 "User name",
203 "Station Address",
204 "Login time");
205 for (i = 1; i <= info.MaximumServiceConnections; i++) {
206 char name[49];
207 name[48] = '\0';
208 error = ncp_get_stations_logged_info(connid, i, &user, &login_time);
209 if (error) continue;
210 memset(&addr, 0, sizeof(addr));
211 error = ncp_get_internet_address(connid, i, &addr, &conn_type);
212 if (error) continue;
213 memcpy(name, user.object_name, 48);
214 str_trim_right(name, ' ');
215 printf("%4d: %-20s ", i, name);
216 ipx_print_addr(&addr);
217 printf(" ");
218 printf("%s", ctime(&login_time));
221 return;
224 void
225 show_queuelist(char *server, char *patt) {
226 struct ncp_bindery_object q;
227 int found = 0, connid;
228 char default_pattern[] = "*";
229 char *pattern = default_pattern;
231 connid = ncp_get_connid(server, 1);
232 if (connid < 0) return;
233 if (patt != NULL)
234 pattern = patt;
235 ncp_str_upper(pattern);
237 printf("\nServer: %s\n", server);
238 printf("%-52s%-10s\n"
239 "-----------------------------------------------"
240 "-------------\n",
241 "Print queue name",
242 "Queue ID");
243 q.object_id = 0xffffffff;
245 while (ncp_scan_bindery_object(connid, q.object_id,
246 NCP_BINDERY_PQUEUE, pattern, &q) == 0)
248 found = 1;
249 printf("%-52s", q.object_name);
250 printf("%08X\n", (unsigned int) q.object_id);
253 if (!found) {
254 printf("No queues found\n");
256 return;
259 void
260 list_volumes(char *server) {
261 int found = 0, connid, i, error;
262 struct ncp_file_server_info si;
263 char volname[NCP_VOLNAME_LEN+1];
265 connid = ncp_get_connid(server, 1);
266 if (connid < 0) return;
268 error = ncp_get_file_server_information(connid, &si);
269 if (error) {
270 ncp_error("Can't get information for server %s", error, server);
271 return;
274 printf("\nMounted volumes on server %s:\n", server);
275 printf("Number Name\n");
276 printf("------ -----------------------------------------------\n");
278 for(i = 0; i < si.NumberMountedVolumes; i++) {
279 if (NWGetVolumeName(connid, i, volname))
280 continue;
281 found = 1;
282 printf("%6d %s\n", i, volname);
285 if (!found)
286 printf("No volumes found ?\n");
287 return;
290 struct ncp_bind_type {
291 u_long type;
292 char *name;
295 static struct ncp_bind_type btypes[] = {
296 {NCP_BINDERY_USER, "USER"},
297 {NCP_BINDERY_UGROUP, "GROUP"},
298 {NCP_BINDERY_PSERVER, "PSERVER"},
299 {0x278, "TREE"},
300 {0, NULL}
303 void
304 list_bindery(char *server, char *type, char *patt) {
305 struct ncp_bindery_object q;
306 int i, found = 0, connid;
307 char default_pattern[] = "*";
308 char *pattern = default_pattern;
309 u_long objtype;
311 ncp_str_upper(type);
312 objtype = 0;
314 for(i = 0; btypes[i].type; i++) {
315 if (strcmp(btypes[i].name, type) == 0) {
316 objtype = btypes[i].type;
317 break;
320 if (!objtype) {
321 printf("Bindery object of type %s is unknown\n", type);
322 return;
324 if (patt != NULL)
325 pattern = patt;
326 ncp_str_upper(pattern);
327 connid = ncp_get_connid(server, 1);
328 if (connid < 0) return;
330 connid = ncp_get_connid(server, 1);
331 if (connid < 0) return;
334 printf("\nServer: %s\n", server);
335 printf("%-52s%-10s\n"
336 "-----------------------------------------------"
337 "-------------\n",
338 "Object name",
339 "Object ID");
341 q.object_id = 0xffffffff;
342 while (ncp_scan_bindery_object(connid, q.object_id,
343 objtype, pattern, &q) == 0)
345 found = 1;
346 printf("%-52s", q.object_name);
347 printf("%08X\n", (unsigned int) q.object_id);
350 if (!found) {
351 printf("No bindery objects found\n");
353 return;
356 enum listop {
357 LO_NONE, LO_SERVERS, LO_QUEUES, LO_BINDERY, LO_USERS, LO_VOLUMES
360 #define MAX_ARGS 10
363 main(int argc, char *argv[]) {
364 int opt, wdone = 0, nargs = 0, i;
365 enum listop what;
366 char *args[MAX_ARGS];
368 bzero(args, sizeof(args));
370 what = LO_NONE;
371 while ((opt = getopt(argc, argv, "h")) != -1) {
372 switch (opt) {
373 case 'h': case '?':
374 help();
375 /*NOTREACHED */
376 default:
377 help();
378 return 1;
381 if (optind >= argc)
382 help();
384 if(ncp_initlib())
385 exit(1);
387 switch(argv[optind++][0]) {
388 case 'b':
389 what = LO_BINDERY;
390 nargs = 2;
391 break;
392 case 'c':
393 show_connlist();
394 return 0;
395 case 's':
396 what = LO_SERVERS;
397 break;
398 case 'u':
399 what = LO_USERS;
400 nargs = 1;
401 break;
402 case 'q':
403 what = LO_QUEUES;
404 nargs = 1;
405 break;
406 case 'v':
407 what = LO_VOLUMES;
408 nargs = 1;
409 break;
410 default:
411 printf("Unknown command %s\n", argv[optind-1]);
412 help();
414 for (i = 0; i < MAX_ARGS; i++) {
415 if (optind < argc) {
416 args[i] = argv[optind++];
417 } else if (i < nargs) {
418 printf("Not enough arguments\n");
419 help();
420 return 1;
421 } else
422 break;
424 switch(what) {
425 case LO_SERVERS:
426 show_serverlist(args[0]);
427 wdone = 1;
428 break;
429 case LO_USERS:
430 show_userlist(args[0]);
431 wdone = 1;
432 break;
433 case LO_QUEUES:
434 show_queuelist(args[0], args[1]);
435 wdone = 1;
436 break;
437 case LO_VOLUMES:
438 list_volumes(args[0]);
439 wdone = 1;
440 break;
441 case LO_BINDERY:
442 list_bindery(args[0], args[1], args[2]);
443 wdone = 1;
444 break;
445 default:
446 help();
448 return 0;
451 static void
452 help(void) {
453 printf("\n");
454 printf("usage: %s command [args]\n", __progname);
455 printf("where commands are:\n"
456 " b server user|group [pattern] list bindery objects on server\n"
457 " c display opened connections\n"
458 " s [server] display known servers\n"
459 " u server list logged-in users on server\n"
460 " q server [pattern] list print queues on server\n"
461 " v server list mounted volumes on a specified server\n"
462 "\n");
463 exit(1);