r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text
[samba.git] / source3 / utils / nmblookup.c
index 7e0ed4a2030287d5176de9d57e3c69c35e5d6962..8bb80239174e5e273a912b19a524f0e51b19aa94 100644 (file)
@@ -2,10 +2,11 @@
    Unix SMB/CIFS implementation.
    NBT client - used to lookup netbios names
    Copyright (C) Andrew Tridgell 1994-1998
+   Copyright (C) Jelmer Vernooij 2003 (Conversion to popt)
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
 */
 
-#define NO_SYSLOG
-
 #include "includes.h"
 
 extern BOOL AllowDebugChange;
@@ -54,31 +52,6 @@ static BOOL open_sockets(void)
   return True;
 }
 
-
-/****************************************************************************
-usage on the program
-****************************************************************************/
-static void usage(void)
-{
-  d_printf("Usage: nmblookup [options] name\n");
-  d_printf("Version %s\n",VERSION);
-  d_printf("\t-d debuglevel         set the debuglevel\n");
-  d_printf("\t-B broadcast address  the address to use for broadcasts\n");
-  d_printf("\t-f                    list the NMB flags returned\n");
-  d_printf("\t-U unicast   address  the address to use for unicast\n");
-  d_printf("\t-M                    searches for a master browser\n");
-  d_printf("\t-R                    set recursion desired in packet\n");
-  d_printf("\t-S                    lookup node status as well\n");
-  d_printf("\t-T                    translate IP addresses into names\n");
-  d_printf("\t-r                    Use root port 137 (Win95 only replies to this)\n");
-  d_printf("\t-A                    Do a node status on <name> as an IP Address\n");
-  d_printf("\t-i NetBIOS scope      Use the given NetBIOS scope for name queries\n");
-  d_printf("\t-s smb.conf file      Use the given path to the smb.conf file\n");
-  d_printf("\t-h                    Print this help message.\n");
-  d_printf("\n  If you specify -M and name is \"-\", nmblookup looks up __MSBROWSE__<01>\n");
-  d_printf("\n");
-}
-
 /****************************************************************************
 turn a node status flags field into a string
 ****************************************************************************/
@@ -125,15 +98,16 @@ static void do_node_status(int fd, const char *name, int type, struct in_addr ip
 {
        struct nmb_name nname;
        int count, i, j;
-       struct node_status *status;
+       NODE_STATUS_STRUCT *status;
+       struct node_status_extra extra;
        fstring cleanname;
 
        d_printf("Looking up status of %s\n",inet_ntoa(ip));
        make_nmb_name(&nname, name, type);
-       status = node_status_query(fd,&nname,ip, &count);
+       status = node_status_query(fd,&nname,ip, &count, &extra);
        if (status) {
                for (i=0;i<count;i++) {
-                       fstrcpy(cleanname, status[i].name);
+                       pull_ascii_fstring(cleanname, status[i].name);
                        for (j=0;cleanname[j];j++) {
                                if (!isprint((int)cleanname[j])) cleanname[j] = '.';
                        }
@@ -141,9 +115,15 @@ static void do_node_status(int fd, const char *name, int type, struct in_addr ip
                               cleanname,status[i].type,
                               node_status_flags(status[i].flags));
                }
+               d_printf("\n\tMAC Address = %02X-%02X-%02X-%02X-%02X-%02X\n",
+                               extra.mac_addr[0], extra.mac_addr[1],
+                               extra.mac_addr[2], extra.mac_addr[3],
+                               extra.mac_addr[4], extra.mac_addr[5]);
+               d_printf("\n");
                SAFE_FREE(status);
+       } else {
+               d_printf("No reply from %s\n\n",inet_ntoa(ip));
        }
-       d_printf("\n");
 }
 
 
@@ -188,13 +168,12 @@ static BOOL query_one(const char *lookup, unsigned int lookup_type)
                        }
                }
                d_printf("%s %s<%02x>\n",inet_ntoa(ip_list[j]),lookup, lookup_type);
-       }
-
-       /* We can only do find_status if the ip address returned
-          was valid - ie. name_query returned true.
-       */
-       if (find_status) {
-               do_node_status(ServerFD, lookup, lookup_type, ip_list[0]);
+               /* We can only do find_status if the ip address returned
+                  was valid - ie. name_query returned true.
+                */
+               if (find_status) {
+                       do_node_status(ServerFD, lookup, lookup_type, ip_list[j]);
+               }
        }
 
        safe_free(ip_list);
@@ -211,130 +190,108 @@ int main(int argc,char *argv[])
   int opt;
   unsigned int lookup_type = 0x0;
   fstring lookup;
-  extern int optind;
-  extern char *optarg;
-  BOOL find_master=False;
-  int i;
-  BOOL lookup_by_ip = False;
-  int commandline_debuglevel = -2;
-
-  DEBUGLEVEL = 1;
-  /* Prevent smb.conf setting from overridding */
-  AllowDebugChange = False;
-
+  static BOOL find_master=False;
+  static BOOL lookup_by_ip = False;
+  poptContext pc;
+
+  struct poptOption long_options[] = {
+         POPT_AUTOHELP
+         { "broadcast", 'B', POPT_ARG_STRING, NULL, 'B', "Specify address to use for broadcasts", "BROADCAST-ADDRESS" },
+         { "flags", 'f', POPT_ARG_VAL, &give_flags, True, "List the NMB flags returned" },
+         { "unicast", 'U', POPT_ARG_STRING, NULL, 'U', "Specify address to use for unicast" },
+         { "master-browser", 'M', POPT_ARG_VAL, &find_master, True, "Search for a master browser" },
+         { "recursion", 'R', POPT_ARG_VAL, &recursion_desired, True, "Set recursion desired in package" },
+         { "status", 'S', POPT_ARG_VAL, &find_status, True, "Lookup node status as well" },
+         { "translate", 'T', POPT_ARG_NONE, NULL, 'T', "Translate IP addresses into names" },
+         { "root-port", 'r', POPT_ARG_VAL, &RootPort, True, "Use root port 137 (Win95 only replies to this)" },
+         { "lookup-by-ip", 'A', POPT_ARG_VAL, &lookup_by_ip, True, "Do a node status on <name> as an IP Address" },
+         POPT_COMMON_SAMBA
+         POPT_COMMON_CONNECTION
+         { 0, 0, 0, 0 }
+  };
+       
   *lookup = 0;
 
