summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerrell Lipman <derrell@samba.org>2005-12-06 17:09:44 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:05:44 -0500
commit44293df2aeaeccb1e2cca18bb7d61534a5e07b1a (patch)
treed72999c8185bddd4193b606354538459ae76c7bb
parenta2bac34183ce003a194f741c62e69d6674516b07 (diff)
downloadsamba-44293df2aeaeccb1e2cca18bb7d61534a5e07b1a.tar.gz
samba-44293df2aeaeccb1e2cca18bb7d61534a5e07b1a.tar.bz2
samba-44293df2aeaeccb1e2cca18bb7d61534a5e07b1a.zip
r12098: r10797@cabra: derrell | 2005-12-06 12:09:00 -0500
fixed another memory leak and reverted an (incorrect) fix from yesterday (This used to be commit 8a86d7bddc291da094d060fbe185f071ffdbddd8)
-rw-r--r--examples/libsmbclient/Makefile5
-rw-r--r--examples/libsmbclient/testbrowse2.c214
-rw-r--r--source3/libsmb/libsmbclient.c14
3 files changed, 228 insertions, 5 deletions
diff --git a/examples/libsmbclient/Makefile b/examples/libsmbclient/Makefile
index 7e893fd488..c324a578d1 100644
--- a/examples/libsmbclient/Makefile
+++ b/examples/libsmbclient/Makefile
@@ -15,6 +15,7 @@ TESTS= testsmbc \
tree \
testacl \
testbrowse \
+ testbrowse2 \
teststat \
testchmod \
testutime \
@@ -38,6 +39,10 @@ testbrowse: testbrowse.o
@echo Linking testbrowse
@$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -lsmbclient -lpopt $<
+testbrowse2: testbrowse2.o
+ @echo Linking testbrowse2
+ @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -lsmbclient -lpopt $<
+
teststat: teststat.o
@echo Linking teststat
@$(CC) $(CFLAGS) $(LDFLAGS) -o $@ /usr/local/samba/lib/libsmbclient.so -lpopt $<
diff --git a/examples/libsmbclient/testbrowse2.c b/examples/libsmbclient/testbrowse2.c
new file mode 100644
index 0000000000..a3d2cf3b8e
--- /dev/null
+++ b/examples/libsmbclient/testbrowse2.c
@@ -0,0 +1,214 @@
+/*
+ * Alternate testbrowse utility provided by Mikhail Kshevetskiy.
+ * This version tests use of multiple contexts.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <string.h>
+#include <libsmbclient.h>
+
+int debuglevel = 0;
+char *workgroup = "NT";
+char *username = "guest";
+char *password = "";
+
+typedef struct smbitem smbitem;
+typedef int(*qsort_cmp)(const void *, const void *);
+
+struct smbitem{
+ smbitem *next;
+ int type;
+ char name[1];
+};
+
+int smbitem_cmp(smbitem *elem1, smbitem *elem2){
+ return strcmp(elem1->name, elem2->name);
+}
+
+int smbitem_list_count(smbitem *list){
+ int count = 0;
+
+ while(list != NULL){
+ list = list->next;
+ count++;
+ }
+ return count;
+}
+
+void smbitem_list_delete(smbitem *list){
+ smbitem *elem;
+
+ while(list != NULL){
+ elem = list;
+ list = list->next;
+ free(elem);
+ }
+}
+
+smbitem* smbitem_list_sort(smbitem *list){
+ smbitem *item, **array;
+ int count, i;
+
+ if ((count = smbitem_list_count(list)) == 0) return NULL;
+ if ((array = malloc(count * sizeof(smbitem*))) == NULL){
+ smbitem_list_delete(list);
+ return NULL;
+ }
+
+ for(i = 0; i < count; i++){
+ array[i] = list;
+ list = list->next;
+ }
+ qsort(array, count, sizeof(smbitem*), (qsort_cmp)smbitem_cmp);
+
+ for(i = 0; i < count - 1; i++) array[i]->next = array[i + 1];
+ array[count - 1]->next = NULL;
+
+ list = array[0];
+ free(array);
+ return list;
+}
+
+void smbc_auth_fn(
+ const char *server,
+ const char *share,
+ char *wrkgrp, int wrkgrplen,
+ char *user, int userlen,
+ char *passwd, int passwdlen){
+
+ (void) server;
+ (void) share;
+ (void) wrkgrp;
+ (void) wrkgrplen;
+
+ strncpy(wrkgrp, workgroup, wrkgrplen - 1); wrkgrp[wrkgrplen - 1] = 0;
+ strncpy(user, username, userlen - 1); user[userlen - 1] = 0;
+ strncpy(passwd, password, passwdlen - 1); passwd[passwdlen - 1] = 0;
+}
+
+SMBCCTX* create_smbctx(){
+ SMBCCTX *ctx;
+
+ if ((ctx = smbc_new_context()) == NULL) return NULL;
+
+ ctx->debug = debuglevel;
+ ctx->callbacks.auth_fn = smbc_auth_fn;
+
+ if (smbc_init_context(ctx) == NULL){
+ smbc_free_context(ctx, 1);
+ return NULL;
+ }
+
+ return ctx;
+}
+
+void delete_smbctx(SMBCCTX* ctx){
+ ctx->callbacks.purge_cached_fn(ctx);
+ smbc_free_context(ctx, 1);
+}
+
+smbitem* get_smbitem_list(SMBCCTX *ctx, char *smb_path){
+ SMBCFILE *fd;
+ struct smbc_dirent *dirent;
+ smbitem *list = NULL, *item;
+
+ if ((fd = ctx->opendir(ctx, smb_path)) == NULL) return NULL;
+ while((dirent = ctx->readdir(ctx, fd)) != NULL){
+ if (strcmp(dirent->name, "") == 0) continue;
+ if (strcmp(dirent->name, ".") == 0) continue;
+ if (strcmp(dirent->name, "..") == 0) continue;
+
+ if ((item = malloc(sizeof(smbitem) + strlen(dirent->name))) == NULL)
+ continue;
+
+ item->next = list;
+ item->type = dirent->smbc_type;
+ strcpy(item->name, dirent->name);
+ list = item;
+ }
+ ctx->close_fn(ctx, fd);
+ return /* smbitem_list_sort */ (list);
+
+}
+
+void print_smb_path(char *group, char *path){
+ if ((strlen(group) == 0) && (strlen(path) == 0)) printf("/\n");
+ else if (strlen(path) == 0) printf("/%s\n", group);
+ else{
+ if (strlen(group) == 0) group = "(unknown_group)";
+ printf("/%s/%s\n", group, path);
+ }
+}
+
+void recurse(SMBCCTX *ctx, char *smb_group, char *smb_path, int maxlen){
+ int len;
+ smbitem *list, *item;
+ SMBCCTX *ctx1;
+
+ len = strlen(smb_path);
+
+ list = get_smbitem_list(ctx, smb_path);
+ while(list != NULL){
+ switch(list->type){
+ case SMBC_WORKGROUP:
+ case SMBC_SERVER:
+ if (list->type == SMBC_WORKGROUP){
+ print_smb_path(list->name, "");
+ smb_group = list->name;
+ }
+ else print_smb_path(smb_group, list->name);
+
+ if (maxlen < 7 + strlen(list->name)) break;
+ strcpy(smb_path + 6, list->name);
+ if ((ctx1 = create_smbctx()) != NULL){
+ recurse(ctx1, smb_group, smb_path, maxlen);
+ delete_smbctx(ctx1);
+ }else{
+ recurse(ctx, smb_group, smb_path, maxlen);
+ ctx->callbacks.purge_cached_fn(ctx);
+ }
+ break;
+ case SMBC_FILE_SHARE:
+ case SMBC_DIR:
+ case SMBC_FILE:
+ if (maxlen < len + strlen(list->name) + 2) break;
+
+ smb_path[len] = '/';
+ strcpy(smb_path + len + 1, list->name);
+ print_smb_path(smb_group, smb_path + 6);
+ if (list->type != SMBC_FILE){
+ recurse(ctx, smb_group, smb_path, maxlen);
+ if (list->type == SMBC_FILE_SHARE)
+ ctx->callbacks.purge_cached_fn(ctx);
+ }
+ break;
+ }
+ item = list;
+ list = list->next;
+ free(item);
+ }
+ smb_path[len] = '\0';
+}
+
+int main(int argc, char *argv[]){
+ int i;
+ SMBCCTX *ctx;
+ char smb_path[32768] = "smb://";
+
+ if ((ctx = create_smbctx()) == NULL){
+ perror("Cant create samba context.");
+ return 1;
+ }
+
+ if (argc == 1) recurse(ctx, "", smb_path, sizeof(smb_path));
+ else for(i = 1; i < argc; i++){
+ strncpy(smb_path + 6, argv[i], sizeof(smb_path) - 7);
+ smb_path[sizeof(smb_path) - 1] = '\0';
+ recurse(ctx, "", smb_path, sizeof(smb_path));
+ }
+
+ delete_smbctx(ctx);
+ return 0;
+}
diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c
index 9fda48a540..e6906eb79a 100644
--- a/source3/libsmb/libsmbclient.c
+++ b/source3/libsmb/libsmbclient.c
@@ -483,6 +483,8 @@ int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv)
DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv));
context->callbacks.remove_cached_srv_fn(context, srv);
+
+ SAFE_FREE(srv);
return 0;
}
@@ -822,9 +824,9 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context,
SMBCSRV *ipc_srv=NULL;
/*
- * See if we've already created this special connection. Reference our
- * "special" share name '*IPC$', which is an impossible real share name
- * due to the leading asterisk.
+ * See if we've already created this special connection. Reference
+ * our "special" share name '*IPC$', which is an impossible real share
+ * name due to the leading asterisk.
*/
ipc_srv = find_server(context, server, "*IPC$",
workgroup, username, password);
@@ -2386,9 +2388,11 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
/* Now, list the stuff ... */
- if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_unique_wg_fn,
+ if (!cli_NetServerEnum(&srv->cli,
+ workgroup,
+ SV_TYPE_DOMAIN_ENUM,
+ list_unique_wg_fn,
(void *)dir)) {
-
if (dir) {
SAFE_FREE(dir->fname);
SAFE_FREE(dir);