summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sharpe <sharpe@samba.org>2001-01-12 05:10:45 +0000
committerRichard Sharpe <sharpe@samba.org>2001-01-12 05:10:45 +0000
commitfb4013444677629af4b663a61da3b575bba49195 (patch)
tree7651b05326ecf23a1ccfafbdb988b44f0502df6f
parent78b2616049f19f7dad7c259bf04b0fb8645de218 (diff)
downloadsamba-fb4013444677629af4b663a61da3b575bba49195.tar.gz
samba-fb4013444677629af4b663a61da3b575bba49195.tar.bz2
samba-fb4013444677629af4b663a61da3b575bba49195.zip
Many bug fixes to the libsmbclient.c code plus
- an implementation of smbc_readdir - extensions to tree.c to show files in a second window - changes to auth_fn to provide buffers for username, password, etc from caller rather than callee (This used to be commit 7f559c1a7307b91218d5984f48f65e7dc0ab66b9)
-rw-r--r--source3/client/testsmbc.c46
-rw-r--r--source3/client/tree.c219
-rw-r--r--source3/include/libsmbclient.h11
-rw-r--r--source3/libsmb/libsmbclient.c175
4 files changed, 382 insertions, 69 deletions
diff --git a/source3/client/testsmbc.c b/source3/client/testsmbc.c
index 0dbd5b3c2d..49d9692176 100644
--- a/source3/client/testsmbc.c
+++ b/source3/client/testsmbc.c
@@ -26,30 +26,36 @@
#include <libsmbclient.h>
void auth_fn(char *server, char *share,
- char **workgroup, char **username, char **password)
+ char *workgroup, int wgmaxlen, char *username, int unmaxlen,
+ char *password, int pwmaxlen)
{
- static char wg[128], un[128], pw[128];
- /* DO nothing for now ... change later */
+ char temp[128];
- fprintf(stdout, "Enter workgroup: ");
- fgets(wg, sizeof(wg), stdin);
+ fprintf(stdout, "Need password for //%s/%s\n", server, share);
- if (wg[strlen(wg) - 1] == 0x0a) /* A new line? */
- wg[strlen(wg) - 1] = 0x00;
+ fprintf(stdout, "Enter workgroup: [%s] ", workgroup);
+ fgets(temp, sizeof(temp), stdin);
- fprintf(stdout, "Enter username: ");
- fgets(un, sizeof(un), stdin);
+ if (temp[strlen(temp) - 1] == 0x0a) /* A new line? */
+ temp[strlen(temp) - 1] = 0x00;
- if (un[strlen(un) - 1] == 0x0a) /* A new line? */
- un[strlen(un) - 1] = 0x00;
+ if (temp[0]) strncpy(workgroup, temp, wgmaxlen - 1);
- fprintf(stdout, "Enter password: ");
- fgets(pw, sizeof(pw), stdin);
+ fprintf(stdout, "Enter username: [%s] ", username);
+ fgets(temp, sizeof(temp), stdin);
- if (pw[strlen(pw) - 1] == 0x0a) /* A new line? */
- pw[strlen(pw) - 1] = 0x00;
+ if (temp[strlen(temp) - 1] == 0x0a) /* A new line? */
+ temp[strlen(temp) - 1] = 0x00;
- *workgroup = wg; *password = pw; *username = un;
+ if (temp[0]) strncpy(username, temp, unmaxlen - 1);
+
+ fprintf(stdout, "Enter password: [%s] ", password);
+ fgets(temp, sizeof(temp), stdin);
+
+ if (temp[strlen(temp) - 1] == 0x0a) /* A new line? */
+ temp[strlen(temp) - 1] = 0x00;
+
+ if (temp[0]) strncpy(password, temp, pwmaxlen - 1);
}
@@ -122,7 +128,7 @@ int main(int argc, char *argv[])
while (dirc > 0) {
- dsize = sizeof(struct smbc_dirent) + dirp->namelen + dirp->commentlen + 1;
+ dsize = dirp->dirlen;
fprintf(stdout, "Dir Ent, Type: %u, Name: %s, Comment: %s\n",
dirp->smbc_type, dirp->name, dirp->comment);
@@ -148,7 +154,7 @@ int main(int argc, char *argv[])
while (dirc > 0) {
- dsize = sizeof(struct smbc_dirent) + dirp->namelen + dirp->commentlen + 1;
+ dsize = dirp->dirlen;
fprintf(stdout, "Dir Ent, Type: %u, Name: %s, Comment: %s\n",
dirp->smbc_type, dirp->name, dirp->comment);
@@ -174,7 +180,7 @@ int main(int argc, char *argv[])
while (dirc > 0) {
- dsize = sizeof(struct smbc_dirent) + dirp->namelen + dirp->commentlen + 1;
+ dsize = dirp->dirlen;
fprintf(stdout, "\nDir Ent, Type: %u, Name: %s, Comment: %s\n",
dirp->smbc_type, dirp->name, dirp->comment);
@@ -330,7 +336,9 @@ int main(int argc, char *argv[])
fprintf(stdout, "Stat'ed file: %s. Size = %d, mode = %04X\n", file2,
st2.st_size, st2.st_mode);
+ fprintf(stdout, " time: %s\n", ctime(&st2.st_atime));
fprintf(stdout, "Earlier stat: %s, Size = %d, mode = %04X\n", file,
st1.st_size, st1.st_mode);
+ fprintf(stdout, " time: %s\n", ctime(&st1.st_atime));
}
diff --git a/source3/client/tree.c b/source3/client/tree.c
index e2c7fb70d8..872ec0f1ab 100644
--- a/source3/client/tree.c
+++ b/source3/client/tree.c
@@ -28,6 +28,8 @@
#include <gtk/gtk.h>
#include "libsmbclient.h"
+static GtkWidget *clist;
+
struct tree_data {
guint32 type; /* Type of tree item, an SMBC_TYPE */
@@ -142,7 +144,7 @@ static void cb_itemsignal( GtkWidget *item,
if ((dh = smbc_opendir(get_path(item))) < 0) { /* Handle error */
- g_print("cb_wholenet: Could not open dir %s, %s\n", server,
+ g_print("cb_wholenet: Could not open dir %s, %s\n", get_path(item),
strerror(errno));
gtk_main_quit();
@@ -208,7 +210,10 @@ static void cb_itemsignal( GtkWidget *item,
fprintf(stdout, "Added: %s, len: %u\n", dirp->name, dirlen);
- if (dirp->smbc_type != SMBC_FILE && dirp->smbc_type != SMBC_IPC_SHARE){
+ if (dirp->smbc_type != SMBC_FILE &&
+ dirp->smbc_type != SMBC_IPC_SHARE &&
+ (strcmp(dirp->name, ".") != 0) &&
+ (strcmp(dirp->name, "..") !=0)){
subtree = gtk_tree_new();
gtk_tree_item_set_subtree(GTK_TREE_ITEM(aitem), subtree);
@@ -242,8 +247,147 @@ static void cb_unselect_child( GtkWidget *root_tree,
static void cb_select_child (GtkWidget *root_tree, GtkWidget *child,
GtkWidget *subtree)
{
+ gint dh, err, dirlen;
+ char dirbuf[512];
+ struct smbc_dirent *dirp;
+ struct stat st1;
+ char path[1024], path1[1024];
+
g_print ("select_child called for root tree %p, subtree %p, child %p\n",
root_tree, subtree, child);
+
+ /* Now, figure out what it is, and display it in the clist ... */
+
+ gtk_clist_clear(GTK_CLIST(clist)); /* Clear the CLIST */
+
+ /* Now, get the private data for the subtree */
+
+ strncpy(path, get_path(child), 1024);
+
+ if ((dh = smbc_opendir(path)) < 0) { /* Handle error */
+
+ g_print("cb_select_child: Could not open dir %s, %s\n", path,
+ strerror(errno));
+
+ gtk_main_quit();
+
+ return;
+
+ }
+
+ while ((err = smbc_getdents(dh, (struct smbc_dirent *)dirbuf,
+ sizeof(dirbuf))) != 0) {
+
+ if (err < 0) {
+
+ g_print("cb_select_child: Could not read dir %s, %s\n", path,
+ strerror(errno));
+
+ gtk_main_quit();
+
+ return;
+
+ }
+
+ dirp = (struct smbc_dirent *)dirbuf;
+
+ while (err > 0) {
+ gchar col1[128], col2[128], col3[128], col4[128];
+ gchar *rowdata[4] = {col1, col2, col3, col4};
+
+ dirlen = dirp->dirlen;
+
+ /* Format each of the items ... */
+
+ strncpy(col1, dirp->name, 128);
+
+ col2[0] = col3[0] = col4[0] = (char)0;
+
+ switch (dirp->smbc_type) {
+
+ case SMBC_WORKGROUP:
+
+ break;
+
+ case SMBC_SERVER:
+
+ strncpy(col2, (dirp->comment?dirp->comment:""), 128);
+
+ break;
+
+ case SMBC_FILE_SHARE:
+
+ strncpy(col2, (dirp->comment?dirp->comment:""), 128);
+
+ break;
+
+ case SMBC_PRINTER_SHARE:
+
+ strncpy(col2, (dirp->comment?dirp->comment:""), 128);
+ break;
+
+ case SMBC_COMMS_SHARE:
+
+ break;
+
+ case SMBC_IPC_SHARE:
+
+ break;
+
+ case SMBC_DIR:
+ case SMBC_FILE:
+
+ /* Get stats on the file/dir and see what we have */
+
+ if ((strcmp(dirp->name, ".") != 0) &&
+ (strcmp(dirp->name, "..") != 0)) {
+
+ strncpy(path1, path, sizeof(path1));
+ strncat(path1, "/", sizeof(path) - strlen(path));
+ strncat(path1, dirp->name, sizeof(path) - strlen(path));
+
+ if (smbc_stat(path1, &st1) < 0) {
+
+ g_print("cb_select_child: Could not stat file %s, %s\n", path1,
+ strerror(errno));
+
+ gtk_main_quit();
+
+ return;
+
+ }
+
+ /* Now format each of the relevant things ... */
+
+ snprintf(col2, sizeof(col2), "%s%s%s%s%s%s(%0X)",
+ (st1.st_mode&0x20?"A":""),
+ (st1.st_mode&0x10?"D":""),
+ (st1.st_mode&0x08?"V":""),
+ (st1.st_mode&0x04?"S":""),
+ (st1.st_mode&0x02?"H":""),
+ (st1.st_mode&0x01?"R":""),
+ st1.st_mode);
+ snprintf(col3, sizeof(col3), "%u", st1.st_size);
+ snprintf(col4, sizeof(col4), "%s", ctime(&st1.st_ctime));
+
+ }
+
+ break;
+
+ default:
+
+ break;
+ }
+
+ gtk_clist_append(GTK_CLIST(clist), rowdata);
+
+ (char *)dirp += dirlen;
+ err -= dirlen;
+
+ }
+
+ }
+
}
static void cb_selection_changed( GtkWidget *tree )
@@ -363,22 +507,28 @@ static void cb_wholenet(GtkWidget *item, gchar *signame)
}
+/* Should put up a dialog box to ask the user for username and password */
+
static void
auth_fn(char *server, char *share,
- char **workgroup, char **username, char **password)
+ char *workgroup, int wgmaxlen, char *username, int unmaxlen,
+ char *password, int pwmaxlen)
{
- *workgroup = "";
- *username = "test";
- *password = "test";
+ strncpy(username, "test", unmaxlen);
+ strncpy(password, "test", pwmaxlen);
}
+static char *col_titles[] = {
+ "Name", "Attributes", "Size", "Creation Date",
+};
+
int main( int argc,
char *argv[] )
{
- GtkWidget *window, *scrolled_win, *tree;
- GtkWidget *subtree, *item;
+ GtkWidget *window, *scrolled_win, *scrolled_win2, *tree;
+ GtkWidget *subtree, *item, *main_hbox, *r_pane, *l_pane;
gint err, dh;
gint i;
char dirbuf[512];
@@ -392,18 +542,50 @@ int main( int argc,
/* a generic toplevel window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_widget_set_name(window, "main browser window");
gtk_signal_connect (GTK_OBJECT(window), "delete_event",
GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
+ gtk_window_set_title(GTK_WINDOW(window), "The Linux Windows Network Browser");
+ gtk_widget_set_usize(GTK_WIDGET(window), 750, -1);
gtk_container_set_border_width (GTK_CONTAINER(window), 5);
+ gtk_widget_show (window);
+
+ /* A container for the two panes ... */
+
+ main_hbox = gtk_hbox_new(FALSE, 1);
+ gtk_container_border_width(GTK_CONTAINER(main_hbox), 1);
+ gtk_container_add(GTK_CONTAINER(window), main_hbox);
+
+ gtk_widget_show(main_hbox);
+
+ l_pane = gtk_hpaned_new();
+ gtk_paned_gutter_size(GTK_PANED(l_pane), (GTK_PANED(l_pane))->handle_size);
+ r_pane = gtk_hpaned_new();
+ gtk_paned_gutter_size(GTK_PANED(r_pane), (GTK_PANED(r_pane))->handle_size);
+ gtk_container_add(GTK_CONTAINER(main_hbox), l_pane);
+ gtk_widget_show(l_pane);
+ /*gtk_container_add(GTK_CONTAINER(main_hbox), r_pane);
+ gtk_widget_show(r_pane); */
+
+
/* A generic scrolled window */
scrolled_win = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_widget_set_usize (scrolled_win, 150, 200);
- gtk_container_add (GTK_CONTAINER(window), scrolled_win);
+ gtk_container_add (GTK_CONTAINER(l_pane), scrolled_win);
gtk_widget_show (scrolled_win);
+
+ /* Another generic scrolled window */
+ scrolled_win2 = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win2),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ gtk_widget_set_usize (scrolled_win2, 150, 200);
+ gtk_paned_add2 (GTK_PANED(l_pane), scrolled_win2);
+ gtk_widget_show (scrolled_win2);
/* Create the root tree */
tree = gtk_tree_new();
@@ -424,6 +606,14 @@ int main( int argc,
/* Show it */
gtk_widget_show (tree);
+ /* Now, create a clist and attach it to the second pane */
+
+ clist = gtk_clist_new_with_titles(4, col_titles);
+
+ gtk_container_add (GTK_CONTAINER(scrolled_win2), clist);
+
+ gtk_widget_show(clist);
+
/* Now, build the top level display ... */
if ((dh = smbc_opendir("smb:///")) < 0) {
@@ -458,6 +648,11 @@ int main( int argc,
gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), subtree);
+ gtk_signal_connect (GTK_OBJECT(subtree), "select_child",
+ GTK_SIGNAL_FUNC(cb_select_child), tree);
+ gtk_signal_connect (GTK_OBJECT(subtree), "unselect_child",
+ GTK_SIGNAL_FUNC(cb_unselect_child), tree);
+
/* Now, get the items in smb:/// and add them to the tree */
dirp = (struct smbc_dirent *)dirbuf;
@@ -507,6 +702,11 @@ int main( int argc,
gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), subtree);
+ gtk_signal_connect (GTK_OBJECT(subtree), "select_child",
+ GTK_SIGNAL_FUNC(cb_select_child), tree);
+ gtk_signal_connect (GTK_OBJECT(subtree), "unselect_child",
+ GTK_SIGNAL_FUNC(cb_unselect_child), tree);
+
(char *)dirp += dirlen;
err -= dirlen;
@@ -517,7 +717,6 @@ int main( int argc,
smbc_closedir(dh); /* FIXME, check for error :-) */
/* Show the window and loop endlessly */
- gtk_widget_show (window);
gtk_main();
return 0;
}
diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h
index 6f608bdc5b..34e9405ff5 100644
--- a/source3/include/libsmbclient.h
+++ b/source3/include/libsmbclient.h
@@ -60,8 +60,9 @@ struct smbc_dirent {
#define SMBC_DIR_MODE (S_IFDIR | 0555)
typedef void (*smbc_get_auth_data_fn)(char *server, char *share,
- char **workgroup, char **username,
- char **password);
+ char *workgroup, int wgmaxlen,
+ char *username, int unmaxlen,
+ char *password, int pwmaxlen);
/*
* Init the smbc package
@@ -160,6 +161,12 @@ int smbc_closedir(int fd);
int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count);
+/*
+ * Read a dirent in the old way
+ */
+
+struct smbc_dirent *smbc_readdir(unsigned int fd);
+
/*
* Create a directory on a server, share, dir in fname URL
*/
diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c
index 3c1c343ec2..807dfb987c 100644
--- a/source3/libsmb/libsmbclient.c
+++ b/source3/libsmb/libsmbclient.c
@@ -65,6 +65,7 @@ static int smbc_max_fd = 10000;
static struct smbc_file **smbc_file_table;
static struct smbc_server *smbc_srvs;
static pstring my_netbios_name;
+static pstring smbc_user;
/*
* Clean up a filename by removing redundent stuff
@@ -174,14 +175,15 @@ smbc_clean_fname(char *name)
static const char *smbc_prefix = "smb:";
static int
-smbc_parse_path(const char *fname, char *server, char *share, char *path)
+smbc_parse_path(const char *fname, char *server, char *share, char *path,
+ char *user, char *password) /* FIXME, lengths of strings */
{
static pstring s;
char *p;
int len;
fstring workgroup;
- server[0] = share[0] = path[0] = (char)0;
+ server[0] = share[0] = path[0] = user[0] = password[0] = (char)0;
pstrcpy(s, fname);
/* clean_fname(s); causing problems ... */
@@ -257,15 +259,21 @@ int smbc_errno(struct cli_state *c)
/*
* Connect to a server, possibly on an existing connection
+ *
+ * Here, what we want to do is: If the server and username
+ * match an existing connection, reuse that, otherwise, establish a
+ * new connection.
+ *
+ * If we have to create a new connection, call the auth_fn to get the
+ * info we need, unless the username and password were passed in.
*/
-struct smbc_server *smbc_server(char *server, char *share)
+struct smbc_server *smbc_server(char *server, char *share,
+ char *workgroup, char *username,
+ char *password)
{
struct smbc_server *srv=NULL;
struct cli_state c;
- char *username = NULL;
- char *password = NULL;
- char *workgroup = NULL;
struct nmb_name called, calling;
char *p, *server_n = server;
fstring group;
@@ -276,16 +284,6 @@ struct smbc_server *smbc_server(char *server, char *share)
ip = ipzero;
ZERO_STRUCT(c);
- if (strncmp(share, "IPC$", 4)) /* IPC$ should not need a pwd ... */
- smbc_auth_fn(server, share, &workgroup, &username, &password);
- else {
-
- workgroup = lp_workgroup(); /* Is this relevant here? */
- username = "";
- password = "";
-
- }
-
/* try to use an existing connection */
for (srv=smbc_srvs;srv;srv=srv->next) {
if (strcmp(server,srv->server_name)==0 &&
@@ -300,6 +298,24 @@ struct smbc_server *smbc_server(char *server, char *share)
return NULL;
}
+ /* Pick up the auth info here, once we know we need to connect */
+
+ smbc_auth_fn(server, share, workgroup, sizeof(fstring),
+ username, sizeof(fstring), password, sizeof(fstring));
+
+ /*
+ * However, smbc_auth_fn may have picked up info relating to an
+ * existing connection, so try for and existing connection again ...
+ */
+
+ for (srv=smbc_srvs;srv;srv=srv->next) {
+ if (strcmp(server,srv->server_name)==0 &&
+ strcmp(share,srv->share_name)==0 &&
+ strcmp(workgroup,srv->workgroup)==0 &&
+ strcmp(username, srv->username) == 0)
+ return srv;
+ }
+
make_nmb_name(&calling, my_netbios_name, 0x0);
make_nmb_name(&called , server, 0x20);
@@ -443,7 +459,12 @@ int smbc_init(smbc_get_auth_data_fn fn, const char *wgroup, int debug)
*/
user = getenv("USER");
- if (!user) user = "";
+ if (!user) user = ""; /* FIXME: What to do about this? */
+
+ /*
+ * FIXME: Is this the best way to get the user info? */
+
+ pstrcpy(smbc_user, user); /* Save for use elsewhere */
pid = getpid();
@@ -533,7 +554,7 @@ int smbc_init(smbc_get_auth_data_fn fn, const char *wgroup, int debug)
int smbc_open(const char *fname, int flags, mode_t mode)
{
- fstring server, share;
+ fstring server, share, user, password;
pstring path;
struct smbc_server *srv = NULL;
struct smbc_file *file = NULL;
@@ -553,9 +574,11 @@ int smbc_open(const char *fname, int flags, mode_t mode)
}
- smbc_parse_path(fname, server, share, path); /* FIXME, check errors */
+ smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */
- srv = smbc_server(server, share);
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
+
+ srv = smbc_server(server, share, lp_workgroup(), user, password);
if (!srv) {
@@ -787,7 +810,7 @@ int smbc_close(int fd)
int smbc_unlink(const char *fname)
{
- fstring server, share;
+ fstring server, share, user, password;
pstring path;
struct smbc_server *srv = NULL;
@@ -805,9 +828,11 @@ int smbc_unlink(const char *fname)
}
- smbc_parse_path(fname, server, share, path); /* FIXME, check errors */
+ smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */
+
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
- srv = smbc_server(server, share);
+ srv = smbc_server(server, share, lp_workgroup(), user, password);
if (!srv) {
@@ -847,7 +872,7 @@ int smbc_unlink(const char *fname)
int smbc_rename(const char *oname, const char *nname)
{
- fstring server1, share1, server2, share2;
+ fstring server1, share1, server2, share2, user1, user2, password1, password2;
pstring path1, path2;
struct smbc_server *srv = NULL;
@@ -867,19 +892,25 @@ int smbc_rename(const char *oname, const char *nname)
DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname));
- smbc_parse_path(oname, server1, share1, path1);
- smbc_parse_path(nname, server2, share2, path2);
+ smbc_parse_path(oname, server1, share1, path1, user1, password1);
- if (strcmp(server1, server2) || strcmp(share1, share2)) {
+ if (user1[0] == (char)0) pstrcpy(user1, smbc_user);
- /* Can't rename across file systems */
+ smbc_parse_path(nname, server2, share2, path2, user2, password2);
+
+ if (user2[0] == (char)0) pstrcpy(user2, smbc_user);
+
+ if (strcmp(server1, server2) || strcmp(share1, share2) ||
+ strcmp(user1, user2)) {
+
+ /* Can't rename across file systems, or users?? */
errno = EXDEV;
return -1;
}
- srv = smbc_server(server1, share1);
+ srv = smbc_server(server1, share1, lp_workgroup(), user1, password1);
if (!srv) {
return -1;
@@ -1059,7 +1090,7 @@ BOOL smbc_getatr(struct smbc_server *srv, char *path,
int smbc_stat(const char *fname, struct stat *st)
{
struct smbc_server *srv;
- fstring server, share;
+ fstring server, share, user, password;
pstring path;
time_t m_time = 0, a_time = 0, c_time = 0;
size_t size = 0;
@@ -1082,9 +1113,11 @@ int smbc_stat(const char *fname, struct stat *st)
DEBUG(4, ("stat(%s)\n", fname));
- smbc_parse_path(fname, server, share, path);
+ smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
- srv = smbc_server(server, share);
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
+
+ srv = smbc_server(server, share, lp_workgroup(), user, password);
if (!srv) {
@@ -1353,7 +1386,7 @@ dir_list_fn(file_info *finfo, const char *mask, void *state)
int smbc_opendir(const char *fname)
{
struct in_addr addr;
- fstring server, share;
+ fstring server, share, user, password;
pstring path;
struct smbc_server *srv = NULL;
struct in_addr rem_ip;
@@ -1373,13 +1406,15 @@ int smbc_opendir(const char *fname)
}
- if (smbc_parse_path(fname, server, share, path)) {
+ if (smbc_parse_path(fname, server, share, path, user, password)) {
errno = EINVAL;
return -1;
}
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
+
/* Get a file entry ... */
slot = 0;
@@ -1433,7 +1468,7 @@ int smbc_opendir(const char *fname)
* Get a connection to IPC$ on the server if we do not already have one
*/
- srv = smbc_server(server, "IPC$");
+ srv = smbc_server(server, "IPC$", lp_workgroup(), user, password);
if (!srv) {
@@ -1486,7 +1521,7 @@ int smbc_opendir(const char *fname)
* Get a connection to IPC$ on the server if we do not already have one
*/
- srv = smbc_server(buserver, "IPC$");
+ srv = smbc_server(buserver, "IPC$", lp_workgroup(), user, password);
if (!srv) {
@@ -1518,7 +1553,7 @@ int smbc_opendir(const char *fname)
smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE;
- srv = smbc_server(server, "IPC$");
+ srv = smbc_server(server, "IPC$", lp_workgroup(), user, password);
if (!srv) {
@@ -1560,7 +1595,7 @@ int smbc_opendir(const char *fname)
smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE;
- srv = smbc_server(server, share);
+ srv = smbc_server(server, share, lp_workgroup(), user, password);
if (!srv) {
@@ -1638,6 +1673,70 @@ int smbc_closedir(int fd)
* Routine to get a directory entry
*/
+static char smbc_local_dirent[512]; /* Make big enough */
+
+struct smbc_dirent *smbc_readdir(unsigned int fd)
+{
+ struct smbc_file *fe;
+ struct smbc_dirent *dirp, *dirent;
+
+ /* Check that all is ok first ... */
+
+ if (!smbc_initialized) {
+
+ errno = EUCLEAN;
+ return NULL;
+
+ }
+
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) {
+
+ errno = EBADF;
+ return NULL;
+
+ }
+
+ fe = smbc_file_table[fd - smbc_start_fd];
+
+ if (fe->file != False) { /* FIXME, should be dir, perhaps */
+
+ errno = ENOTDIR;
+ return NULL;
+
+ }
+
+ if (!fe->dir_next)
+ return NULL;
+ else {
+
+ dirent = fe->dir_next->dirent;
+
+ if (!dirent) {
+
+ errno = ENOENT;
+ return NULL;
+
+ }
+
+ /* Hmmm, do I even need to copy it? */
+
+ bcopy(dirent, smbc_local_dirent, dirent->dirlen); /* Copy the dirent */
+
+ dirp = (struct smbc_dirent *)smbc_local_dirent;
+
+ dirp->comment = (char *)(&dirp->name + dirent->namelen + 1);
+
+ fe->dir_next = fe->dir_next->next;
+
+ return (struct smbc_dirent *)smbc_local_dirent;
+ }
+
+}
+
+/*
+ * Routine to get directory entries
+ */
+
int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count)
{
struct smbc_file *fe;