2 * Alternate testbrowse utility provided by Mikhail Kshevetskiy.
3 * This version tests use of multiple contexts.
9 #include <libsmbclient.h>
12 const char *workgroup
= "NT";
13 const char *username
= "guest";
14 const char *password
= "";
16 typedef struct smbitem smbitem
;
17 typedef int(*qsort_cmp
)(const void *, const void *);
25 static void smbc_auth_fn(
28 char *wrkgrp
, int wrkgrplen
,
29 char *user
, int userlen
,
30 char *passwd
, int passwdlen
){
37 strncpy(wrkgrp
, workgroup
, wrkgrplen
- 1); wrkgrp
[wrkgrplen
- 1] = 0;
38 strncpy(user
, username
, userlen
- 1); user
[userlen
- 1] = 0;
39 strncpy(passwd
, password
, passwdlen
- 1); passwd
[passwdlen
- 1] = 0;
42 static SMBCCTX
* create_smbctx(void){
45 if ((ctx
= smbc_new_context()) == NULL
) return NULL
;
47 smbc_setDebug(ctx
, debuglevel
);
48 smbc_setFunctionAuthData(ctx
, smbc_auth_fn
);
50 if (smbc_init_context(ctx
) == NULL
){
51 smbc_free_context(ctx
, 1);
58 static void delete_smbctx(SMBCCTX
* ctx
){
59 smbc_getFunctionPurgeCachedServers(ctx
)(ctx
);
60 smbc_free_context(ctx
, 1);
63 static smbitem
* get_smbitem_list(SMBCCTX
*ctx
, char *smb_path
){
65 struct smbc_dirent
*dirent
;
66 smbitem
*list
= NULL
, *item
;
68 if ((fd
= smbc_getFunctionOpendir(ctx
)(ctx
, smb_path
)) == NULL
)
70 while((dirent
= smbc_getFunctionReaddir(ctx
)(ctx
, fd
)) != NULL
){
72 if (strcmp(dirent
->name
, "") == 0) continue;
73 if (strcmp(dirent
->name
, ".") == 0) continue;
74 if (strcmp(dirent
->name
, "..") == 0) continue;
76 slen
= strlen(dirent
->name
)+1;
77 if ((item
= malloc(sizeof(smbitem
) + slen
)) == NULL
)
81 item
->type
= dirent
->smbc_type
;
82 memcpy(item
->name
, dirent
->name
, slen
);
85 smbc_getFunctionClose(ctx
)(ctx
, fd
);
86 return /* smbitem_list_sort */ (list
);
89 static void print_smb_path(const char *group
, const char *path
){
90 if ((strlen(group
) == 0) && (strlen(path
) == 0)) printf("/\n");
91 else if (strlen(path
) == 0) printf("/%s\n", group
);
93 if (strlen(group
) == 0) group
= "(unknown_group)";
94 printf("/%s/%s\n", group
, path
);
98 static void recurse(SMBCCTX
*ctx
, const char *smb_group
, char *smb_path
, int maxlen
){
100 smbitem
*list
, *item
;
103 len
= strlen(smb_path
);
105 list
= get_smbitem_list(ctx
, smb_path
);
110 if (list
->type
== SMBC_WORKGROUP
){
111 print_smb_path(list
->name
, "");
112 smb_group
= list
->name
;
114 else print_smb_path(smb_group
, list
->name
);
116 if (maxlen
< 7 + strlen(list
->name
)) break;
117 strncpy(smb_path
+ 6, list
->name
, maxlen
- 6);
118 smb_path
[maxlen
-1] = '\0';
119 if ((ctx1
= create_smbctx()) != NULL
){
120 recurse(ctx1
, smb_group
, smb_path
, maxlen
);
123 recurse(ctx
, smb_group
, smb_path
, maxlen
);
124 smbc_getFunctionPurgeCachedServers(ctx
)(ctx
);
127 case SMBC_FILE_SHARE
:
130 if (maxlen
< len
+ strlen(list
->name
) + 2) break;
133 strncpy(smb_path
+ len
+ 1, list
->name
, maxlen
- len
- 1);
134 smb_path
[maxlen
-1] = '\0';
135 print_smb_path(smb_group
, smb_path
+ 6);
136 if (list
->type
!= SMBC_FILE
){
137 recurse(ctx
, smb_group
, smb_path
, maxlen
);
138 if (list
->type
== SMBC_FILE_SHARE
)
139 smbc_getFunctionPurgeCachedServers(ctx
)(ctx
);
147 smb_path
[len
] = '\0';
150 int main(int argc
, char *argv
[]){
153 char smb_path
[32768] = "smb://";
155 if ((ctx
= create_smbctx()) == NULL
){
156 perror("Can't create samba context.");
160 if (argc
== 1) recurse(ctx
, "", smb_path
, sizeof(smb_path
));
161 else for(i
= 1; i
< argc
; i
++){
162 strncpy(smb_path
+ 6, argv
[i
], sizeof(smb_path
) - 7);
163 smb_path
[sizeof(smb_path
) - 1] = '\0';
164 recurse(ctx
, "", smb_path
, sizeof(smb_path
));