ncplist.c revision 52406
1219820Sjeff/* 2219820Sjeff * Copyright (c) 1999, Boris Popov 3219820Sjeff * All rights reserved. 4219820Sjeff * 5270710Shselasky * Redistribution and use in source and binary forms, with or without 6328653Shselasky * modification, are permitted provided that the following conditions 7219820Sjeff * are met: 8219820Sjeff * 1. Redistributions of source code must retain the above copyright 9219820Sjeff * notice, this list of conditions and the following disclaimer. 10219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright 11219820Sjeff * notice, this list of conditions and the following disclaimer in the 12219820Sjeff * documentation and/or other materials provided with the distribution. 13219820Sjeff * 3. All advertising materials mentioning features or use of this software 14219820Sjeff * must display the following acknowledgement: 15219820Sjeff * This product includes software developed by Boris Popov. 16219820Sjeff * 4. Neither the name of the author nor the names of any co-contributors 17219820Sjeff * may be used to endorse or promote products derived from this software 18219820Sjeff * without specific prior written permission. 19219820Sjeff * 20219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21219820Sjeff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22219820Sjeff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23219820Sjeff * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24219820Sjeff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25219820Sjeff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26219820Sjeff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27219820Sjeff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28219820Sjeff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29289644Shselasky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30289644Shselasky * SUCH DAMAGE. 31219820Sjeff * 32328653Shselasky * $FreeBSD: head/usr.bin/ncplist/ncplist.c 52406 1999-10-20 11:31:02Z bp $ 33328653Shselasky */ 34219820Sjeff#include <sys/param.h> 35219820Sjeff#include <sys/time.h> 36300671Shselasky#include <stdio.h> 37328653Shselasky#include <string.h> 38219820Sjeff#include <unistd.h> 39219820Sjeff#include <stdlib.h> 40328653Shselasky 41328653Shselasky#include <netncp/ncp_lib.h> 42219820Sjeff 43219820Sjeffextern char *__progname; 44219820Sjeff 45328653Shselaskystatic struct ncp_conn_stat conndesc; 46289564Shselasky 47328653Shselaskystatic void help(void); 48328653Shselaskystatic void show_connlist(void); 49219820Sjeffstatic void show_serverlist(char *server); 50335425Shselaskystatic void show_userlist(char *server); 51335425Shselaskystatic void list_volumes(char *server); 52335425Shselaskystatic void str_trim_right(char *s, char c); 53335425Shselasky 54328653Shselasky 55328653Shselaskyint 56219820Sjeffncp_get_connid(char *server, int justattach) { 57328653Shselasky int connid, error; 58328653Shselasky struct ncp_conn_loginfo li; 59219820Sjeff 60328653Shselasky connid = ncp_conn_find(server, NULL); 61219820Sjeff if (connid > 0) { 62328653Shselasky ncp_conn_getinfo(connid, &conndesc); 63328653Shselasky return connid; 64328653Shselasky } 65328653Shselasky if (!justattach) { 66328653Shselasky if (connid == -1) { 67328653Shselasky printf("You are not attached to server %s\n",server); 68328653Shselasky return -1; 69328653Shselasky } 70335424Shselasky printf("You are not attached to any server\n"); 71335424Shselasky return -1; 72335424Shselasky } 73335424Shselasky ncp_li_init(&li, 0, NULL); 74328653Shselasky if (server) { 75219820Sjeff ncp_li_setserver(&li, server); 76328653Shselasky error = ncp_find_fileserver(&li, AF_IPX, NULL); 77328653Shselasky if (error) { 78335424Shselasky printf("Could not find server %s\n", li.server); 79335424Shselasky return -1; 80335424Shselasky } 81335424Shselasky } else { 82328653Shselasky error = ncp_find_fileserver(&li, AF_IPX, NULL); 83328653Shselasky if (error) { 84328653Shselasky printf("Can't find any file server\n"); 85328653Shselasky return -1; 86328653Shselasky } 87328653Shselasky } 88328653Shselasky error = ncp_connect(&li, &connid); 89330861Shselasky if (error) { 90328653Shselasky printf("Can't attach to a nearest server\n"); 91330861Shselasky return -1; 92328653Shselasky } 93328653Shselasky ncp_conn_getinfo(connid, &conndesc); 94330861Shselasky return connid; 95328653Shselasky} 96328653Shselasky 97328653Shselaskystatic struct ncp_bitname conn_statenames [] = { 98330861Shselasky {NCPFL_INVALID, "invalid"}, 99330861Shselasky {NCPFL_LOGGED, "active"}, 100330861Shselasky {NCPFL_PERMANENT, "permanent"}, 101328653Shselasky {NCPFL_PRIMARY, "primary"}, 102328653Shselasky {0, NULL} 103328653Shselasky}; 104328653Shselasky 105328653Shselaskystatic void 106328653Shselaskystr_trim_right(char *s, char c) { 107328653Shselasky int len; 108328653Shselasky 109328653Shselasky for(len = strlen(s) - 1; len > 0 && s[len] == c; len--) 110328653Shselasky s[len] = '\0'; 111328653Shselasky} 112328653Shselasky 113328653Shselaskyvoid 114328653Shselaskyshow_connlist(void) { 115328653Shselasky void *p; 116328653Shselasky int cnt; 117219820Sjeff char buf[200]; 118219820Sjeff struct ncp_conn_stat *ncsp; 119335423Shselasky 120328653Shselasky printf("Active NCP connections:\n"); 121328653Shselasky p = ncp_conn_list(); 122335423Shselasky if (p == NULL) { 123335423Shselasky printf("None\n"); 124328653Shselasky return; 125328653Shselasky } 126328653Shselasky printf(" refid server:user(connid), owner:group(mode), refs, <state>\n"); 127328653Shselasky cnt = *(int*)p; 128328653Shselasky ncsp = (struct ncp_conn_stat*)(((int*)p)+1); 129328653Shselasky while(cnt--) { 130328653Shselasky printf("%6d %s:%s(%d), %s:%s(%o), %d, %s", 131328653Shselasky ncsp->connRef, ncsp->li.server,ncsp->user,ncsp->connid, 132328653Shselasky user_from_uid(ncsp->owner, 0), 133328653Shselasky group_from_gid(ncsp->group, 0), 134328653Shselasky ncsp->li.access_mode, 135328653Shselasky ncsp->ref_cnt, 136328653Shselasky ncp_printb(buf, ncsp->flags, conn_statenames)); 137328653Shselasky printf("\n"); 138328653Shselasky ncsp++; 139328653Shselasky } 140328653Shselasky free(p); 141328653Shselasky printf("\n"); 142328653Shselasky} 143328653Shselasky 144328653Shselaskyvoid 145328653Shselaskyshow_serverlist(char *server) { 146328653Shselasky int found = 0, connid; 147328653Shselasky struct ncp_bindery_object obj; 148328653Shselasky char *pattern = "*"; 149328653Shselasky 150328653Shselasky connid = ncp_get_connid(server, 1); 151328653Shselasky if (connid < 0) 152328653Shselasky return; 153328653Shselasky printf("Visible servers (from %s):\n", conndesc.li.server); 154328653Shselasky printf("Name Network Node Port\n"); 155328653Shselasky printf("----------------------------------------------- -------- ------------ ----\n"); 156328653Shselasky obj.object_id = 0xffffffff; 157328653Shselasky 158328653Shselasky while (ncp_scan_bindery_object(connid, obj.object_id, NCP_BINDERY_FSERVER, 159328653Shselasky pattern, &obj) == 0) { 160328653Shselasky struct nw_property prop; 161328653Shselasky struct ipx_addr *naddr = (struct ipx_addr *) ∝ 162328653Shselasky 163328653Shselasky found = 1; 164328653Shselasky printf("%-48s", obj.object_name); 165328653Shselasky 166328653Shselasky if (ncp_read_property_value(connid, NCP_BINDERY_FSERVER, 167328653Shselasky obj.object_name, 1, "NET_ADDRESS", 168328653Shselasky &prop) == 0) { 169328653Shselasky ipx_print_addr(naddr); 170328653Shselasky } 171328653Shselasky printf("\n"); 172328653Shselasky } 173328653Shselasky 174219820Sjeff if (!found) { 175219820Sjeff printf("No servers found\n"); 176328653Shselasky } 177328653Shselasky printf("\n"); 178328653Shselasky} 179328653Shselasky 180328653Shselasky 181328653Shselaskyvoid 182328653Shselaskyshow_userlist(char *server) { 183328653Shselasky int connid, error, i; 184328653Shselasky struct ncp_file_server_info info; 185328653Shselasky struct ncp_bindery_object user; 186334760Shselasky time_t login_time; 187334760Shselasky struct ipx_addr addr; 188334760Shselasky u_int8_t conn_type; 189334760Shselasky 190334760Shselasky connid = ncp_get_connid(server, 0); 191328653Shselasky if (connid < 0) return; 192328653Shselasky if (ncp_get_file_server_information(connid, &info) != 0) { 193328653Shselasky perror("Could not get server information"); 194328653Shselasky return; 195328653Shselasky } 196328653Shselasky printf("User information for server %s\n",info.ServerName); 197328653Shselasky printf("\n%-6s%-21s%-27s%-12s\n" 198328653Shselasky "---------------------------------------------" 199328653Shselasky "---------------------------------\n", 200328653Shselasky "Conn", 201328653Shselasky "User name", 202328653Shselasky "Station Address", 203328653Shselasky "Login time"); 204328653Shselasky for (i = 1; i <= info.MaximumServiceConnections; i++) { 205328653Shselasky char name[49]; 206297459Snp name[48] = '\0'; 207328653Shselasky error = ncp_get_stations_logged_info(connid, i, &user, &login_time); 208328653Shselasky if (error) continue; 209328653Shselasky memset(&addr, 0, sizeof(addr)); 210328653Shselasky error = ncp_get_internet_address(connid, i, &addr, &conn_type); 211297459Snp if (error) continue; 212297459Snp memcpy(name, user.object_name, 48); 213297459Snp str_trim_right(name, ' '); 214328653Shselasky printf("%4d: %-20s ", i, name); 215330862Shselasky ipx_print_addr(&addr); 216328653Shselasky printf(" "); 217328653Shselasky printf("%s", ctime(&login_time)); 218328653Shselasky } 219328653Shselasky 220328653Shselasky return; 221297459Snp} 222330862Shselasky 223330862Shselaskyvoid 224330862Shselaskyshow_queuelist(char *server, char *patt) { 225330862Shselasky struct ncp_bindery_object q; 226330862Shselasky int found = 0, connid; 227330862Shselasky char default_pattern[] = "*"; 228330862Shselasky char *pattern = default_pattern; 229330862Shselasky 230328653Shselasky connid = ncp_get_connid(server, 1); 231328653Shselasky if (connid < 0) return; 232289564Shselasky if (patt != NULL) 233328653Shselasky pattern = patt; 234289564Shselasky ncp_str_upper(pattern); 235219820Sjeff 236328653Shselasky printf("\nServer: %s\n", server); 237328653Shselasky printf("%-52s%-10s\n" 238328653Shselasky "-----------------------------------------------" 239289564Shselasky "-------------\n", 240328653Shselasky "Print queue name", 241328653Shselasky "Queue ID"); 242328653Shselasky q.object_id = 0xffffffff; 243328653Shselasky 244328653Shselasky while (ncp_scan_bindery_object(connid, q.object_id, 245289564Shselasky NCP_BINDERY_PQUEUE, pattern, &q) == 0) 246328653Shselasky { 247289564Shselasky found = 1; 248328653Shselasky printf("%-52s", q.object_name); 249289564Shselasky printf("%08X\n", (unsigned int) q.object_id); 250289564Shselasky } 251289564Shselasky 252328653Shselasky if (!found) { 253289564Shselasky printf("No queues found\n"); 254328653Shselasky } 255289564Shselasky return; 256289564Shselasky} 257328653Shselasky 258328653Shselaskyvoid 259328653Shselaskylist_volumes(char *server) { 260328653Shselasky int found = 0, connid, i, error; 261328653Shselasky struct ncp_file_server_info si; 262328653Shselasky char volname[NCP_VOLNAME_LEN+1]; 263328653Shselasky 264328653Shselasky connid = ncp_get_connid(server, 1); 265328653Shselasky if (connid < 0) return; 266328653Shselasky 267328653Shselasky error = ncp_get_file_server_information(connid, &si); 268328653Shselasky if (error) { 269328653Shselasky ncp_error("Can't get information for server %s", error, server); 270328653Shselasky return; 271328653Shselasky } 272328653Shselasky 273328653Shselasky printf("\nMounted volumes on server %s:\n", server); 274328653Shselasky printf("Number Name\n"); 275328653Shselasky printf("------ -----------------------------------------------\n"); 276328653Shselasky 277328653Shselasky for(i = 0; i < si.NumberMountedVolumes; i++) { 278328653Shselasky if (NWGetVolumeName(connid, i, volname)) 279328653Shselasky continue; 280328653Shselasky found = 1; 281328653Shselasky printf("%6d %s\n", i, volname); 282330847Shselasky } 283330847Shselasky 284328653Shselasky if (!found) 285328653Shselasky printf("No volumes found ?\n"); 286328653Shselasky return; 287328653Shselasky} 288328653Shselasky 289328653Shselaskystruct ncp_bind_type { 290328653Shselasky u_long type; 291328653Shselasky char *name; 292328653Shselasky}; 293328653Shselasky 294328653Shselaskystatic struct ncp_bind_type btypes[] = { 295328653Shselasky {NCP_BINDERY_USER, "USER"}, 296328653Shselasky {NCP_BINDERY_UGROUP, "GROUP"}, 297328653Shselasky {NCP_BINDERY_PSERVER, "PSERVER"}, 298328653Shselasky {0x278, "TREE"}, 299328653Shselasky {0, NULL} 300328653Shselasky}; 301328653Shselasky 302void 303list_bindery(char *server, char *type, char *patt) { 304 struct ncp_bindery_object q; 305 int i, found = 0, connid; 306 char default_pattern[] = "*"; 307 char *pattern = default_pattern; 308 u_long objtype; 309 310 ncp_str_upper(type); 311 objtype = 0; 312 313 for(i = 0; btypes[i].type; i++) { 314 if (strcmp(btypes[i].name, type) == 0) { 315 objtype = btypes[i].type; 316 break; 317 } 318 } 319 if (!objtype) { 320 printf("Bindery object of type %s is unknown\n", type); 321 return; 322 } 323 if (patt != NULL) 324 pattern = patt; 325 ncp_str_upper(pattern); 326 connid = ncp_get_connid(server, 1); 327 if (connid < 0) return; 328 329 connid = ncp_get_connid(server, 1); 330 if (connid < 0) return; 331 332 333 printf("\nServer: %s\n", server); 334 printf("%-52s%-10s\n" 335 "-----------------------------------------------" 336 "-------------\n", 337 "Object name", 338 "Object ID"); 339 340 q.object_id = 0xffffffff; 341 while (ncp_scan_bindery_object(connid, q.object_id, 342 objtype, pattern, &q) == 0) 343 { 344 found = 1; 345 printf("%-52s", q.object_name); 346 printf("%08X\n", (unsigned int) q.object_id); 347 } 348 349 if (!found) { 350 printf("No bindery objects found\n"); 351 } 352 return; 353} 354 355enum listop { 356 LO_NONE, LO_SERVERS, LO_QUEUES, LO_BINDERY, LO_USERS, LO_VOLUMES 357}; 358 359#define MAX_ARGS 10 360 361int 362main(int argc, char *argv[]) { 363 int opt, wdone = 0, nargs = 0, i; 364 enum listop what; 365 char *args[MAX_ARGS]; 366 367 bzero(args, sizeof(args)); 368 369 what = LO_NONE; 370 while ((opt = getopt(argc, argv, "h")) != EOF) { 371 switch (opt) { 372 case 'h': case '?': 373 help(); 374 /*NOTREACHED */ 375 default: 376 help(); 377 return 1; 378 } 379 } 380 if (optind >= argc) 381 help(); 382 383 if(ncp_initlib()) 384 exit(1); 385 386 switch(argv[optind++][0]) { 387 case 'b': 388 what = LO_BINDERY; 389 nargs = 2; 390 break; 391 case 'c': 392 show_connlist(); 393 return 0; 394 case 's': 395 what = LO_SERVERS; 396 break; 397 case 'u': 398 what = LO_USERS; 399 nargs = 1; 400 break; 401 case 'q': 402 what = LO_QUEUES; 403 nargs = 1; 404 break; 405 case 'v': 406 what = LO_VOLUMES; 407 nargs = 1; 408 break; 409 default: 410 printf("Unknown command %s\n", argv[optind-1]); 411 help(); 412 } 413 for (i = 0; i < MAX_ARGS; i++) { 414 if (optind < argc) { 415 args[i] = argv[optind++]; 416 } else if (i < nargs) { 417 printf("Not enough arguments\n"); 418 help(); 419 return 1; 420 } else 421 break; 422 } 423 switch(what) { 424 case LO_SERVERS: 425 show_serverlist(args[0]); 426 wdone = 1; 427 break; 428 case LO_USERS: 429 show_userlist(args[0]); 430 wdone = 1; 431 break; 432 case LO_QUEUES: 433 show_queuelist(args[0], args[1]); 434 wdone = 1; 435 break; 436 case LO_VOLUMES: 437 list_volumes(args[0]); 438 wdone = 1; 439 break; 440 case LO_BINDERY: 441 list_bindery(args[0], args[1], args[2]); 442 wdone = 1; 443 break; 444 default: 445 help(); 446 } 447 return 0; 448} 449 450static void 451help(void) { 452 printf("\n"); 453 printf("usage: %s command [args]\n", __progname); 454 printf("where commands are:\n" 455 " b server user|group [pattern] list bindery objects on server\n" 456 " c display opened connections\n" 457 " s [server] display known servers\n" 458 " u server list logged-in users on server\n" 459 " q server [pattern] list print queues on server\n" 460 " v server list mounted volumes on a specified server\n" 461 "\n"); 462 exit(1); 463} 464