From fb4013444677629af4b663a61da3b575bba49195 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 12 Jan 2001 05:10:45 +0000 Subject: 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) --- source3/client/testsmbc.c | 46 +++++---- source3/client/tree.c | 219 +++++++++++++++++++++++++++++++++++++++-- source3/include/libsmbclient.h | 11 ++- source3/libsmb/libsmbclient.c | 175 +++++++++++++++++++++++++------- 4 files changed, 382 insertions(+), 69 deletions(-) (limited to 'source3') 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 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 #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; -- cgit