"Fossies" - the Fresh Open Source Software Archive

Member "xarchive-0.2.8-6/src/main.c" (23 Feb 2006, 12691 Bytes) of package /linux/privat/old/xarchive-0.2.8-6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "main.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  *  Xarchive - a gtk2.0 front-end for various command like archive tools 
    3  *  Copyright (C) 2005 Lee Bigelow <ligelowbee@yahoo.com> 
    4  *
    5  *  This program is free software; you can redistribute it and/or modify
    6  *  it under the terms of the GNU General Public License as published by
    7  *  the Free Software Foundation; either version 2 of the License, or
    8  *  (at your option) any later version.
    9  *
   10  *  This program is distributed in the hope that it will be useful,
   11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13  *  GNU General Public License for more details.
   14  *
   15  *  You should have received a copy of the GNU General Public License
   16  *  along with this program; if not, write to the Free Software
   17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   18  */
   19 
   20 #include"main.h"
   21 
   22 #ifndef HAVE_CANONICALIZE_FILE_NAME
   23 char *
   24 canonicalize_file_name(char *path)
   25 {
   26   char *name, rzpath[256];
   27   name = realpath(path, rzpath);
   28   return name;
   29 }
   30 #endif
   31 
   32 #ifndef HAVE_GETLINE
   33 ssize_t
   34 getline(char **lineptr, size_t *n, FILE *stream)
   35 {
   36   char *line;
   37   size_t len;
   38 
   39   line = fgetln(stream, &len);
   40   if (!line) return -1;
   41   if (len >= *n) 
   42   {
   43     char *tmp;
   44     tmp = realloc(*lineptr, len+1);
   45     if (!tmp) return -1;
   46     *lineptr = tmp;
   47     *n = len + 1;
   48   }
   49   memcpy(*lineptr, line, len);
   50   (*lineptr)[len] = 0;
   51   return len;
   52 }
   53 #endif
   54 
   55 void 
   56 setup_exts(WrapperEntry *wrapent)
   57 {
   58   int maxline=MAXLINE;
   59   gchar *dataline = (gchar *) g_malloc (MAXLINE + 1);
   60   gchar *cmd, *extname;
   61   FILE *fdata;
   62   gchar delimit[]=";\n";
   63   GPtrArray *ext_array = NULL;
   64 
   65   /* read extentions into dataline from wrapper */
   66   cmd = g_strdup_printf("%s -i", wrapent->path);
   67   fdata = popen(cmd, "r");
   68   if (getline(&dataline, &maxline, fdata) > 0) 
   69   {
   70     /*get first ext token and add it to array */
   71     if ((extname = strtok(dataline, delimit)) != NULL)
   72     {
   73       ext_array = g_ptr_array_new();
   74       g_ptr_array_add(ext_array, g_strdup_printf("*.%s",extname));
   75     } 
   76     while ((extname = strtok(NULL,delimit)) != NULL)
   77     {
   78       g_ptr_array_add(ext_array, g_strdup_printf("*.%s",extname));
   79     }
   80     wrapent->ext_array = ext_array;
   81     pclose(fdata);
   82   }
   83   g_free(cmd);
   84 }
   85 
   86 WrapperEntry *
   87 make_wrapper(gchar *dir,gchar *fname)
   88 {
   89   WrapperEntry *wrapent;
   90 
   91   wrapent = (WrapperEntry *) g_malloc (sizeof(WrapperEntry));
   92   wrapent->path = g_strdup_printf("%s/%s", dir, fname);
   93   wrapent->ext_array = NULL;
   94   
   95   return wrapent;
   96 }
   97 
   98 gint 
   99 is_wrapper(const struct dirent *dirent)
  100 {
  101   /* used as a filter for scandir */
  102   /* check if name contains "wrap" */
  103   if (fnmatch("*wrap*",dirent->d_name,FNM_PERIOD|FNM_CASEFOLD) == 0) 
  104     return 1;
  105     
  106   return 0;
  107 }
  108 
  109 void 
  110 setup_wrappers(void)
  111 {
  112   gchar *home;
  113   gint nwraps, i, cnt;
  114   struct dirent **dirents;
  115   WrapperEntry *wrapent = NULL;
  116 
  117   home = g_strdup_printf("%s/.xarchive/wrappers", getenv("HOME"));
  118   char *dir[] = 
  119     { 
  120       home, 
  121       WRAPPER_DIR, 
  122       canonicalize_file_name("../wrappers"), 
  123       NULL 
  124     };
  125   WRAPPER_ARRAY = g_ptr_array_sized_new(10);
  126   for ( i=0; dir[i] != NULL; i++) 
  127   {
  128     g_print("dir: %s\n",dir[i]);
  129     nwraps = scandir(dir[i], &dirents, is_wrapper, alphasort);
  130     if (nwraps > 0) 
  131     {
  132       g_print("Found %d wrappers\n", nwraps);
  133       /* fill wrapper list*/
  134       for (cnt=0; cnt < nwraps; cnt++) 
  135       {
  136         wrapent = make_wrapper(dir[i],dirents[cnt]->d_name);
  137         setup_exts(wrapent);
  138         g_ptr_array_add(WRAPPER_ARRAY, wrapent);
  139       }
  140       free(dirents);
  141     } 
  142     else g_print("no wrappers in %s\n", dir[i]);
  143   }
  144   g_free(home);
  145   if (WRAPPER_ARRAY->len == 0) 
  146   {
  147     g_print("No wrappers found\n");
  148   }
  149 } 
  150 
  151 extern gchar * 
  152 wrapper_info(void)
  153 {
  154   GString *info_text;
  155   WrapperEntry *wrapent;
  156   gchar *ext;
  157   gint w,e;
  158 
  159   info_text = g_string_new("Wrappers found and their supported file extensions:\n");
  160   if (WRAPPER_ARRAY == NULL)
  161     return g_strdup_printf("No wrappers found..\n"
  162                            "Please check your wrapper dirs:\n\n"
  163                            "%s\n"
  164                            "%s/.xarchive/wrappers",
  165                            WRAPPER_DIR, getenv("HOME"));
  166   for (w = 0; w < WRAPPER_ARRAY->len; w++)
  167   {
  168     wrapent = (WrapperEntry *) g_ptr_array_index(WRAPPER_ARRAY, w);
  169     g_string_append_printf(info_text,"\n%s\n     Extentions: ",
  170                          wrapent->path);
  171     if (wrapent->ext_array == NULL)
  172     {
  173       g_string_append_printf(info_text, 
  174                              "** Needed program not found, ignored **\n");
  175       continue;
  176     }
  177     for (e = 0; e < wrapent->ext_array->len; e++)
  178     {
  179       ext = (gchar *) g_ptr_array_index(wrapent->ext_array, e);
  180       g_string_append_printf(info_text,"%s ", ext);
  181     }
  182     g_string_append_c(info_text, '\n');
  183   }
  184   return g_string_free(info_text, FALSE);
  185 }
  186 
  187 gchar *
  188 get_wrapper(gchar *archive)
  189 {
  190   /* returns path string of appropriate wrapper for archive, or NULL */
  191   WrapperEntry *wrapent;
  192   gchar *ext;
  193   gint w, e;
  194   
  195   if (WRAPPER_ARRAY == NULL) 
  196     return NULL;
  197   for (w=0; w < WRAPPER_ARRAY->len; w++)
  198   {
  199     wrapent = (WrapperEntry *) g_ptr_array_index(WRAPPER_ARRAY, w);
  200     if (wrapent->ext_array == NULL) 
  201       continue;
  202     for(e = 0; e < wrapent->ext_array->len; e++)
  203     { 
  204       ext = (gchar *) g_ptr_array_index(wrapent->ext_array, e);
  205       if (fnmatch(ext, archive, FNM_CASEFOLD) == 0)
  206         return wrapent->path;
  207     }
  208   }
  209   return NULL;
  210 }
  211 
  212 int 
  213 get_archive_data(gchar **argv)
  214 {
  215   /* read in archive contents from wrapper line by line
  216    * sending each line to the widgets add_row function */
  217   enum {name=0,size,attr,user,group,date,time,link,num_ent};
  218   FILE *fdata;
  219   gint cnt, maxline=MAXLINE, i = 20, error = 0;
  220   gchar *ent[num_ent], *esc_archive;
  221   gchar *dataline = (gchar *) g_malloc (MAXLINE + 1);
  222   gchar delimit[]=";\n";
  223   gchar *cmd = NULL;
  224   gboolean stopit = FALSE;
  225   GtkWidget *pbwin, *pbar;
  226   GtkListStore *liststore;
  227   GtkTreeView *treeview;
  228   
  229   treeview = get_current_tree();
  230   liststore = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
  231   g_object_ref(G_OBJECT(liststore));
  232   gtk_tree_view_set_model(treeview, NULL);
  233 
  234   pbar = gtk_progress_bar_new();
  235   pbwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  236   setup_opening_progress_bar(pbwin, pbar, &stopit);
  237 
  238   esc_archive = my_strescape(argv[2]);
  239   cmd = g_strdup_printf("%s %s %s", argv[0], argv[1], esc_archive);
  240   g_free(esc_archive);
  241   fdata = popen(cmd, "r"); 
  242   while ( (error == 0) && (getline(&dataline, &maxline, fdata) > 0))
  243   {
  244     if (i == 20)
  245     {
  246       gtk_progress_bar_pulse(GTK_PROGRESS_BAR(pbar));
  247       while (gtk_events_pending())
  248         gtk_main_iteration();
  249       i = 0;
  250     }
  251     i++;
  252     
  253     if (stopit == TRUE)
  254     {
  255       error = -1;
  256       break;
  257     }
  258     ent[name] = strtok(dataline,delimit);
  259     for (cnt = size; cnt < num_ent; cnt++) 
  260     { 
  261       ent[cnt] = strtok(NULL,delimit);
  262       if ( (ent[cnt] == NULL) && (cnt < link) ) 
  263       {
  264         g_print("Error running cmd: %s\n", cmd);
  265         message(MAIN_WINDOW,
  266         GTK_MESSAGE_ERROR, "Error reading file");
  267         error = -1;
  268         break;
  269       }
  270     }
  271     if (error == 0) add_row(liststore, ent);
  272   }
  273   pclose(fdata);
  274   free(dataline);
  275 
  276   gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(liststore));
  277   g_object_unref(G_OBJECT(liststore));
  278 
  279   gtk_widget_destroy(pbwin);
  280   while(gtk_events_pending())
  281     gtk_main_iteration();
  282 
  283   return error;
  284 }
  285 
  286 gint 
  287 wrapper_cmd(gint ar_func, gchar *argv[], gchar *dir)
  288 {
  289   /* order: AR_OPEN, AR_NEW, AR_EXTRACT, AR_ADD, AR_REMOVE, AR_VIEW */
  290   gchar *wrap_opt[]= { "-o", "-n", "-e", "-a", "-r", "-v" }; 
  291   gint wrapper_status = 0, i;
  292   GPid pid;
  293   GError *error;
  294     
  295   if ((argv[WRAPPER_INDEX] = g_strdup(get_wrapper(argv[ARCHIVE_INDEX]))) 
  296       == NULL )
  297   {
  298     g_print("from main.c: No wrapper found for archive %s\n", 
  299             argv[ARCHIVE_INDEX]);
  300     return -1;
  301   } 
  302 
  303   argv[OPTION_INDEX] = g_strdup(wrap_opt[ar_func]);
  304   
  305   g_print("from wrapper_cmd: ");
  306   for (i=0; argv[i] != NULL; i++)
  307     g_print("%s ", argv[i]);
  308   g_print("\n");
  309 
  310   switch ( ar_func ) 
  311   {
  312     case AR_OPEN:       
  313       if (get_archive_data(argv) < 0) return -1;
  314       break;
  315     case AR_ADD:
  316     case AR_NEW:        
  317     case AR_REMOVE:     
  318     case AR_VIEW:
  319     case AR_EXTRACT:
  320       g_spawn_async(dir, /* working dir */
  321                     argv, /* argument vector */
  322                     NULL, /* env vector */
  323                     G_SPAWN_DO_NOT_REAP_CHILD, /* GSpawnFlags */
  324                     NULL, /* child setup function */
  325                     NULL, /* child setup data */
  326                     &pid, /* GPid process pid */
  327                     &error); /* GError error */
  328       /* wait for the command and run the progress bar */
  329       wait_with_progress_bar(pid, &wrapper_status, ar_func); 
  330       break;
  331     default:    
  332       break;
  333   }
  334 
  335   g_print("wrapper exited with: %i\n", WEXITSTATUS(wrapper_status));
  336   switch (WEXITSTATUS(wrapper_status)) 
  337   {
  338     case 0:
  339       return 0;
  340     case E_UNSUPPORTED:
  341       message(MAIN_WINDOW,
  342           GTK_MESSAGE_ERROR, 
  343               "Action not supported by wrapper for this archive type.");
  344       return -1;
  345     default:
  346       message(MAIN_WINDOW,
  347           GTK_MESSAGE_ERROR, 
  348               "Wrapper exited with a error.");
  349       return -1;
  350   }
  351 }
  352 
  353 void
  354 setup_home_directory(void)
  355 {
  356   gchar *dir;
  357 
  358   dir = g_strdup_printf("%s/.xarchive", getenv("HOME"));
  359   if (g_file_test(dir, G_FILE_TEST_IS_DIR) == FALSE)  
  360     g_mkdir(dir, S_IRWXU|S_IRWXG);
  361   g_free(dir);
  362 
  363   dir = g_strdup_printf("%s/.xarchive/wrappers", getenv("HOME"));
  364   if (g_file_test(dir, G_FILE_TEST_IS_DIR) == FALSE)  
  365     g_mkdir(dir, S_IRWXU|S_IRWXG);
  366   g_free(dir);
  367 }
  368 
  369 ParsedArgs *
  370 parse_options(gint argc, gchar *argv[])
  371 {
  372   
  373   ParsedArgs *pargs = (ParsedArgs *) g_malloc (sizeof(ParsedArgs));
  374   GError *error = NULL;
  375   GOptionContext *context;
  376   gchar *cfname = NULL;
  377   gchar *afname = NULL;
  378   GOptionEntry entries[] = 
  379     {
  380       { "geometry", 'g', 0, G_OPTION_ARG_STRING, &pargs->geom, 
  381         "Change intial widget geometry to GEOM.\n"
  382         "\t\t\t   Format: WxH+Xpos+Ypos, eg 500x300+10+10\n", 
  383         "GEOM" },
  384       { "create", 'c', 0, G_OPTION_ARG_FILENAME, &cfname, 
  385         "Create an archive named ARCHIVE containing FILES.\n"
  386         "\t\t\t   ARCHIVE should be the full path to the archive.\n"
  387         "\t\t\t   FILES will be shown in a file chooser.\n"
  388         "\t\t\t   If the name 'ask' is passed as the ARCHIVE name\n"
  389         "\t\t\t   XArchive will give you a file creation dialog.\n"
  390         "\t\t\t   May not be used with -a option.\n",
  391         "ARCHIVE" },
  392       { "add", 'a', 0, G_OPTION_ARG_FILENAME, &afname,
  393         "Add FILES to ARCHIVE.\n"
  394         "\t\t\t   ARCHIVE should be the full path to the archive.\n"
  395         "\t\t\t   FILES will be shown in a file chooser.\n"
  396         "\t\t\t   If the name 'ask' is passed as the ARCHIVE name\n"
  397         "\t\t\t   XArchive will give you a file selector dialog.\n"
  398         "\t\t\t   May not be used with -c option.\n",
  399         "ARCHIVE" },
  400       { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &pargs->files, 
  401         NULL, NULL },
  402       { NULL }
  403     };
  404   
  405   pargs->action = AR_OPEN;
  406   pargs->archive = NULL;
  407   pargs->files = NULL;
  408   pargs->geom = NULL;
  409 
  410   context=g_option_context_new("[FILES...]\n\n"
  411                                "\tWithout an option each file in the list\n"
  412                                "\tof passed FILES is treated as an archive\n"
  413                                "\tand an attempt is made to open them.\n"
  414                                "\tWith no FILES passed an info page is shown."
  415                                );
  416   g_option_context_add_main_entries (context, entries, NULL);
  417   g_option_context_add_group (context, gtk_get_option_group (TRUE));
  418   g_option_context_parse (context, &argc, &argv, &error);
  419   g_option_context_free(context);
  420 
  421   if (error != NULL || (cfname != NULL && afname != NULL))
  422   {
  423     g_printerr("Error parsing options\n"
  424                "Note: you can use -c ** OR ** -a, not both.\n"
  425                "Please see:  xarchive --help\n"
  426                "or:          man xarchive\n");
  427     exit(EXIT_FAILURE);
  428   }
  429   if (cfname != NULL)
  430   {
  431     pargs->archive = cfname;
  432     pargs->action = AR_NEW;
  433   }
  434   else if (afname != NULL)
  435   {
  436     pargs->archive = afname;
  437     pargs->action = AR_ADD;
  438   }
  439   
  440   return pargs;
  441 }     
  442 
  443 int 
  444 main( gint argc, gchar *argv[] )
  445 {
  446   gchar *wrapinf;
  447   ParsedArgs *pargs;
  448 
  449   pargs = parse_options(argc, argv);
  450   setup_home_directory();
  451   setup_wrappers();
  452 
  453   wrapinf = wrapper_info();
  454   g_print("%s\n%s\n\n", PACKAGE_STRING, PACKAGE_BUGREPORT);
  455   puts(wrapinf);
  456   g_free(wrapinf);
  457 
  458   make_widgets(pargs);
  459 
  460   return 0;
  461 }