Project Homepage Sourceforge Page CVS Repository Freshmeat.net Page Download project Author's Homepage

main.c File Reference


Detailed Description

run-free main file

run-free is a command line launching program written in gtk. This version of run-free is written is C for gtk+1.2

Definition in file main.c.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include "interface.h"
#include "support.h"
#include "main.h"
#include "comboBox.h"
#include "kbhit.h"
#include "commonDefs.h"
#include "debug.h"
#include "comboHandlers.h"
#include "help.h"
#include <getopt.h>
#include <sys/types.h>
#include <unistd.h>

Include dependency graph for main.c:

Include dependency graph

Go to the source code of this file.

getopt externs

externs from getopt functionality

char * optarg
 command line options

int optind
 option arguments

int opterr
 option arguments

int optopt
 option arguments

char ** environ
 the environment


Functions

int main (int argc, char *argv[], char *env[])
 The Main.

void run_command (char *command)
 Run a command.


Function Documentation

int main int  argc,
char *  argv[],
char *  env[]
 

The Main.

Long mian function that is intended to be split up some day

get the user's home directory

Todo:
cleanup getopt stuff -it's messy!

add cleanup routines

Definition at line 78 of file main.c.

References bash_shell_mode, cbitems, checkbutton, combo1, combo_init(), combo_mode, command, create_fileselection(), create_mainWindow(), DEBUG_MODE, die, do_kbhit(), dprint, dprint_s2, fileselection, freeList(), history_file, history_len, home_directory, keep_open, KEYSTROKES, mainWindow, no_kbhit, optarg, OPTARG_HISTORY, OPTARG_HISTORY_FILETYPE_BASH, OPTARG_HISTORY_FILETYPE_RF, OPTARG_HISTORY_LEN, RF_EXAMPLE_MODE, RF_HISTORY_FILENAME, RF_HISTORY_MODE, run_in_term, and terminal_path.

