support NetServerEnum in smbwrapper. You can now do a ls in /smb/ and
authorAndrew Tridgell <tridge@samba.org>
Sun, 4 Oct 1998 11:25:06 +0000 (11:25 +0000)
committerAndrew Tridgell <tridge@samba.org>
Sun, 4 Oct 1998 11:25:06 +0000 (11:25 +0000)
it will list all servers in your workgroup. You can set your workgroup
with the SMBW_WORKGROUP environment variable.

source/include/proto.h
source/libsmb/clientgen.c
source/libsmb/namequery.c
source/smbwrapper/smbw.c
source/smbwrapper/smbw_dir.c

index f2b484ceec10a868b9b9fb3bacf0dff82ecfbf7a..86792a224577b3691a97806fdcc8980313acf35f 100644 (file)
@@ -365,7 +365,7 @@ BOOL cli_api(struct cli_state *cli,
 BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation);
 BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *));
 BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
-                      void (*fn)(char *, uint32, char *));
+                      void (*fn)(const char *, uint32, const char *));
 BOOL cli_session_setup(struct cli_state *cli, 
                       char *user, 
                       char *pass, int passlen,
@@ -405,7 +405,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo
                              char *old_password);
 BOOL cli_negprot(struct cli_state *cli);
 BOOL cli_session_request(struct cli_state *cli,
-                       struct nmb_name *calling, struct nmb_name *called);
+                        struct nmb_name *calling, struct nmb_name *called);
 BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip);
 BOOL cli_initialise(struct cli_state *cli);
 void cli_shutdown(struct cli_state *cli);
@@ -448,6 +448,7 @@ FILE *startlmhosts(char *fname);
 BOOL getlmhostsent( FILE *fp, char *name, int *name_type, struct in_addr *ipaddr);
 void endlmhosts(FILE *fp);
 BOOL resolve_name(char *name, struct in_addr *return_ip);
+BOOL find_master(char *group, struct in_addr *master_ip);
 
 /*The following definitions come from  libsmb/nmblib.c  */
 
index 20c0c361664c7f6bab5f7ef3c4dbb93223f1b2bd..6b07eb65b335196947eea4464cdfb5f781043dd6 100644 (file)
@@ -535,7 +535,7 @@ The callback function takes 3 arguments: the machine name, the server type and
 the comment.
 ****************************************************************************/
 BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