+  load_case_tables();
+
   setup_logging(argv[0],True);
 
-  while ((opt = getopt(argc, argv, "d:fB:U:i:s:SMrhART")) != EOF)
-    switch (opt)
-      {
-      case 'B':
-       bcast_addr = *interpret_addr2(optarg);
-       got_bcast = True;
-       use_bcast = True;
-       break;
-      case 'f':
-       give_flags = True;
-       break;
-      case 'U':
-       bcast_addr = *interpret_addr2(optarg);
-       got_bcast = True;
-       use_bcast = False;
-       break;
-      case 'T':
-        translate_addresses = !translate_addresses;
-       break;
-      case 'i':
-       set_global_scope(optarg);
-       break;
-      case 'M':
-       find_master = True;
-       break;
-      case 'S':
-       find_status = True;
-       break;
-      case 'R':
-       recursion_desired = True;
-       break;
-      case 'd':
-       commandline_debuglevel = DEBUGLEVEL = atoi(optarg);
-       break;
-      case 's':
-       pstrcpy(dyn_CONFIGFILE, optarg);
-       break;
-      case 'r':
-        RootPort = True;
-        break;
-      case 'h':
-       usage();
-       exit(0);
-       break;
-      case 'A':
-        lookup_by_ip = True;
-        break;
-      default:
-       usage();
-       exit(1);
-      }
-
-  if (argc < 2) {
-    usage();
-    exit(1);
+  pc = poptGetContext("nmblookup", argc, (const char **)argv, long_options, 
+                                         POPT_CONTEXT_KEEP_FIRST);
+
+  poptSetOtherOptionHelp(pc, "<NODE> ...");
+
+  while ((opt = poptGetNextOpt(pc)) != -1) {
+         switch (opt) {
+         case 'B':
+                 bcast_addr = *interpret_addr2(poptGetOptArg(pc));
+                 got_bcast = True;
+                 use_bcast = True;
+                 break;
+         case 'U':
+                 bcast_addr = *interpret_addr2(poptGetOptArg(pc));
+                 got_bcast = True;
+                 use_bcast = False;
+                 break;
+         case 'T':
+                 translate_addresses = !translate_addresses;
+                 break;
+         }
   }
 
-  if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
-    fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
-  }
+  poptGetArg(pc); /* Remove argv[0] */
 
-  /*
-   * Ensure we reset DEBUGLEVEL if someone specified it
-   * on the command line.
-   */
+  if(!poptPeekArg(pc)) { 
+         poptPrintUsage(pc, stderr, 0);
+         exit(1);
+  }
 
-  if(commandline_debuglevel != -2)
-    DEBUGLEVEL = commandline_debuglevel;
+  if (!lp_load(dyn_CONFIGFILE,True,False,False,True)) {
+         fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
+  }
 
   load_interfaces();
   if (!open_sockets()) return(1);
 
-  for (i=optind;i<argc;i++)
+  while(poptPeekArg(pc))
   {
-      char *p;
-      struct in_addr ip;
-
-      fstrcpy(lookup,argv[i]);
-
-      if(lookup_by_ip)
-      {
-        fstrcpy(lookup,"*");
-        ip = *interpret_addr2(argv[i]);
-       do_node_status(ServerFD, lookup, lookup_type, ip);
-        continue;
-      }
-
-      if (find_master) {
-       if (*lookup == '-') {
-         fstrcpy(lookup,"\01\02__MSBROWSE__\02");
-         lookup_type = 1;
-       } else {
-         lookup_type = 0x1d;
-       }
-      }
-
-      p = strchr_m(lookup,'#');
-      if (p) {
-        *p = '\0';
-        sscanf(++p,"%x",&lookup_type);
-      }
-
-      if (!query_one(lookup, lookup_type)) {
-       d_printf( "name_query failed to find name %s", lookup );
-        if( 0 != lookup_type )
-          d_printf( "#%02x", lookup_type );
-        d_printf( "\n" );
-      }
+         char *p;
+         struct in_addr ip;
+
+         fstrcpy(lookup,poptGetArg(pc));
+
+         if(lookup_by_ip)
+         {
+                 ip = *interpret_addr2(lookup);
+                 fstrcpy(lookup,"*");
+                 do_node_status(ServerFD, lookup, lookup_type, ip);
+                 continue;
+         }
+
+         if (find_master) {
+                 if (*lookup == '-') {
+                         fstrcpy(lookup,"\01\02__MSBROWSE__\02");
+                         lookup_type = 1;
+                 } else {
+                         lookup_type = 0x1d;
+                 }
+         }
+
+         p = strchr_m(lookup,'#');
+         if (p) {
+                 *p = '\0';
+                 sscanf(++p,"%x",&lookup_type);
+         }
+
+         if (!query_one(lookup, lookup_type)) {
+                 d_printf( "name_query failed to find name %s", lookup );
+                 if( 0 != lookup_type )
+                         d_printf( "#%02x", lookup_type );
+                 d_printf( "\n" );
+         }
   }
-  
+
+  poptFreeContext(pc);
+
   return(0);
 }