00079 {
00080   gboolean gui =TRUE, history_set =FALSE, listops = FALSE;
00081   
00082 
00083   int opt =0;
00084 
00085 
00086   /*Global_Initialization -Items initialized for runtime
00087    */
00088   history_file = NULL;          
00089   command = NULL;
00090   terminal_path = NULL;
00091   die = TRUE;                   
00092   run_in_term = FALSE;          
00093   no_kbhit = FALSE;
00094   combo_mode = RF_HISTORY_MODE; 
00095   keep_open = FALSE;
00096 
00097   //init gtk stuff
00098   gtk_set_locale ();
00099   gtk_init (&argc, &argv);
00100 
00101   char *home_directory = getenv("HOME"); /*! get the user's home directory */
00102 
00103   //show debug mode message
00104   dprint("run-free: debug mode enabled");
00105 
00106   //loop through the argument options
00107   while(1)
00108     {
00109       int option_index = 0;
00110       static struct option long_options[] = {
00111         {"bash", 0, 0, 'b'},
00112         {"command", 1, 0, 'c'},
00113         {"die", 0, 0, 'd'},
00114         {"help", 0, 0, 'h'},
00115         {"histlen", 1, 0, 0},
00116         {"history", 1, 0, 0},
00117         {"kbhit", 0, 0, 'k'},
00118         {"nokbhit", 0, 0, 'i'},
00119         {"keystrokes", 0, 0, 'y'},
00120         {"listops", 0, 0, 'l'},
00121         {"termstay", 0, 0, 'o'},
00122         {"runterm", 0, 0, 'r'},
00123         {"terminal", 1, 0, 't'},
00124         {"version", 0, 0, 'V'},
00125         //{"smart", 0, 0, 's'},
00126         {0, 0, 0, 0}
00127       };
00128 
00129       /**\todo cleanup getopt stuff -it's messy! */
00130 
00131       //do command line processing
00132       opt = getopt_long(argc, argv, "bc:dhiklort:yV", long_options, &option_index);
00133 
00134       if(opt == -1)
00135         break;
00136       
00137       switch(opt)
00138         {
00139         case 0:         //long arguments
00140           if(strcmp(long_options[option_index].name, OPTARG_HISTORY) ==0)
00141             {
00142               //handle history file
00143               if(strcmp(optarg, OPTARG_HISTORY_FILETYPE_RF)==0) //run-free
00144                 {
00145                   history_file = g_malloc(strlen(home_directory)+strlen(RF_HISTORY_FILENAME)+2);
00146                   sprintf(history_file, "%s/%s", home_directory, RF_HISTORY_FILENAME);
00147                 }
00148               else if(strcmp(optarg, OPTARG_HISTORY_FILETYPE_BASH)==0) //bash
00149                 {
00150                   history_file = g_malloc(strlen(home_directory)+strlen(BASH_HISTORY_FILENAME)+2);
00151                   sprintf(history_file, "%s/%s", home_directory, BASH_HISTORY_FILENAME);
00152                 }
00153               else
00154                 {
00155                   history_file = g_malloc(strlen(optarg)+1);
00156                   sprintf(history_file,"%s", optarg); //xxx
00157                 }
00158               history_set++;
00159             }
00160           else if(strcmp(long_options[option_index].name, OPTARG_HISTORY_LEN) ==0)
00161             {
00162               history_len = atol(optarg);
00163             }
00164           break;
00165         case 'b':
00166           bash_shell_mode = TRUE;
00167           break;
00168         case 'c':
00169           //copy command from command line
00170           if(optarg)
00171             {
00172               command = g_malloc(strlen(optarg)+1);
00173               sprintf(command, "%s", optarg);           /* copy the string */
00174             }
00175           break;
00176         case 'd':
00177           die = FALSE;
00178           break;
00179         case 'h':
00180           g_print("%s: version %s.\n%s\n", PACKAGE, VERSION, COPYRIGHT);
00181           g_print("%s\n\n", LICENSE);
00182           g_print("\nHELP:\n");
00183           char *help = 
00184             "-b, --bash\t\tRun in Bash mode (reads ~/.bashrc before execution)"
00185             "\n"
00186             "-c, --command=COMMAND\tSet COMMAND in entry box on startup"
00187             "\n"
00188             "-d, --die\t\tDo NOT die after executing a command"
00189             "\n"
00190             "-h, --help\t\tThis help list"
00191             "\n"
00192             "    --histlen=NUM\tShow NUM items from history in history list"
00193             "\n"
00194             "    --history=FILEPATH\tUse history file from FILEPATH"
00195             "\n"
00196             "-i, --nokbhit\t\tDo NOT allow keyboard hit mode (DON'T show \"HIT ANY KEY\" on exit)"
00197             "\n"
00198             "-k, --kbhit\t\tRun in keyboard hit mode (show \"HIT ANY KEY\" and exit)"
00199             "\n"
00200             "-l, --listops\t\tList default (compiled in) options and exit"
00201             "\n"
00202             "-o, --termstay\t\tKeep the terminal open after command exec"
00203             "\n"
00204             "-r, --runterm\t\tSet run_in_term mode on startup"
00205             "\n"
00206             "-t, --terminal=TERMPATH\tUse TERMPATH program for run_in_terminal mode"
00207             "\n"
00208             "-y, --keystrokes\tDisplay the keystrokes for run-free"
00209             "\n"
00210             "-V, --version\t\tShow version and copyright information"
00211             "\n";
00212           g_print("%s", help);
00213           exit(0);
00214           break;
00215         case 'i':
00216           no_kbhit = TRUE;
00217           break;
00218         case 'k':
00219           gui = FALSE;
00220           break;
00221         case 'l':
00222           listops = TRUE;
00223           break;
00224         case 'o':
00225           keep_open = TRUE;
00226           break;
00227         case 'r':
00228           run_in_term = TRUE;
00229           break;
00230         case 't':
00231           if(optarg)
00232             {
00233               terminal_path = g_malloc(strlen(optarg)+1);
00234               sprintf(terminal_path, "%s", optarg);
00235             }
00236           break;
00237         case 'y':
00238           g_print("%s: version %s.\n%s\n", PACKAGE, VERSION, COPYRIGHT);
00239           g_print("%s\n\n", LICENSE);
00240           g_print("\nKEYSTROKES:\n");
00241           g_print("%s\n",KEYSTROKES);
00242 
00243           /**\todo add cleanup routines */
00244 
00245           //cleanup
00246           freeList(cbitems);
00247           g_free(history_file);
00248           g_free(home_directory);
00249           g_free(command);
00250           g_free(terminal_path);
00251           exit(0);
00252           break;
00253         case 'V':
00254           g_print("%s: version %s.\n%s\n", PACKAGE, VERSION, COPYRIGHT);
00255           g_print("%s\n\n", LICENSE);
00256           exit(0);
00257           break;
00258         default:
00259           dprint("an argument is not being delt with");
00260           break;
00261         }
00262     }
00263   
00264 
00265   //handle options not set
00266   if(!history_set)
00267     {
00268       //string terminators are accounted for
00269 #ifdef USE_USER_HISTORY_FILENAME 
00270       dprint_s2("user history compile option",USER_HISTORY_FILENAME);
00271       history_file = g_malloc(strlen(USER_HISTORY_FILENAME)+1);
00272       sprintf(history_file, "%s", USER_HISTORY_FILENAME);
00273 #else 
00274       dprint_s2("bash history compile option",BASH_HISTORY_FILENAME);
00275       history_file = g_malloc(strlen(home_directory)+strlen(BASH_HISTORY_FILENAME)+2);
00276       sprintf(history_file, "%s/%s", home_directory, BASH_HISTORY_FILENAME);
00277 #endif
00278     }
00279 
00280   if(!history_len)
00281     history_len = DEFAULT_HISTORY_LEN;
00282 
00283   if(terminal_path == NULL)
00284     {
00285       terminal_path = g_malloc(strlen(DEFAULT_TERMINAL_PATH)+1);
00286       sprintf(terminal_path, "%s", DEFAULT_TERMINAL_PATH);
00287     }
00288 
00289   if(listops)
00290     {
00291       g_print("%s: version %s.\n%s\n", PACKAGE, VERSION, COPYRIGHT);
00292       g_print("%s\n\n", LICENSE);
00293       g_print("\n");
00294 
00295 #ifdef USE_USER_HISTORY_FILENAME
00296       char *use_user_history_filename = "yes";
00297 #else
00298       char *use_user_history_filename = "no";
00299 #endif
00300       //list the default run-time options and exit
00301       g_print("debug mode \t\t\t\t=%s\n", DEBUG_MODE?"yes":"no");
00302       g_print("default history display length\t\t=%d\n", history_len);
00303       g_print("use user history file by default\t=%s\n",use_user_history_filename);
00304       g_print("name of default user history file: %s\n", USER_HISTORY_FILENAME);
00305       g_print("name of default bash history file:%s/%s\n", home_directory, BASH_HISTORY_FILENAME);
00306       g_print("run_in_term mode terminal path:%s\n", terminal_path);
00307       exit(0);
00308     }
00309 
00310 
00311   //post handle command line options 
00312   if(!gui)
00313     {
00314         do_kbhit();
00315       
00316       //cleanup
00317       freeList(cbitems);
00318       g_free(history_file);
00319       g_free(home_directory);
00320       g_free(command);
00321       g_free(terminal_path);
00322     }
00323   else
00324     {
00325       //already did this
00326       //gtk_set_locale ();
00327       //gtk_init (&argc, &argv);
00328     
00329       //create the main window
00330       mainWindow = create_mainWindow ();
00331       gtk_widget_show (mainWindow);
00332 
00333       //we create it but don't show it until it's needed
00334       fileselection = create_fileselection ();
00335 
00336       //set the state of the run_in_term button
00337       if(run_in_term)
00338         {
00339           run_in_term = FALSE;  /* cheezy */
00340           gtk_button_clicked(GTK_BUTTON(checkbutton)); 
00341         }
00342 
00343       //initialize the combo box in history mode
00344       //combo_init(RF_HISTORY_MODE);
00345       combo_init(RF_EXAMPLE_MODE);
00346       combo_init(RF_HISTORY_MODE);
00347 
00348       if(command !=NULL)
00349         {
00350           //gtk_entry_set_text(combo_entry1, command);
00351           gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo1)->entry), command);
00352           dprint_s2("startup command", command);
00353         }
00354       
00355       //run the program
00356       gtk_main ();
00357     }
00358 
00359   return 0;
00360 }