-                      void (*fn)(char *, uint32, char *))
+                      void (*fn)(const char *, uint32, const char *))
 {
        char *rparam = NULL;
        char *rdata = NULL;
index f988504bba5141ba96556352e476c4b7ee72d1cf..a9da735f362cd9bffcf8c7a9534154350a31d826 100644 (file)
@@ -420,7 +420,6 @@ void endlmhosts(FILE *fp)
  or NetBIOS name. This uses the name switch in the
  smb.conf to determine the order of name resolution.
 *********************************************************/
-
 BOOL resolve_name(char *name, struct in_addr *return_ip)
 {
   int i;
@@ -573,3 +572,43 @@ BOOL resolve_name(char *name, struct in_addr *return_ip)
 
   return False;
 }
+
+
+
+/********************************************************
+find the IP address of the master browser for a workgroup
+*********************************************************/
+BOOL find_master(char *group, struct in_addr *master_ip)
+{
+       int sock;
+       struct in_addr *iplist = NULL;
+        int count, i;
+        int num_interfaces = iface_count();
+
+       sock = open_socket_in( SOCK_DGRAM, 0, 3,
+                              interpret_addr(lp_socket_address()) );
+
+       if (sock == -1) return False;
+
+        set_socket_options(sock,"SO_BROADCAST");
+
+        /*
+         * Lookup the name on all the interfaces, return on
+         * the first successful match.
+         */
+        for( i = 0; i < num_interfaces; i++) {
+               struct in_addr sendto_ip;
+               /* Done this way to fix compiler error on IRIX 5.x */
+               sendto_ip = *iface_bcast(*iface_n_ip(i));
+               iplist = name_query(sock, group, 0x1D, True, False, 
+                                   sendto_ip, &count, NULL);
+               if(iplist != NULL) {
+                       *master_ip = iplist[0];
+                       free((char *)iplist);
+                       close(sock);
+                       return True;
+               }
+        }
+        close(sock);
+       return False;
+}
index 054b694c4154c14f5cbad446626b946dec002d7f..650d0a08f584f04e1c5f661f35358a285799e556 100644 (file)
@@ -207,7 +207,7 @@ char *smbw_parse_path(const char *fname, char *server, char *share, char *path)
 {
        static pstring s;
        char *p, *p2;
-       int len;
+       int len = strlen(SMBW_PREFIX)-1;
 
        *server = *share = *path = 0;
 
@@ -221,9 +221,12 @@ char *smbw_parse_path(const char *fname, char *server, char *share, char *path)
        DEBUG(5,("cleaned %s (fname=%s cwd=%s)\n", 
                 s, fname, smb_cwd));
 
-       if (strncmp(s,SMBW_PREFIX,strlen(SMBW_PREFIX))) return s;
+       if (strncmp(s,SMBW_PREFIX,len) || 
+           (s[len] != '/' && s[len] != 0)) return s;
+
+       p = s + len;
+       if (*p == '/') p++;
 
-       p = s + strlen(SMBW_PREFIX);
        p2 = strchr(p,'/');
 
        if (p2) {
@@ -239,6 +242,11 @@ char *smbw_parse_path(const char *fname, char *server, char *share, char *path)
 
        p = p2;
        if (!p) {
+               if (len == 0) {
+                       char *workgroup = getenv("SMBW_WORKGROUP");
+                       if (!workgroup) workgroup = lp_workgroup();
+                       slprintf(server,sizeof(fstring)-1, "%s#1D", workgroup);
+               }
                fstrcpy(share,"IPC$");
                pstrcpy(path,"");
                goto ok;
@@ -336,6 +344,8 @@ struct smbw_server *smbw_server(char *server, char *share)
        char *password;
        char *workgroup;
        struct nmb_name called, calling;
+       char *p, *server_n = server;
+       fstring group;
 
        ZERO_STRUCT(c);
 
@@ -364,8 +374,21 @@ struct smbw_server *smbw_server(char *server, char *share)
        make_nmb_name(&called , server, 0x20, "");
 
  again:
+       if ((p=strchr(server_n,'#'))) {
+               struct in_addr ip;
+               fstrcpy(group, server_n);
+               p = strchr(group,'#');
+               *p = 0;
+               if (!find_master(group, &ip)) {
+                       errno = ENOENT;
+                       return NULL;
+               }
+               fstrcpy(group, inet_ntoa(ip));
+               server_n = group;
+       }
+
        /* have to open a new connection */
-       if (!cli_initialise(&c) || !cli_connect(&c, server, NULL)) {
+       if (!cli_initialise(&c) || !cli_connect(&c, server_n, NULL)) {
                errno = ENOENT;
                return NULL;
        }
index 3fdaebec5a279f021353b332627796c750294191..d794944b1a88db70474576809d91d8901a6605a4 100644 (file)
@@ -112,6 +112,23 @@ static void smbw_share_add(const char *share, uint32 type, const char *comment)
 }
 
 
+/***************************************************** 
+add a server to a directory listing
+*******************************************************/
+static void smbw_server_add(const char *name, uint32 type, 
+                           const char *comment)
+{
+       struct file_info finfo;
+
+       ZERO_STRUCT(finfo);
+
+       pstrcpy(finfo.name, name);
+       finfo.mode = aRONLY | aDIR;     
+
+       smbw_dir_add(&finfo);
+}
+
+
 /***************************************************** 
 add a entry to a directory listing
 *******************************************************/
@@ -145,7 +162,7 @@ int smbw_dir_open(const char *fname)
        struct smbw_dir *dir=NULL;
        pstring mask;
        int fd;
-       char *s;
+       char *s, *p;
 
        DEBUG(4,("%s\n", __FUNCTION__));
 
@@ -181,7 +198,13 @@ int smbw_dir_open(const char *fname)
        slprintf(mask, sizeof(mask)-1, "%s\\*", path);
        string_sub(mask,"\\\\","\\");
 
-       if (strcmp(srv->cli.dev,"IPC") == 0) {
+       if ((p=strstr(srv->server_name,"#1D"))) {
+               DEBUG(4,("doing NetServerEnum\n"));
+               *p = 0;
+               cli_NetServerEnum(&srv->cli, srv->server_name, SV_TYPE_ALL,
+                                 smbw_server_add);
+               *p = '#';
+       } else if (strcmp(srv->cli.dev,"IPC") == 0) {
                DEBUG(4,("doing NetShareEnum\n"));
                if (cli_RNetShareEnum(&srv->cli, smbw_share_add) < 0) {
                        errno = smbw_errno(&srv->cli);