1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
|
/*
* gnome-exe-handler.c: Invoked when the user double clicks on an ELF
* file, we need to figure out what to do with it.
*
* Author:
* Miguel de Icaza (miguel@ximian.com)
*/
#include <config.h>
#include <gnome.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
enum {
OK_DIALOG = 0,
YESNO_DIALOG = 1,
WARNING_DIALOG = TRUE,
ERROR_DIALOG = FALSE,
WINDOW_CLOSE = -1,
OK_BUTTON = 0,
YES_BUTTON = 0,
NO_BUTTON = 1
};
static int
message (const char *msg, int type, gboolean warning)
{
GtkWidget *box;
char *b1, *b2, *b3;
int help_button = 0;
int ret;
if (type == YESNO_DIALOG) {
b1 = GNOME_STOCK_BUTTON_YES;
b2 = GNOME_STOCK_BUTTON_NO;
b3 = GNOME_STOCK_BUTTON_HELP;
help_button = 2;
} else /* type == OK_DIALOG */ {
b1 = GNOME_STOCK_BUTTON_OK;
b2 = GNOME_STOCK_BUTTON_HELP;
help_button = 1;
b3 = NULL;
}
box = gnome_message_box_new (msg,
warning ?
GNOME_MESSAGE_BOX_WARNING :
GNOME_MESSAGE_BOX_ERROR,
b1, b2, b3, NULL);
gnome_dialog_set_close (GNOME_DIALOG (box), FALSE);
while ((ret = gnome_dialog_run (GNOME_DIALOG (box))) == help_button) {
GnomeHelpMenuEntry ref
= {"gnome-exe-handler", "index.html"};
gnome_help_display (NULL, &ref);
}
gnome_dialog_close (GNOME_DIALOG (box));
return ret;
}
static void
error (const char *msg)
{
message (msg, OK_DIALOG, ERROR_DIALOG);
exit (1);
}
static void
execute (const char *file)
{
char *msg = g_strdup_printf (
_("Executing arbitrary programs that you downloaded from the network "
"might be dangerous.\n\nAre you sure you want to run `%s'?"), file);
struct stat s;
switch (message (msg, YESNO_DIALOG, WARNING_DIALOG)){
case YES_BUTTON:
if (stat (file, &s) == -1){
error (_("Could not access file permissions"));
}
if (chmod (file, s.st_mode | 00100) == -1){
msg = g_strdup_printf (
_("Could not execute the file `%s' due to a permission problem"),
file);
error (msg);
}
{
char *argv [2];
argv [0] = (char *)file;
argv [1] = NULL;
execv (file, argv);
}
msg = g_strdup_printf (_("Failure at executing `%s'"), file);
error (msg);
case NO_BUTTON:
case WINDOW_CLOSE:
default:
exit (0);
}
}
static void
launch (const char *file)
{
char buffer [64];
int n;
int fd = open (file, O_RDONLY);
if (fd == -1){
char *msg = g_strdup_printf (
_("It was not possible to open the file `%s'"),
file);
error (msg);
}
n = read (fd, &buffer, sizeof (buffer));
if (n == 0){
char *msg = g_strdup_printf (_("The file `%s' is empty"), file);
error (msg);
}
if (n < 0){
char *msg = g_strdup_printf (_("There was an error. `%s' is empty"), file);
error (msg);
}
if (buffer [0] == 0x7f &&
buffer [1] == 'E' &&
buffer [2] == 'L' &&
buffer [3] == 'F'){
unsigned char processor;
/* We got an ELF file, check to see what kind it is */
switch (buffer [16]){
case 1:
case 0:
error (_("This is a library and can not be executed"));
case 2:
break;
case 4:
error (_("The file is a core file and can not be executed"));
default:
error (_("This is an unknown kind of executable"));
}
/*
* This handles executables
*/
processor = buffer [18];
if (
#if defined(__i386__)
(processor == 3)
#elif defined(sparc) || defined(__sparc__) || defined(__sparcv9__)
(processor == 2) || (processor == 18) || (processor == 43)
#elif defined(parisc) || defined (__parisc__)
(processor == 15)
#elif defined(ppc) || defined(__ppc__)
(processor == 20)
#elif defined(__alpha__)
(processor == 41) || (processor == 0x9026)
#elif defined(__superh__)
(processor == 42)
#elif defined(__ia64__)
(processor == 50)
#else
/* On other platforms just assume we're fine */
TRUE
#endif
) {
execute (file);
} else {
error (_("The executable is for a different platform and can not be executed on this system"));
}
}
error (_("This is an unknown kind of executable"));
}
int
main (int argc, char *argv [])
{
poptContext ctx;
const char **files;
/* Initialize the i18n stuff */
bindtextdomain (PACKAGE, GNOMELOCALEDIR);
textdomain (PACKAGE);
gnome_init_with_popt_table ("gnome-exe-handler", VERSION, argc, argv, NULL, 0, &ctx);
files = poptGetArgs (ctx);
while (files && *files){
launch (*files);
files++;
}
return 0;
}
|