Here is the call graph for this function:

void run_command char *  command  ) 
 

Run a command.

Author:
Karl N. Redman
Parameters:
command The command we want to run
Purpose: Execute the command in a way that is consistant with the design of run-free.

Note:
This is a custom system() type call in order to handle environment settings properly (in the future) if this program is to be a setuid application (which is in the works)

Warning:
NOTE: this function is a potential security problem because we are not replacing the environment. if this is ever going to be a SUID application then I need to handle this. I'll work on this in the future -parasyte

Definition at line 383 of file main.c.

References bash_shell_mode, combo_init(), combo_mode, command, die, environ, history_file, keep_open, no_kbhit, run_in_term, terminal_path, and writeHistory().

Referenced by on_combo_entry1_key_press_event(), and on_runButton_clicked().

00384 {
00385 
00386   char pre[64], post[64], *buffer;
00387 
00388   //anything except NULL is allowed.
00389   if(!command)
00390     return;
00391 
00392   //populate parts of the command
00393   if(run_in_term)
00394     {
00395       //we want to run this in a terminal so act accordingly
00396       if(bash_shell_mode == TRUE)
00397         {
00398           //endable user alias settings (i.e. ls --color)
00399           strcpy(pre," -e bash -i -c \'");
00400         }
00401       else
00402         {
00403           strcpy(pre," -e sh -c \'");
00404         }
00405 
00406       if(!no_kbhit)
00407         {
00408           //alsways show "HIT ANY KEY"
00409           if(keep_open)
00410             if(bash_shell_mode == TRUE)
00411               strcpy(post, ";  bash -i \'&");
00412             else
00413               strcpy(post, ";  sh \'&");
00414           else
00415             strcpy(post, "; run-free -k \'&");
00416         }
00417       else
00418         if(keep_open)
00419             if(bash_shell_mode == TRUE)
00420               strcpy(post, ";  bash -i \'&");
00421             else
00422               strcpy(post, ";  sh \'&");
00423         else
00424           strcpy(post, "; \'&");
00425         
00426 
00427       //allocate a buffer
00428       buffer = g_malloc(strlen(terminal_path)
00429                       +strlen(pre)
00430                       +strlen(command)
00431                       +strlen(post)
00432                       +1);
00433       
00434       //populate the buffer with the command
00435       sprintf(buffer, "%s%s%s%s", terminal_path, pre, command, post);
00436     }
00437   else
00438     {
00439       //no terminal, we must want to just execute something in the
00440       //background
00441       strcpy(pre, "");
00442       strcpy(post, " &");
00443 
00444       //allocate a buffer
00445       buffer = g_malloc( +strlen(pre)
00446                       +strlen(command)
00447                       +strlen(post)
00448                       +1);
00449       
00450       //populate the buffer with the command
00451       sprintf(buffer, "%s%s%s", pre, command, post);
00452     }
00453       
00454 
00455 
00456   //fork the program to execute the command
00457   int pid = fork();
00458 
00459   //if we are the child...
00460   if(pid == 0)
00461     {
00462       //update the history file
00463       writeHistory(command, history_file);
00464 
00465       //populate the command to execute 
00466       char * argv[4];
00467       argv[0] = "sh";
00468       argv[1] = "-c";
00469       argv[2] = (char *)buffer;
00470       argv[3] = 0;
00471 
00472       /**\warning
00473          NOTE: this function is a potential security problem because we are not
00474          replacing the environment. if this is ever going to be a SUID
00475          application then I need to handle this. I'll work on this in the
00476          future -parasyte
00477       */
00478       //execute the program
00479       execve("/bin/sh", argv, environ);
00480       
00481       //free memory
00482       g_free(buffer);
00483 
00484       //exit properly
00485       exit(0);
00486     }
00487   else
00488     {
00489       g_free(buffer);
00490 
00491       if(die)
00492         {
00493           //kill the main program
00494           gtk_main_quit();
00495         }
00496       else
00497         {
00498           //update the history list
00499           combo_init(combo_mode);
00500         }
00501     }
00502 }

Here is the call graph for this function:


Variable Documentation

char** environ
 

the environment

Definition at line 71 of file main.c.

Referenced by run_command().

char* optarg
 

command line options

Definition at line 67 of file main.c.

Referenced by main().

int opterr
 

option arguments

Definition at line 69 of file main.c.

int optind
 

option arguments

Definition at line 69 of file main.c.

int optopt
 

option arguments

Definition at line 69 of file main.c.


Generated on Thu Mar 18 07:26:19 2004 for run-free by doxygen 1.3.5