Raw File
1 /*============================================================================
2 epub2txt v2
3 util.c
4 Copyright (c)2022 Marco Bonelli, Kevin Boone, GPL v3.0
5 ============================================================================*/
6
7 #include <errno.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <stdlib.h>
11 #include <ctype.h>
12 #include <signal.h>
13 #include <sys/wait.h>
14 #include "util.h"
15 #include "log.h"
16
17 /*==========================================================================
18 run_command
19 Run an helper command through fork + execvp, wait for it to finish and return
20 its status. Log execvp errors, and abort execution if abort_on_error is TRUE.
21 (Marco Bonelli)
22 *==========================================================================*/
23 int run_command (const char *const argv[], BOOL abort_on_error)
24 {
25 int status;
26 int pid = fork();
27
28 if (pid == 0)
29 {
30 execvp(argv[0], (char **const)argv);
31 log_error ("Can't execute command \"%s\": %s", argv[0], strerror (errno));
32
33 if (abort_on_error)
34 {
35 kill (getppid(), SIGTERM);
36 _exit (-1);
37 }
38
39 _exit (0);
40 }
41
42 waitpid (pid, &status, 0);
43 return status;
44 }
45
46 /*==========================================================================
47 Decode %xx in URL-type strings. The caller must free the resulting
48 string, which will be no longer than the input.
49 (Kevin Boone)
50 *==========================================================================*/
51 char *decode_url (const char *url)
52 {
53 char *ret = malloc (strlen (url) + 2);
54
55 int len = 0;
56 for (; *url; len++)
57 {
58 if (*url == '%' && url[1] && url[2] &&
59 isxdigit(url[1]) && isxdigit(url[2]))
60 {
61 char url1 = url[1];
62 char url2 = url[2];
63 url1 -= url1 <= '9' ? '0' : (url1 <= 'F' ? 'A' : 'a')-10;
64 url2 -= url2 <= '9' ? '0' : (url2 <= 'F' ? 'A' : 'a')-10;
65 ret[len] = 16 * url1 + url2;
66 url += 3;
67 continue;
68 }
69 else if (*url == '+')
70 {
71 /* I have not tested this piece of the function, because I have not
72 seen any instances of '+' (meaning space) in a spine href */
73 url += 1;
74 ret[len] = ' ';
75 }
76 ret[len] = *url++;
77 }
78 ret[len] = '\0';
79
80 return ret;
81 }
82
83 /*==========================================================================
84 is_subpath
85 Determine whether path is a subpath of root; or in other words, whether path
86 points to a file/directory inside root. Both root and path are assumed to be
87 in canonical form, therefore the caller should make sure of this using e.g.
88 canonicalize_file_name(path) or realpath(path, NULL).
89 (Marco Bonelli)
90 *==========================================================================*/
91 BOOL is_subpath (const char *root, const char *path)
92 {
93 size_t root_len = strlen (root);
94 size_t path_len = strlen (path);
95 return path_len > root_len && !strncmp (root, path, root_len)
96 && path[root_len] == '/';
97 }
98
Generated by GNU Enscript 1.6.6, and GophHub 1.3.