Patch: client.c: Easily parsable output for host list

Derrell.Lipman at UnwiredUniverse.com Derrell.Lipman at UnwiredUniverse.com
Fri Apr 26 15:32:02 GMT 2002


This patch adds the '-x' option, which generates the same data as -L, but
presents the data in a manner that's easy for scripts to parse.

Diff is against SAMBA_2_2 from CVS...

----------------------------------------------------------------------

--- client/client.c~	Mon Mar 18 17:08:00 2002
+++ client/client.c	Fri Apr 26 18:23:37 2002
@@ -50,6 +50,36 @@
 static int process_tok(fstring tok);
 static void cmd_help(void);
 
+/*
+ * Line Field Output allows for easily-parsable output when generating a list
+ * of shares available on a host.
+ *
+ * Output is tab-separated fields, with all fields pertaining to one record on
+ * a single line.  Field 1 will be one of the following, with the indicated
+ * additional fields:
+ *
+ * #D = Share type is "Disk"
+ *         Field 2 = Share name / Field 3 = Comment
+ * #P = Share type is "Printer"
+ *         Field 2 = Share name / Field 3 = Comment
+ * #V = Share type is "deVice"
+ *         Field 2 = Share name / Field 3 = Comment
+ * #I = Share type is "Ipc"
+ *         Field 2 = Share name / Field 3 = Comment
+ *
+ * #E = Error
+ *         Field 2 = Full error message
+ *
+ * #S = Server
+ *         Field 2 = Server name / Field 3 = Comment
+ *
+ * #W = Workgroup
+ *         Field 2 = Workgroup name / Field 3 = Master
+ *
+ * Selecting this option implies -L as well.
+ */
+static BOOL line_field_output = False;
+
 /* 30 second timeout on most commands */
 #define CLIENT_TIMEOUT (30*1000)
 #define SHORT_TIMEOUT (5*1000)
@@ -1800,23 +1830,32 @@
                       const char *comment, void *state)
 {
         fstring typestr;
+        char line_id_char;
 
         *typestr=0;
 
         switch (m)
         {
           case STYPE_DISKTREE:
-            fstrcpy(typestr,"Disk"); break;
+            fstrcpy(typestr,"Disk"); line_id_char = 'D'; break;
           case STYPE_PRINTQ:
-            fstrcpy(typestr,"Printer"); break;
+            fstrcpy(typestr,"Printer"); line_id_char = 'P'; break;
           case STYPE_DEVICE:
-            fstrcpy(typestr,"Device"); break;
+            fstrcpy(typestr,"Device"); line_id_char = 'V'; break;
           case STYPE_IPC:
-            fstrcpy(typestr,"IPC"); break;
+            fstrcpy(typestr,"IPC"); line_id_char = 'I'; break;
         }
 
-        printf("\t%-15.15s%-10.10s%s\n",
-               name, typestr,comment);
+        if (line_field_output)
+        {
+                printf("#%c\t%s\t%s\n",
+                       line_id_char, name, comment);
+        }
+        else
+        {
+                printf("\t%-15.15s%-10.10s%s\n",
+                       name, typestr,comment);
+        }
 }
 
 
@@ -1827,11 +1866,18 @@
 {
 	int ret;
 
-        printf("\n\tSharename      Type      Comment\n");
-        printf("\t---------      ----      -------\n");
+        if (! line_field_output)
+        {
+                printf("\n\tSharename      Type      Comment\n");
+                printf("\t---------      ----      -------\n");
+        }
 
 	if((ret = cli_RNetShareEnum(cli, browse_fn, NULL)) == -1)
-		printf("Error returning browse list: %s\n", cli_errstr(cli));
+        {
+                if (line_field_output)
+                        printf("#E\t");
+                printf("Error returning browse list: %s\n", cli_errstr(cli));
+        }
 
 	return (ret != -1);
 }
