root/examples/libsmbclient/testbrowse2.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. smbitem_cmp
  2. smbitem_list_count
  3. smbitem_list_delete
  4. smbitem_list_sort
  5. smbc_auth_fn
  6. create_smbctx
  7. delete_smbctx
  8. get_smbitem_list
  9. print_smb_path
  10. recurse
  11. main

   1 /*
   2  * Alternate testbrowse utility provided by Mikhail Kshevetskiy.
   3  * This version tests use of multiple contexts.
   4  */
   5 
   6 #include <stdio.h>
   7 #include <stdlib.h>
   8 #include <malloc.h>
   9 #include <string.h>
  10 #include <libsmbclient.h>
  11 
  12 int     debuglevel      = 0;
  13 char    *workgroup      = "NT";
  14 char    *username       = "guest";
  15 char    *password       = "";
  16 
  17 typedef struct smbitem smbitem;
  18 typedef int(*qsort_cmp)(const void *, const void *);
  19 
  20 struct smbitem{
  21     smbitem     *next;
  22     int         type;
  23     char        name[1];
  24 };
  25 
  26 int smbitem_cmp(smbitem *elem1, smbitem *elem2){
     /* [<][>][^][v][top][bottom][index][help] */
  27     return strcmp(elem1->name, elem2->name);
  28 }
  29 
  30 int smbitem_list_count(smbitem *list){
     /* [<][>][^][v][top][bottom][index][help] */
  31     int count = 0;
  32     
  33     while(list != NULL){
  34         list = list->next;
  35         count++;
  36     }
  37     return count;
  38 }
  39 
  40 void smbitem_list_delete(smbitem *list){
     /* [<][>][^][v][top][bottom][index][help] */
  41     smbitem     *elem;
  42     
  43     while(list != NULL){
  44         elem = list;
  45         list = list->next;
  46         free(elem);
  47     }
  48 }
  49 
  50 smbitem* smbitem_list_sort(smbitem *list){
     /* [<][>][^][v][top][bottom][index][help] */
  51     smbitem     *item, **array;
  52     int         count, i;
  53 
  54     if ((count = smbitem_list_count(list)) == 0) return NULL;
  55     if ((array = malloc(count * sizeof(smbitem*))) == NULL){
  56         smbitem_list_delete(list);
  57         return NULL;
  58     }
  59     
  60     for(i = 0; i < count; i++){
  61         array[i] = list;
  62         list = list->next;
  63     }   
  64     qsort(array, count, sizeof(smbitem*), (qsort_cmp)smbitem_cmp);
  65     
  66     for(i = 0; i < count - 1; i++) array[i]->next = array[i + 1];
  67     array[count - 1]->next = NULL;
  68     
  69     list = array[0];
  70     free(array);
  71     return list;
  72 }
  73 
  74 void smbc_auth_fn(
     /* [<][>][^][v][top][bottom][index][help] */
  75                 const char      *server,
  76                 const char      *share,
  77                 char            *wrkgrp, int wrkgrplen,
  78                 char            *user,   int userlen,
  79                 char            *passwd, int passwdlen){
  80                 
  81     (void) server;
  82     (void) share;
  83     (void) wrkgrp;
  84     (void) wrkgrplen;
  85 
  86     strncpy(wrkgrp, workgroup, wrkgrplen - 1); wrkgrp[wrkgrplen - 1] = 0;
  87     strncpy(user, username, userlen - 1); user[userlen - 1] = 0;
  88     strncpy(passwd, password, passwdlen - 1); passwd[passwdlen - 1] = 0;
  89 }
  90 
  91 SMBCCTX* create_smbctx(){
     /* [<][>][^][v][top][bottom][index][help] */
  92     SMBCCTX     *ctx;
  93 
  94     if ((ctx = smbc_new_context()) == NULL) return NULL;
  95 
  96     smbc_setDebug(ctx, debuglevel);
  97     smbc_setFunctionAuthData(ctx, smbc_auth_fn);
  98 
  99     if (smbc_init_context(ctx) == NULL){
 100         smbc_free_context(ctx, 1);
 101         return NULL;
 102     }
 103 
 104     return ctx;
 105 }
 106 
 107 void delete_smbctx(SMBCCTX* ctx){
     /* [<][>][^][v][top][bottom][index][help] */
 108     smbc_getFunctionPurgeCachedServers(ctx)(ctx);
 109     smbc_free_context(ctx, 1);
 110 }
 111 
 112 smbitem* get_smbitem_list(SMBCCTX *ctx, char *smb_path){
     /* [<][>][^][v][top][bottom][index][help] */
 113     SMBCFILE            *fd;
 114     struct smbc_dirent  *dirent;
 115     smbitem             *list = NULL, *item;
 116 
 117     if ((fd = smbc_getFunctionOpendir(ctx)(ctx, smb_path)) == NULL)
 118         return NULL;
 119     while((dirent = smbc_getFunctionReaddir(ctx)(ctx, fd)) != NULL){
 120         if (strcmp(dirent->name, "") == 0) continue;
 121         if (strcmp(dirent->name, ".") == 0) continue;
 122         if (strcmp(dirent->name, "..") == 0) continue;
 123         
 124         if ((item = malloc(sizeof(smbitem) + strlen(dirent->name))) == NULL)
 125             continue;
 126         
 127         item->next = list;
 128         item->type = dirent->smbc_type;
 129         strcpy(item->name, dirent->name);
 130         list = item;
 131     }
 132     smbc_getFunctionClose(ctx)(ctx, fd);
 133     return /* smbitem_list_sort */ (list);    
 134         
 135 }
 136 
 137 void print_smb_path(char *group, char *path){
     /* [<][>][^][v][top][bottom][index][help] */
 138     if ((strlen(group) == 0) && (strlen(path) == 0)) printf("/\n");
 139     else if (strlen(path) == 0) printf("/%s\n", group);
 140     else{
 141         if (strlen(group) == 0) group = "(unknown_group)";
 142         printf("/%s/%s\n", group, path);
 143     }
 144 }
 145 
 146 void recurse(SMBCCTX *ctx, char *smb_group, char *smb_path, int maxlen){
     /* [<][>][^][v][top][bottom][index][help] */
 147     int         len;
 148     smbitem     *list, *item;
 149     SMBCCTX     *ctx1;
 150     
 151     len = strlen(smb_path);
 152     
 153     list = get_smbitem_list(ctx, smb_path);
 154     while(list != NULL){
 155         switch(list->type){
 156             case SMBC_WORKGROUP:
 157             case SMBC_SERVER:
 158                 if (list->type == SMBC_WORKGROUP){
 159                     print_smb_path(list->name, "");
 160                     smb_group = list->name;
 161                 }
 162                 else print_smb_path(smb_group, list->name);
 163                 
 164                 if (maxlen < 7 + strlen(list->name)) break;
 165                 strcpy(smb_path + 6, list->name);
 166                 if ((ctx1 = create_smbctx()) != NULL){
 167                     recurse(ctx1, smb_group, smb_path, maxlen);
 168                     delete_smbctx(ctx1);
 169                 }else{
 170                     recurse(ctx, smb_group, smb_path, maxlen);
 171                     smbc_getFunctionPurgeCachedServers(ctx)(ctx);
 172                 }
 173                 break;
 174             case SMBC_FILE_SHARE:
 175             case SMBC_DIR:
 176             case SMBC_FILE:
 177                 if (maxlen < len + strlen(list->name) + 2) break;
 178                 
 179                 smb_path[len] = '/';
 180                 strcpy(smb_path + len + 1, list->name);
 181                 print_smb_path(smb_group, smb_path + 6);
 182                 if (list->type != SMBC_FILE){
 183                     recurse(ctx, smb_group, smb_path, maxlen);
 184                     if (list->type == SMBC_FILE_SHARE)
 185                         smbc_getFunctionPurgeCachedServers(ctx)(ctx);
 186                 }
 187                 break;
 188         }
 189         item = list;
 190         list = list->next;
 191         free(item);
 192     }
 193     smb_path[len] = '\0';
 194 }
 195 
 196 int main(int argc, char *argv[]){
     /* [<][>][^][v][top][bottom][index][help] */
 197     int         i;
 198     SMBCCTX     *ctx;
 199     char        smb_path[32768] = "smb://";
 200 
 201     if ((ctx = create_smbctx()) == NULL){
 202         perror("Cant create samba context.");
 203         return 1;
 204     }
 205 
 206     if (argc == 1) recurse(ctx, "", smb_path, sizeof(smb_path));
 207     else for(i = 1; i < argc; i++){
 208         strncpy(smb_path + 6, argv[i], sizeof(smb_path) - 7);
 209         smb_path[sizeof(smb_path) - 1] = '\0';
 210         recurse(ctx, "", smb_path, sizeof(smb_path));
 211     }
 212     
 213     delete_smbctx(ctx);
 214     return 0;   
 215 }

/* [<][>][^][v][top][bottom][index][help] */