GophHub - kevinboone/epub2txt2/src/util.c


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.