client/tree.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    SMB client GTK+ tree-based application
00004    Copyright (C) Andrew Tridgell 1998
00005    Copyright (C) Richard Sharpe 2001
00006    Copyright (C) John Terpstra 2001
00007    
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012    
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017    
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021 */
00022 
00023 /* example-gtk+ application, ripped off from the gtk+ tree.c sample */
00024 
00025 #include <stdio.h>
00026 #include <errno.h>
00027 #include <gtk/gtk.h>
00028 #include "libsmbclient.h"
00029 
00030 static GtkWidget *clist;
00031 
00032 struct tree_data {
00033 
00034   guint32 type;    /* Type of tree item, an SMBC_TYPE */
00035   char name[256];  /* May need to change this later   */
00036 
00037 };
00038 
00039 static void tree_error_message(gchar *message) {
00040 
00041   GtkWidget *dialog, *label, *okay_button;
00042      
00043   /* Create the widgets */
00044      
00045   dialog = gtk_dialog_new();
00046   gtk_window_set_modal(GTK_WINDOW(dialog), True);
00047   label = gtk_label_new (message);
00048   okay_button = gtk_button_new_with_label("Okay");
00049      
00050   /* Ensure that the dialog box is destroyed when the user clicks ok. */
00051      
00052   gtk_signal_connect_object (GTK_OBJECT (okay_button), "clicked",
00053                              GTK_SIGNAL_FUNC (gtk_widget_destroy), dialog);
00054   gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area),
00055                      okay_button);
00056 
00057   /* Add the label, and show everything we've added to the dialog. */
00058 
00059   gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
00060                      label);
00061   gtk_widget_show_all (dialog);
00062 }
00063 
00064 /*
00065  * We are given a widget, and we want to retrieve its URL so we 
00066  * can do a directory listing.
00067  *
00068  * We walk back up the tree, picking up pieces until we hit a server or
00069  * workgroup type and return a path from there
00070  */
00071 
00072 static pstring path_string;
00073 
00074 char *get_path(GtkWidget *item)
00075 {
00076   GtkWidget *p = item;
00077   struct tree_data *pd;
00078   char *comps[1024];  /* We keep pointers to the components here */
00079   int i = 0, j, level,type;
00080 
00081   /* Walk back up the tree, getting the private data */
00082 
00083   level = GTK_TREE(item->parent)->level;
00084 
00085   /* Pick up this item's component info */
00086 
00087   pd = (struct tree_data *)gtk_object_get_user_data(GTK_OBJECT(item));
00088 
00089   comps[i++] = pd->name;
00090   type = pd->type;
00091 
00092   while (level > 0 && type != SMBC_SERVER && type != SMBC_WORKGROUP) {
00093 
00094     /* Find the parent and extract the data etc ... */
00095 
00096     p = GTK_WIDGET(p->parent);    
00097     p = GTK_WIDGET(GTK_TREE(p)->tree_owner);
00098 
00099     pd = (struct tree_data *)gtk_object_get_user_data(GTK_OBJECT(p));
00100 
00101     level = GTK_TREE(item->parent)->level;
00102 
00103     comps[i++] = pd->name;
00104     type = pd->type;
00105 
00106   }
00107 
00108   /* 
00109    * Got a list of comps now, should check that we did not hit a workgroup
00110    * when we got other things as well ... Later
00111    *
00112    * Now, build the path
00113    */
00114 
00115   pstrcpy( path_string, "smb:/" );
00116 
00117   for (j = i - 1; j >= 0; j--) {
00118 
00119     strncat(path_string, "/", sizeof(path_string) - strlen(path_string));
00120     strncat(path_string, comps[j], sizeof(path_string) - strlen(path_string));
00121 
00122   }
00123   
00124   fprintf(stdout, "Path string = %s\n", path_string);
00125 
00126   return path_string;
00127 
00128 }
00129 
00130 struct tree_data *make_tree_data(guint32 type, const char *name)
00131 {
00132   struct tree_data *p = SMB_MALLOC_P(struct tree_data);
00133 
00134   if (p) {
00135 
00136     p->type = type;
00137     strncpy(p->name, name, sizeof(p->name));
00138 
00139   }
00140 
00141   return p;
00142 
00143 }
00144 
00145 /* Note that this is called every time the user clicks on an item,
00146    whether it is already selected or not. */
00147 static void cb_select_child (GtkWidget *root_tree, GtkWidget *child,
00148                              GtkWidget *subtree)
00149 {
00150   gint dh, err, dirlen;
00151   char dirbuf[512];
00152   struct smbc_dirent *dirp;
00153   struct stat st1;
00154   pstring path, path1;
00155 
00156   g_print ("select_child called for root tree %p, subtree %p, child %p\n",
00157            root_tree, subtree, child);
00158 
00159   /* Now, figure out what it is, and display it in the clist ... */
00160 
00161   gtk_clist_clear(GTK_CLIST(clist));  /* Clear the CLIST */
00162 
00163   /* Now, get the private data for the subtree */
00164 
00165   strncpy(path, get_path(child), 1024);
00166 
00167   if ((dh = smbc_opendir(path)) < 0) { /* Handle error */
00168 
00169     g_print("cb_select_child: Could not open dir %s, %s\n", path,
00170             strerror(errno));
00171 
00172     gtk_main_quit();
00173 
00174     return;
00175 
00176   }
00177 
00178   while ((err = smbc_getdents(dh, (struct smbc_dirent *)dirbuf,
00179                               sizeof(dirbuf))) != 0) {
00180 
00181     if (err < 0) {
00182 
00183       g_print("cb_select_child: Could not read dir %s, %s\n", path,
00184               strerror(errno));
00185 
00186       gtk_main_quit();
00187 
00188       return;
00189 
00190     }
00191 
00192     dirp = (struct smbc_dirent *)dirbuf;
00193 
00194     while (err > 0) {
00195       gchar col1[128], col2[128], col3[128], col4[128];
00196       gchar *rowdata[4] = {col1, col2, col3, col4};
00197 
00198       dirlen = dirp->dirlen;
00199 
00200       /* Format each of the items ... */
00201 
00202       strncpy(col1, dirp->name, 128);
00203 
00204       col2[0] = col3[0] = col4[0] = (char)0;
00205 
00206       switch (dirp->smbc_type) {
00207 
00208       case SMBC_WORKGROUP:
00209 
00210         break;
00211 
00212       case SMBC_SERVER:
00213 
00214         strncpy(col2, (dirp->comment?dirp->comment:""), 128);
00215 
00216         break;
00217 
00218       case SMBC_FILE_SHARE:
00219 
00220         strncpy(col2, (dirp->comment?dirp->comment:""), 128);
00221 
00222         break;
00223 
00224       case SMBC_PRINTER_SHARE:
00225 
00226         strncpy(col2, (dirp->comment?dirp->comment:""), 128);
00227         break;
00228 
00229       case SMBC_COMMS_SHARE:
00230 
00231         break;
00232 
00233       case SMBC_IPC_SHARE:
00234 
00235         break;
00236 
00237       case SMBC_DIR:
00238       case SMBC_FILE:
00239 
00240         /* Get stats on the file/dir and see what we have */
00241 
00242         if ((strcmp(dirp->name, ".") != 0) &&
00243             (strcmp(dirp->name, "..") != 0)) {
00244 
00245           strncpy(path1, path, sizeof(path1));
00246           strncat(path1, "/", sizeof(path) - strlen(path));
00247           strncat(path1, dirp->name, sizeof(path) - strlen(path));
00248 
00249           if (smbc_stat(path1, &st1) < 0) {
00250             
00251             if (errno != EBUSY) {
00252               
00253               g_print("cb_select_child: Could not stat file %s, %s\n", path1, 
00254                       strerror(errno));
00255             
00256               gtk_main_quit();
00257 
00258               return;
00259 
00260             }
00261             else {
00262 
00263               strncpy(col2, "Device or resource busy", sizeof(col2));
00264 
00265             }
00266           }
00267           else {
00268             /* Now format each of the relevant things ... */
00269 
00270             snprintf(col2, sizeof(col2), "%c%c%c%c%c%c%c%c%c(%0X)",
00271                      (st1.st_mode&S_IRUSR?'r':'-'),
00272                      (st1.st_mode&S_IWUSR?'w':'-'),
00273                      (st1.st_mode&S_IXUSR?'x':'-'),
00274                      (st1.st_mode&S_IRGRP?'r':'-'),
00275                      (st1.st_mode&S_IWGRP?'w':'-'),
00276                      (st1.st_mode&S_IXGRP?'x':'-'),
00277                      (st1.st_mode&S_IROTH?'r':'-'),
00278                      (st1.st_mode&S_IWOTH?'w':'-'),
00279                      (st1.st_mode&S_IXOTH?'x':'-'),
00280                      st1.st_mode); 
00281             snprintf(col3, sizeof(col3), "%u", st1.st_size);
00282             snprintf(col4, sizeof(col4), "%s", ctime(&st1.st_mtime));
00283           }
00284         }
00285 
00286         break;
00287 
00288       default:
00289 
00290         break;
00291       }
00292 
00293       gtk_clist_append(GTK_CLIST(clist), rowdata);
00294 
00295       (char *)dirp += dirlen;
00296       err -= dirlen;
00297 
00298     }
00299 
00300   }
00301 
00302 }
00303 
00304 /* Note that this is never called */
00305 static void cb_unselect_child( GtkWidget *root_tree,
00306                                GtkWidget *child,
00307                                GtkWidget *subtree )
00308 {
00309   g_print ("unselect_child called for root tree %p, subtree %p, child %p\n",
00310            root_tree, subtree, child);
00311 }
00312 
00313 /* for all the GtkItem:: and GtkTreeItem:: signals */
00314 static void cb_itemsignal( GtkWidget *item,
00315                            gchar     *signame )
00316 {
00317   GtkWidget *real_tree, *aitem, *subtree;
00318   gchar *name;
00319   GtkLabel *label;
00320   gint dh, err, dirlen, level;
00321   char dirbuf[512];
00322   struct smbc_dirent *dirp;
00323   
00324   label = GTK_LABEL (GTK_BIN (item)->child);
00325   /* Get the text of the label */
00326   gtk_label_get (label, &name);
00327 
00328   level = GTK_TREE(item->parent)->level;
00329 
00330   /* Get the level of the tree which the item is in */
00331   g_print ("%s called for item %s->%p, level %d\n", signame, name,
00332            item, GTK_TREE (item->parent)->level);
00333 
00334   real_tree = GTK_TREE_ITEM_SUBTREE(item);  /* Get the subtree */
00335 
00336   if (strncmp(signame, "expand", 6) == 0) { /* Expand called */
00337     char server[128];
00338 
00339     if ((dh = smbc_opendir(get_path(item))) < 0) { /* Handle error */
00340       gchar errmsg[256];
00341 
00342       g_print("cb_itemsignal: Could not open dir %s, %s\n", get_path(item), 
00343               strerror(errno));
00344 
00345       slprintf(errmsg, sizeof(errmsg), "cb_itemsignal: Could not open dir %s, %s\n", get_path(item), strerror(errno));
00346 
00347       tree_error_message(errmsg);
00348 
00349       /*      gtk_main_quit();*/
00350 
00351       return;
00352 
00353     }
00354 
00355     while ((err = smbc_getdents(dh, (struct smbc_dirent *)dirbuf, 
00356                                 sizeof(dirbuf))) != 0) {
00357 
00358       if (err < 0) { /* An error, report it */
00359         gchar errmsg[256];
00360 
00361         g_print("cb_itemsignal: Could not read dir smbc://, %s\n",
00362                 strerror(errno));
00363 
00364         slprintf(errmsg, sizeof(errmsg), "cb_itemsignal: Could not read dir smbc://, %s\n", strerror(errno));
00365 
00366         tree_error_message(errmsg);
00367 
00368         /*      gtk_main_quit();*/
00369 
00370         return;
00371 
00372       }
00373 
00374       dirp = (struct smbc_dirent *)dirbuf;
00375 
00376       while (err > 0) {
00377         struct tree_data *my_data;
00378 
00379         dirlen = dirp->dirlen;
00380 
00381         my_data = make_tree_data(dirp->smbc_type, dirp->name);
00382 
00383         if (!my_data) {
00384 
00385           g_print("Could not allocate space for tree_data: %s\n",
00386                   dirp->name);
00387 
00388           gtk_main_quit();
00389           return;
00390 
00391         }
00392 
00393         aitem = gtk_tree_item_new_with_label(dirp->name);
00394 
00395         /* Connect all GtkItem:: and GtkTreeItem:: signals */
00396         gtk_signal_connect (GTK_OBJECT(aitem), "select",
00397                             GTK_SIGNAL_FUNC(cb_itemsignal), "select");
00398         gtk_signal_connect (GTK_OBJECT(aitem), "deselect",
00399                             GTK_SIGNAL_FUNC(cb_itemsignal), "deselect");
00400         gtk_signal_connect (GTK_OBJECT(aitem), "toggle",
00401                             GTK_SIGNAL_FUNC(cb_itemsignal), "toggle");
00402         gtk_signal_connect (GTK_OBJECT(aitem), "expand",
00403                             GTK_SIGNAL_FUNC(cb_itemsignal), "expand");
00404         gtk_signal_connect (GTK_OBJECT(aitem), "collapse",
00405                             GTK_SIGNAL_FUNC(cb_itemsignal), "collapse");
00406         /* Add it to the parent tree */
00407         gtk_tree_append (GTK_TREE(real_tree), aitem);
00408 
00409         gtk_widget_show (aitem);
00410 
00411         gtk_object_set_user_data(GTK_OBJECT(aitem), (gpointer)my_data);
00412 
00413         fprintf(stdout, "Added: %s, len: %u\n", dirp->name, dirlen);
00414 
00415         if (dirp->smbc_type != SMBC_FILE &&
00416             dirp->smbc_type != SMBC_IPC_SHARE &&
00417             (strcmp(dirp->name, ".") != 0) && 
00418             (strcmp(dirp->name, "..") !=0)){
00419           
00420           subtree = gtk_tree_new();
00421           gtk_tree_item_set_subtree(GTK_TREE_ITEM(aitem), subtree);
00422 
00423           gtk_signal_connect(GTK_OBJECT(subtree), "select_child",
00424                              GTK_SIGNAL_FUNC(cb_select_child), real_tree);
00425           gtk_signal_connect(GTK_OBJECT(subtree), "unselect_child",
00426                              GTK_SIGNAL_FUNC(cb_unselect_child), real_tree);
00427 
00428         }
00429 
00430         (char *)dirp += dirlen;
00431         err -= dirlen;
00432 
00433       }
00434 
00435     }
00436 
00437     smbc_closedir(dh);   
00438 
00439   }
00440   else if (strncmp(signame, "collapse", 8) == 0) {
00441     GtkWidget *subtree = gtk_tree_new();
00442 
00443     gtk_tree_remove_items(GTK_TREE(real_tree), GTK_TREE(real_tree)->children);
00444 
00445     gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), subtree);
00446 
00447     gtk_signal_connect (GTK_OBJECT(subtree), "select_child",
00448                         GTK_SIGNAL_FUNC(cb_select_child), real_tree);
00449     gtk_signal_connect (GTK_OBJECT(subtree), "unselect_child",
00450                         GTK_SIGNAL_FUNC(cb_unselect_child), real_tree);
00451 
00452   }
00453 
00454 }
00455 
00456 static void cb_selection_changed( GtkWidget *tree )
00457 {
00458   GList *i;
00459   
00460   g_print ("selection_change called for tree %p\n", tree);
00461   g_print ("selected objects are:\n");
00462 
00463   i = GTK_TREE_SELECTION(tree);
00464   while (i){
00465     gchar *name;
00466     GtkLabel *label;
00467     GtkWidget *item;
00468 
00469     /* Get a GtkWidget pointer from the list node */
00470     item = GTK_WIDGET (i->data);
00471     label = GTK_LABEL (GTK_BIN (item)->child);
00472     gtk_label_get (label, &name);
00473     g_print ("\t%s on level %d\n", name, GTK_TREE
00474              (item->parent)->level);
00475     i = i->next;
00476   }
00477 }
00478 
00479 /*
00480  * Expand or collapse the whole network ...
00481  */
00482 static void cb_wholenet(GtkWidget *item, gchar *signame)
00483 {
00484   GtkWidget *real_tree, *aitem, *subtree;
00485   gchar *name;
00486   GtkLabel *label;
00487   gint dh, err, dirlen;
00488   char dirbuf[512];
00489   struct smbc_dirent *dirp;
00490   
00491   label = GTK_LABEL (GTK_BIN (item)->child);
00492   gtk_label_get (label, &name);
00493   g_print ("%s called for item %s->%p, level %d\n", signame, name,
00494            item, GTK_TREE (item->parent)->level);
00495 
00496   real_tree = GTK_TREE_ITEM_SUBTREE(item);  /* Get the subtree */
00497 
00498   if (strncmp(signame, "expand", 6) == 0) { /* Expand called */
00499 
00500     if ((dh = smbc_opendir("smb://")) < 0) { /* Handle error */
00501 
00502       g_print("cb_wholenet: Could not open dir smbc://, %s\n",
00503               strerror(errno));
00504 
00505       gtk_main_quit();
00506 
00507       return;
00508 
00509     }
00510 
00511     while ((err = smbc_getdents(dh, (struct smbc_dirent *)dirbuf, 
00512                                 sizeof(dirbuf))) != 0) {
00513 
00514       if (err < 0) { /* An error, report it */
00515 
00516         g_print("cb_wholenet: Could not read dir smbc://, %s\n",
00517                 strerror(errno));
00518 
00519         gtk_main_quit();
00520 
00521         return;
00522 
00523       }
00524 
00525       dirp = (struct smbc_dirent *)dirbuf;
00526 
00527       while (err > 0) {
00528         struct tree_data *my_data;
00529 
00530         dirlen = dirp->dirlen;
00531 
00532         my_data = make_tree_data(dirp->smbc_type, dirp->name);
00533 
00534         aitem = gtk_tree_item_new_with_label(dirp->name);
00535 
00536         /* Connect all GtkItem:: and GtkTreeItem:: signals */
00537         gtk_signal_connect (GTK_OBJECT(aitem), "select",
00538                             GTK_SIGNAL_FUNC(cb_itemsignal), "select");
00539         gtk_signal_connect (GTK_OBJECT(aitem), "deselect",
00540                             GTK_SIGNAL_FUNC(cb_itemsignal), "deselect");
00541         gtk_signal_connect (GTK_OBJECT(aitem), "toggle",
00542                             GTK_SIGNAL_FUNC(cb_itemsignal), "toggle");
00543         gtk_signal_connect (GTK_OBJECT(aitem), "expand",
00544                             GTK_SIGNAL_FUNC(cb_itemsignal), "expand");
00545         gtk_signal_connect (GTK_OBJECT(aitem), "collapse",
00546                             GTK_SIGNAL_FUNC(cb_itemsignal), "collapse");
00547 
00548         gtk_tree_append (GTK_TREE(real_tree), aitem);
00549         /* Show it - this can be done at any time */
00550         gtk_widget_show (aitem);
00551 
00552         gtk_object_set_user_data(GTK_OBJECT(aitem), (gpointer)my_data);
00553 
00554         fprintf(stdout, "Added: %s, len: %u\n", dirp->name, dirlen);
00555 
00556         subtree = gtk_tree_new();
00557 
00558         gtk_tree_item_set_subtree(GTK_TREE_ITEM(aitem), subtree);
00559 
00560         gtk_signal_connect(GTK_OBJECT(subtree), "select_child",
00561                            GTK_SIGNAL_FUNC(cb_select_child), real_tree);
00562         gtk_signal_connect(GTK_OBJECT(subtree), "unselect_child",
00563                            GTK_SIGNAL_FUNC(cb_unselect_child), real_tree);
00564 
00565         (char *)dirp += dirlen;
00566         err -= dirlen;
00567 
00568       }
00569 
00570     }
00571 
00572     smbc_closedir(dh);   
00573 
00574   }
00575   else { /* Must be collapse ... FIXME ... */
00576     GtkWidget *subtree = gtk_tree_new();
00577 
00578     gtk_tree_remove_items(GTK_TREE(real_tree), GTK_TREE(real_tree)->children);
00579 
00580     gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), subtree);
00581 
00582     gtk_signal_connect (GTK_OBJECT(subtree), "select_child",
00583                         GTK_SIGNAL_FUNC(cb_select_child), real_tree);
00584     gtk_signal_connect (GTK_OBJECT(subtree), "unselect_child",
00585                         GTK_SIGNAL_FUNC(cb_unselect_child), real_tree);
00586 
00587 
00588   }
00589 
00590 }
00591 
00592 /* Should put up a dialog box to ask the user for username and password */
00593 
00594 static void 
00595 auth_fn(const char *server, const char *share,
00596         char *workgroup, int wgmaxlen, char *username, int unmaxlen,
00597         char *password, int pwmaxlen)
00598 {
00599 
00600    strncpy(username, "test", unmaxlen);
00601    strncpy(password, "test", pwmaxlen);
00602 
00603 }
00604 
00605 static char *col_titles[] = {
00606   "Name", "Attributes", "Size", "Modification Date",
00607 };
00608 
00609 int main( int   argc,
00610           char *argv[] )
00611 {
00612   GtkWidget *window, *scrolled_win, *scrolled_win2, *tree;
00613   GtkWidget *subtree, *item, *main_hbox, *r_pane, *l_pane;
00614   gint err, dh;
00615   gint i;
00616   char dirbuf[512];
00617   struct smbc_dirent *dirp;
00618 
00619   gtk_init (&argc, &argv);
00620 
00621   /* Init the smbclient library */
00622 
00623   err = smbc_init(auth_fn, 10);
00624 
00625   /* Print an error response ... */
00626 
00627   if (err < 0) {
00628 
00629     fprintf(stderr, "smbc_init returned %s (%i)\nDo you have a ~/.smb/smb.conf file?\n", strerror(errno), errno);
00630     exit(1);
00631 
00632   }
00633 
00634   /* a generic toplevel window */
00635   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00636   gtk_widget_set_name(window, "main browser window");
00637   gtk_signal_connect (GTK_OBJECT(window), "delete_event",
00638                       GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
00639   gtk_window_set_title(GTK_WINDOW(window), "The Linux Windows Network Browser");
00640   gtk_widget_set_usize(GTK_WIDGET(window), 750, -1);
00641   gtk_container_set_border_width (GTK_CONTAINER(window), 5);
00642 
00643   gtk_widget_show (window);
00644 
00645   /* A container for the two panes ... */
00646 
00647   main_hbox = gtk_hbox_new(FALSE, 1);
00648   gtk_container_border_width(GTK_CONTAINER(main_hbox), 1);
00649   gtk_container_add(GTK_CONTAINER(window), main_hbox);
00650 
00651   gtk_widget_show(main_hbox);
00652 
00653   l_pane = gtk_hpaned_new();
00654   gtk_paned_gutter_size(GTK_PANED(l_pane), (GTK_PANED(l_pane))->handle_size);
00655   r_pane = gtk_hpaned_new();
00656   gtk_paned_gutter_size(GTK_PANED(r_pane), (GTK_PANED(r_pane))->handle_size);
00657   gtk_container_add(GTK_CONTAINER(main_hbox), l_pane);
00658   gtk_widget_show(l_pane);
00659 
00660   /* A generic scrolled window */
00661   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
00662   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
00663                                   GTK_POLICY_AUTOMATIC,
00664                                   GTK_POLICY_AUTOMATIC);
00665   gtk_widget_set_usize (scrolled_win, 150, 200);
00666   gtk_container_add (GTK_CONTAINER(l_pane), scrolled_win);
00667   gtk_widget_show (scrolled_win);
00668 
00669   /* Another generic scrolled window */
00670   scrolled_win2 = gtk_scrolled_window_new (NULL, NULL);
00671   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win2),
00672                                   GTK_POLICY_AUTOMATIC,
00673                                   GTK_POLICY_AUTOMATIC);
00674   gtk_widget_set_usize (scrolled_win2, 150, 200);
00675   gtk_paned_add2 (GTK_PANED(l_pane), scrolled_win2);
00676   gtk_widget_show (scrolled_win2);
00677   
00678   /* Create the root tree */
00679   tree = gtk_tree_new();
00680   g_print ("root tree is %p\n", tree);
00681   /* connect all GtkTree:: signals */
00682   gtk_signal_connect (GTK_OBJECT(tree), "select_child",
00683                       GTK_SIGNAL_FUNC(cb_select_child), tree);
00684   gtk_signal_connect (GTK_OBJECT(tree), "unselect_child",
00685                       GTK_SIGNAL_FUNC(cb_unselect_child), tree);
00686   gtk_signal_connect (GTK_OBJECT(tree), "selection_changed",
00687                       GTK_SIGNAL_FUNC(cb_selection_changed), tree);
00688   /* Add it to the scrolled window */
00689   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scrolled_win),
00690                                          tree);
00691   /* Set the selection mode */
00692   gtk_tree_set_selection_mode (GTK_TREE(tree),
00693                                GTK_SELECTION_MULTIPLE);
00694   /* Show it */
00695   gtk_widget_show (tree);
00696 
00697   /* Now, create a clist and attach it to the second pane */
00698 
00699   clist = gtk_clist_new_with_titles(4, col_titles);
00700 
00701   gtk_container_add (GTK_CONTAINER(scrolled_win2), clist);
00702 
00703   gtk_widget_show(clist);
00704 
00705   /* Now, build the top level display ... */
00706 
00707   if ((dh = smbc_opendir("smb:///")) < 0) {
00708 
00709     fprintf(stderr, "Could not list default workgroup: smb:///: %s\n",
00710             strerror(errno));
00711 
00712     exit(1);
00713 
00714   }
00715 
00716   /* Create a tree item for Whole Network */
00717 
00718   item = gtk_tree_item_new_with_label ("Whole Network");
00719   /* Connect all GtkItem:: and GtkTreeItem:: signals */
00720   gtk_signal_connect (GTK_OBJECT(item), "select",
00721                       GTK_SIGNAL_FUNC(cb_itemsignal), "select");
00722   gtk_signal_connect (GTK_OBJECT(item), "deselect",
00723                       GTK_SIGNAL_FUNC(cb_itemsignal), "deselect");
00724   gtk_signal_connect (GTK_OBJECT(item), "toggle",
00725                       GTK_SIGNAL_FUNC(cb_itemsignal), "toggle");
00726   gtk_signal_connect (GTK_OBJECT(item), "expand",
00727                       GTK_SIGNAL_FUNC(cb_wholenet), "expand");
00728   gtk_signal_connect (GTK_OBJECT(item), "collapse",
00729                       GTK_SIGNAL_FUNC(cb_wholenet), "collapse");
00730   /* Add it to the parent tree */
00731   gtk_tree_append (GTK_TREE(tree), item);
00732   /* Show it - this can be done at any time */
00733   gtk_widget_show (item);
00734 
00735   subtree = gtk_tree_new();  /* A subtree for Whole Network */
00736 
00737   gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), subtree);
00738 
00739   gtk_signal_connect (GTK_OBJECT(subtree), "select_child",
00740                       GTK_SIGNAL_FUNC(cb_select_child), tree);
00741   gtk_signal_connect (GTK_OBJECT(subtree), "unselect_child",
00742                       GTK_SIGNAL_FUNC(cb_unselect_child), tree);
00743 
00744   /* Now, get the items in smb:/// and add them to the tree */
00745 
00746   dirp = (struct smbc_dirent *)dirbuf;
00747 
00748   while ((err = smbc_getdents(dh, (struct smbc_dirent *)dirbuf, 
00749                               sizeof(dirbuf))) != 0) {
00750 
00751     if (err < 0) { /* Handle the error */
00752 
00753       fprintf(stderr, "Could not read directory for smbc:///: %s\n",
00754               strerror(errno));
00755 
00756       exit(1);
00757 
00758     }
00759 
00760     fprintf(stdout, "Dir len: %u\n", err);
00761 
00762     while (err > 0) { /* Extract each entry and make a sub-tree */
00763       struct tree_data *my_data;
00764       int dirlen = dirp->dirlen;
00765 
00766       my_data = make_tree_data(dirp->smbc_type, dirp->name);
00767 
00768       item = gtk_tree_item_new_with_label(dirp->name);
00769       /* Connect all GtkItem:: and GtkTreeItem:: signals */
00770       gtk_signal_connect (GTK_OBJECT(item), "select",
00771                           GTK_SIGNAL_FUNC(cb_itemsignal), "select");
00772       gtk_signal_connect (GTK_OBJECT(item), "deselect",
00773                           GTK_SIGNAL_FUNC(cb_itemsignal), "deselect");
00774       gtk_signal_connect (GTK_OBJECT(item), "toggle",
00775                           GTK_SIGNAL_FUNC(cb_itemsignal), "toggle");
00776       gtk_signal_connect (GTK_OBJECT(item), "expand",
00777                           GTK_SIGNAL_FUNC(cb_itemsignal), "expand");
00778       gtk_signal_connect (GTK_OBJECT(item), "collapse",
00779                           GTK_SIGNAL_FUNC(cb_itemsignal), "collapse");
00780       /* Add it to the parent tree */
00781       gtk_tree_append (GTK_TREE(tree), item);
00782       /* Show it - this can be done at any time */
00783       gtk_widget_show (item);
00784 
00785       gtk_object_set_user_data(GTK_OBJECT(item), (gpointer)my_data);
00786 
00787       fprintf(stdout, "Added: %s, len: %u\n", dirp->name, dirlen);
00788 
00789       subtree = gtk_tree_new();
00790 
00791       gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), subtree);
00792 
00793       gtk_signal_connect (GTK_OBJECT(subtree), "select_child",
00794                           GTK_SIGNAL_FUNC(cb_select_child), tree);
00795       gtk_signal_connect (GTK_OBJECT(subtree), "unselect_child",
00796                           GTK_SIGNAL_FUNC(cb_unselect_child), tree);
00797 
00798       (char *)dirp += dirlen;
00799       err -= dirlen;
00800 
00801     }
00802 
00803   }
00804 
00805   smbc_closedir(dh); /* FIXME, check for error :-) */
00806 
00807   /* Show the window and loop endlessly */
00808   gtk_main();
00809   return 0;
00810 }
00811 /* example-end */

Sambaに対してSat Aug 29 21:22:53 2009に生成されました。  doxygen 1.4.7