nsxiv00d4b0f
Use "/bin/sh -c" for external commands
+44 −58
3 files changed
- M Makefile +1 −1
- M commands.h +6 −22
- M main.c +37 −35
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | all: sxiv | |
| 2 | 2 | ||
| 3 | − | VERSION=git-20110301 | |
| 3 | + | VERSION=git-20110303 | |
| 4 | 4 | ||
| 5 | 5 | CC?=gcc | |
| 6 | 6 | PREFIX?=/usr/local | |
| @@ -1,29 +1,13 @@ | |||
| 1 | − | #define FILENAME (const char*) 0x1 | |
| 2 | − | ||
| 3 | 1 | typedef struct { | |
| 4 | 2 | KeySym ksym; | |
| 5 | − | const char **cmdline; | |
| 6 | 3 | Bool reload; | |
| 4 | + | const char *cmdline; | |
| 7 | 5 | } command_t; | |
| 8 | 6 | ||
| 9 | − | static const char *cmdline_1[] = { | |
| 10 | − | "jpegtran", "-rotate", "270", "-copy", "all", "-outfile", FILENAME, | |
| 11 | − | FILENAME, NULL }; | |
| 12 | − | ||
| 13 | − | static const char *cmdline_2[] = { | |
| 14 | − | "jpegtran", "-rotate", "90", "-copy", "all", "-outfile", FILENAME, | |
| 15 | − | FILENAME, NULL }; | |
| 16 | − | ||
| 17 | − | static const char *cmdline_3[] = { | |
| 18 | − | "mogrify", "-rotate", "-90", FILENAME, NULL }; | |
| 19 | − | ||
| 20 | − | static const char *cmdline_4[] = { | |
| 21 | − | "mogrify", "-rotate", "+90", FILENAME, NULL }; | |
| 22 | − | ||
| 23 | 7 | static command_t commands[] = { | |
| 24 | − | /* key command-line reload? */ | |
| 25 | − | { XK_a, cmdline_1, True }, | |
| 26 | − | { XK_s, cmdline_2, True }, | |
| 27 | − | { XK_A, cmdline_3, True }, | |
| 28 | − | { XK_S, cmdline_4, True }, | |
| 8 | + | /* key reload? command, '#' is replaced by filename */ | |
| 9 | + | { XK_a, True, "jpegtran -rotate 270 -copy all -outfile # #" }, | |
| 10 | + | { XK_s, True, "jpegtran -rotate 90 -copy all -outfile # #" }, | |
| 11 | + | { XK_A, True, "mogrify -rotate -90 #" }, | |
| 12 | + | { XK_S, True, "mogrify -rotate +90 #" } | |
| 29 | 13 | }; | |
| @@ -273,57 +273,59 @@ void read_dir_rec(const char *dirname) { | |||
| 273 | 273 | free(dirnames); | |
| 274 | 274 | } | |
| 275 | 275 | ||
| 276 | − | int run_command(const char **cmdline, Bool reload) { | |
| 277 | − | int argc, i; | |
| 278 | − | const char **argv; | |
| 276 | + | int run_command(const char *cline, Bool reload) { | |
| 277 | + | int fncnt, fnlen; | |
| 278 | + | char *cn, *cmdline; | |
| 279 | + | const char *co, *fname; | |
| 279 | 280 | pid_t pid; | |
| 280 | − | int error, ret, status; | |
| 281 | + | int ret, status; | |
| 281 | 282 | ||
| 282 | − | if (!cmdline) | |
| 283 | + | if (!cline || !*cline) | |
| 283 | 284 | return 0; | |
| 284 | 285 | ||
| 285 | − | argc = 1; | |
| 286 | − | while (cmdline[argc-1]) | |
| 287 | − | ++argc; | |
| 286 | + | fncnt = 0; | |
| 287 | + | co = cline - 1; | |
| 288 | + | while ((co = strchr(co + 1, '#'))) | |
| 289 | + | ++fncnt; | |
| 288 | 290 | ||
| 289 | − | if (argc < 2) | |
| 291 | + | if (!fncnt) | |
| 290 | 292 | return 0; | |
| 291 | 293 | ||
| 292 | − | argv = (const char**) s_malloc(argc * sizeof(const char*)); | |
| 293 | − | error = ret = 0; | |
| 294 | − | ||
| 295 | − | for (i = 0; i < argc; ++i) { | |
| 296 | − | if (cmdline[i] != FILENAME) | |
| 297 | − | argv[i] = cmdline[i]; | |
| 298 | − | else | |
| 299 | − | argv[i] = filenames[mode == MODE_NORMAL ? fileidx : tns.sel]; | |
| 294 | + | ret = 0; | |
| 295 | + | fname = filenames[mode == MODE_NORMAL ? fileidx : tns.sel]; | |
| 296 | + | fnlen = strlen(fname); | |
| 297 | + | cn = cmdline = (char*) s_malloc((strlen(cline) + fncnt * (fnlen + 2)) * | |
| 298 | + | sizeof(char)); | |
| 299 | + | ||
| 300 | + | /* replace all '#' with filename */ | |
| 301 | + | for (co = cline; *co; ++co) { | |
| 302 | + | if (*co == '#') { | |
| 303 | + | *cn++ = '"'; | |
| 304 | + | strcpy(cn, fname); | |
| 305 | + | cn += fnlen; | |
| 306 | + | *cn++ = '"'; | |
| 307 | + | } else { | |
| 308 | + | *cn++ = *co; | |
| 309 | + | } | |
| 300 | 310 | } | |
| 311 | + | *cn = '\0'; | |
| 301 | 312 | ||
| 302 | 313 | if ((pid = fork()) == 0) { | |
| 303 | − | execvp(argv[0], (char **const) argv); | |
| 304 | − | warn("could not exec %s", argv[0]); | |
| 314 | + | execlp("/bin/sh", "/bin/sh", "-c", cmdline, NULL); | |
| 315 | + | warn("could not exec: /bin/sh"); | |
| 305 | 316 | exit(1); | |
| 306 | − | } else if (pid < 0 && !options->quiet) { | |
| 307 | − | warn("could not fork. command line was:"); | |
| 308 | − | error = 1; | |
| 317 | + | } else if (pid < 0) { | |
| 318 | + | warn("could not fork. command line was: %s", cmdline); | |
| 309 | 319 | } else if (reload) { | |
| 310 | 320 | waitpid(pid, &status, 0); | |
| 311 | − | if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { | |
| 321 | + | if (WIFEXITED(status) && WEXITSTATUS(status) == 0) | |
| 312 | 322 | ret = 1; | |
| 313 | − | } else if (!options->quiet) { | |
| 314 | − | warn("child exited with non-zero return value: %d. command line was:", | |
| 315 | − | WEXITSTATUS(status)); | |
| 316 | − | error = 1; | |
| 317 | − | } | |
| 323 | + | else | |
| 324 | + | warn("child exited with non-zero return value: %d. command line was: %s", | |
| 325 | + | WEXITSTATUS(status), cmdline); | |
| 318 | 326 | } | |
| 319 | 327 | ||
| 320 | − | if (error) { | |
| 321 | − | for (i = 0; i < argc && argv[i]; ++i) | |
| 322 | − | fprintf(stderr, "%s%s", i > 0 ? " " : "", argv[i]); | |
| 323 | − | fprintf(stderr, "\n"); | |
| 324 | − | } | |
| 325 | − | ||
| 326 | − | free(argv); | |
| 328 | + | free(cmdline); | |
| 327 | 329 | return ret; | |
| 328 | 330 | } | |
| 329 | 331 | ||