2 * Alternate testbrowse utility provided by Mikhail Kshevetskiy.
3 * This version tests use of multiple contexts.
10 #include <libsmbclient.h>
13 char *workgroup
= "NT";
14 char *username
= "guest";
17 typedef struct smbitem smbitem
;
18 typedef int(*qsort_cmp
)(const void *, const void *);
26 int smbitem_cmp(smbitem
*elem1
, smbitem
*elem2
){
27 return strcmp(elem1
->name
, elem2
->name
);
30 int smbitem_list_count(smbitem
*list
){
40 void smbitem_list_delete(smbitem
*list
){
50 smbitem
* smbitem_list_sort(smbitem
*list
){
51 smbitem
*item
, **array
;
54 if ((count
= smbitem_list_count(list
)) == 0) return NULL
;
55 if ((array
= malloc(count
* sizeof(smbitem
*))) == NULL
){
56 smbitem_list_delete(list
);
60 for(i
= 0; i
< count
; i
++){
64 qsort(array
, count
, sizeof(smbitem
*), (qsort_cmp
)smbitem_cmp
);
66 for(i
= 0; i
< count
- 1; i
++) array
[i
]->next
= array
[i
+ 1];
67 array
[count
- 1]->next
= NULL
;
77 char *wrkgrp
, int wrkgrplen
,
78 char *user
, int userlen
,
79 char *passwd
, int passwdlen
){
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;
91 SMBCCTX
* create_smbctx(){
94 if ((ctx
= smbc_new_context()) == NULL
) return NULL
;
96 ctx
->debug
= debuglevel
;
97 ctx
->callbacks
.auth_fn
= smbc_auth_fn
;
99 if (smbc_init_context(ctx
) == NULL
){
100 smbc_free_context(ctx
, 1);
107 void delete_smbctx(SMBCCTX
* ctx
){
108 ctx
->callbacks
.purge_cached_fn(ctx
);
109 smbc_free_context(ctx
, 1);
112 smbitem
* get_smbitem_list(SMBCCTX
*ctx
, char *smb_path
){
114 struct smbc_dirent
*dirent
;
115 smbitem
*list
= NULL
, *item
;
117 if ((fd
= ctx
->opendir(ctx
, smb_path
)) == NULL
) return NULL
;
118 while((dirent
= ctx
->readdir(ctx
, fd
)) != NULL
){
119 if (strcmp(dirent
->name
, "") == 0) continue;
120 if (strcmp(dirent
->name
, ".") == 0) continue;
121 if (strcmp(dirent
->name
, "..") == 0) continue;
123 if ((item
= malloc(sizeof(smbitem
) + strlen(dirent
->name
))) == NULL
)
127 item
->type
= dirent
->smbc_type
;
128 strcpy(item
->name
, dirent
->name
);
131 ctx
->close_fn(ctx
, fd
);
132 return /* smbitem_list_sort */ (list
);
136 void print_smb_path(char *group
, char *path
){
137 if ((strlen(group
) == 0) && (strlen(path
) == 0)) printf("/\n");
138 else if (strlen(path
) == 0) printf("/%s\n", group
);
140 if (strlen(group
) == 0) group
= "(unknown_group)";
141 printf("/%s/%s\n", group
, path
);
145 void recurse(SMBCCTX
*ctx
, char *smb_group
, char *smb_path
, int maxlen
){
147 smbitem
*list
, *item
;
150 len
= strlen(smb_path
);
152 list
= get_smbitem_list(ctx
, smb_path
);
157 if (list
->type
== SMBC_WORKGROUP
){
158 print_smb_path(list
->name
, "");
159 smb_group
= list
->name
;
161 else print_smb_path(smb_group
, list
->name
);
163 if (maxlen
< 7 + strlen(list
->name
)) break;
164 strcpy(smb_path
+ 6, list
->name
);
165 if ((ctx1
= create_smbctx()) != NULL
){
166 recurse(ctx1
, smb_group
, smb_path
, maxlen
);
169 recurse(ctx
, smb_group
, smb_path
, maxlen
);
170 ctx
->callbacks
.purge_cached_fn(ctx
);
173 case SMBC_FILE_SHARE
:
176 if (maxlen
< len
+ strlen(list
->name
) + 2) break;
179 strcpy(smb_path
+ len
+ 1, list
->name
);
180 print_smb_path(smb_group
, smb_path
+ 6);
181 if (list
->type
!= SMBC_FILE
){
182 recurse(ctx
, smb_group
, smb_path
, maxlen
);
183 if (list
->type
== SMBC_FILE_SHARE
)
184 ctx
->callbacks
.purge_cached_fn(ctx
);
192 smb_path
[len
] = '\0';
195 int main(int argc
, char *argv
[]){
198 char smb_path
[32768] = "smb://";
200 if ((ctx
= create_smbctx()) == NULL
){
201 perror("Cant create samba context.");
205 if (argc
== 1) recurse(ctx
, "", smb_path
, sizeof(smb_path
));
206 else for(i
= 1; i
< argc
; i
++){
207 strncpy(smb_path
+ 6, argv
[i
], sizeof(smb_path
) - 7);
208 smb_path
[sizeof(smb_path
) - 1] = '\0';
209 recurse(ctx
, "", smb_path
, sizeof(smb_path
));