diff options
author | Derrell Lipman <derrell@samba.org> | 2005-12-06 17:09:44 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:05:44 -0500 |
commit | 44293df2aeaeccb1e2cca18bb7d61534a5e07b1a (patch) | |
tree | d72999c8185bddd4193b606354538459ae76c7bb | |
parent | a2bac34183ce003a194f741c62e69d6674516b07 (diff) | |
download | samba-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/Makefile | 5 | ||||
-rw-r--r-- | examples/libsmbclient/testbrowse2.c | 214 | ||||
-rw-r--r-- | source3/libsmb/libsmbclient.c | 14 |
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); |