@@ -1842,7 +1888,22 @@
 static void server_fn(const char *name, uint32 m, 
                       const char *comment, void *state)
 {
-        printf("\t%-16.16s     %s\n", name, comment);
+        if (line_field_output)
+                printf("#S\t%s\t%s\n", name, comment);
+        else
+                printf("\t%-16.16s     %s\n", name, comment);
+}
+
+/****************************************************************************
+list a workgroup name
+****************************************************************************/
+static void workgroup_fn(const char *name, uint32 m, 
+                         const char *comment, void *state)
+{
+        if (line_field_output)
+                printf("#W\t%s\t%s\n", name, comment);
+        else
+                printf("\t%-16.16s     %s\n", name, comment);
 }
 
 /****************************************************************************
@@ -1852,15 +1913,21 @@
 {
 	if (!cli->server_domain) return False;
 
-        printf("\n\tServer               Comment\n");
-        printf("\t---------            -------\n");
+        if (! line_field_output)
+        {
+                printf("\n\tServer               Comment\n");
+                printf("\t---------            -------\n");
+        }
 
 	cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, server_fn, NULL);
 
-        printf("\n\tWorkgroup            Master\n");
-        printf("\t---------            -------\n");
+        if (! line_field_output)
+        {
+                printf("\n\tWorkgroup            Master\n");
+                printf("\t---------            -------\n");
+        }
 
-	cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM, server_fn, NULL);
+	cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM, workgroup_fn, NULL);
 	return True;
 }
 
@@ -2298,6 +2365,32 @@
   DEBUG(0,("\t-E                    write messages to stderr instead of stdout\n"));
   DEBUG(0,("\t-U username           set the network username\n"));
   DEBUG(0,("\t-L host               get a list of shares available on a host\n"));
+  DEBUG(0,("\t-x host               get a list of shares available on a host but\n"));
+  DEBUG(0,("\t                        print with the following parsable format:\n"));
+  DEBUG(0,("\t                        Output is tab-separated fields, with all fields\n"));
+  DEBUG(0,("\t                        pertaining to one record on a single line.\n"));
+  DEBUG(0,("\t                        Field 1 will be one of the following, with the\n"));
+  DEBUG(0,("\t                        indicated additional fields:\n"));
+  DEBUG(0,("\t                          #D = Share type is Disk\n"));
+  DEBUG(0,("\t                              Field 2 = Share name\n"));
+  DEBUG(0,("\t                              Field 3 = Comment\n"));
+  DEBUG(0,("\t                          #P = Share type is Printer\n"));
+  DEBUG(0,("\t                              Field 2 = Share name\n"));
+  DEBUG(0,("\t                              Field 3 = Comment\n"));
+  DEBUG(0,("\t                          #V = Share type is deVice\n"));
+  DEBUG(0,("\t                              Field 2 = Share name\n"));
+  DEBUG(0,("\t                              Field 3 = Comment\n"));
+  DEBUG(0,("\t                          #I = Share type is Ipc\n"));
+  DEBUG(0,("\t                              Field 2 = Share name\n"));
+  DEBUG(0,("\t                              Field 3 = Comment\n"));
+  DEBUG(0,("\t                          #E = Error\n"));
+  DEBUG(0,("\t                              Field 2 = Full error message\n"));
+  DEBUG(0,("\t                          #S = Server\n"));
+  DEBUG(0,("\t                              Field 2 = Server name\n"));
+  DEBUG(0,("\t                              Field 3 = Comment\n"));
+  DEBUG(0,("\t                          #W = Workgroup\n"));
+  DEBUG(0,("\t                              Field 2 = Workgroup name\n"));
+  DEBUG(0,("\t                              Field 3 = Master\n"));
   DEBUG(0,("\t-t terminal code      terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n"));
   DEBUG(0,("\t-m max protocol       set the max protocol level\n"));
   DEBUG(0,("\t-A filename           get the credentials from a file\n"));
@@ -2607,7 +2700,7 @@
 	}
 
 	while ((opt = 
-		getopt(argc, argv,"s:O:R:M:i:Nn:d:Pp:l:hI:EU:L:t:m:W:T:D:c:b:A:")) != EOF) {
+		getopt(argc, argv,"s:O:R:M:i:Nn:d:Pp:l:hI:EU:x:L:t:m:W:T:D:c:b:A:")) != EOF) {
 		switch (opt) {
 		case 's':
 			pstrcpy(servicesf, optarg);
@@ -2736,6 +2829,9 @@
 			}
 			break;
 
+                case 'x':
+                        line_field_output = True;
+                        /* fall through */
 		case 'L':
 			p = optarg;
 			while(*p == '\\' || *p == '/')




More information about the samba-technical mailing list