diff options
Diffstat (limited to 'libtecla-1.4.1/pathutil.c')
-rw-r--r-- | libtecla-1.4.1/pathutil.c | 532 |
1 files changed, 0 insertions, 532 deletions
diff --git a/libtecla-1.4.1/pathutil.c b/libtecla-1.4.1/pathutil.c deleted file mode 100644 index 015504b..0000000 --- a/libtecla-1.4.1/pathutil.c +++ /dev/null @@ -1,532 +0,0 @@ -/* - * Copyright (c) 2000, 2001 by Martin C. Shepherd. - * - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons - * to whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT - * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL - * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING - * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder - * shall not be used in advertising or otherwise to promote the sale, use - * or other dealings in this Software without prior written authorization - * of the copyright holder. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <ctype.h> - -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include "pathutil.h" - -/*....................................................................... - * Create a new PathName object. - * - * Output: - * return PathName * The new object, or NULL on error. - */ -PathName *_new_PathName(void) -{ - PathName *path; /* The object to be returned */ -/* - * Allocate the container. - */ - path = (PathName *)malloc(sizeof(PathName)); - if(!path) { - fprintf(stderr, "_new_PathName: Insufficient memory.\n"); - return NULL; - }; -/* - * Before attempting any operation that might fail, initialize the - * container at least up to the point at which it can safely be passed - * to _del_PathName(). - */ - path->name = NULL; - path->dim = 0; -/* - * Figure out the maximum length of an expanded pathname. - */ - path->dim = _pu_pathname_dim(); - if(path->dim == 0) - return _del_PathName(path); -/* - * Allocate the pathname buffer. - */ - path->name = (char *)malloc(path->dim * sizeof(char)); - if(!path->name) { - fprintf(stderr, - "_new_PathName: Insufficient memory to allocate pathname buffer.\n"); - return _del_PathName(path); - }; - return path; -} - -/*....................................................................... - * Delete a PathName object. - * - * Input: - * path PathName * The object to be deleted. - * Output: - * return PathName * The deleted object (always NULL). - */ -PathName *_del_PathName(PathName *path) -{ - if(path) { - if(path->name) - free(path->name); - free(path); - }; - return NULL; -} - -/*....................................................................... - * Return the pathname to a zero-length string. - * - * Input: - * path PathName * The pathname container. - * Output: - * return char * The cleared pathname buffer, or NULL on error. - */ -char *_pn_clear_path(PathName *path) -{ -/* - * Check the arguments. - */ - if(!path) { - fprintf(stderr, "_pn_clear_path: NULL argument.\n"); - return NULL; - }; - path->name[0] = '\0'; - return path->name; -} - -/*....................................................................... - * Append a string to a pathname, increasing the size of the pathname - * buffer if needed. - * - * Input: - * path PathName * The pathname container. - * string const char * The string to be appended to the pathname. - * Note that regardless of the slen argument, - * this should be a '\0' terminated string. - * slen int The maximum number of characters to append - * from string[], or -1 to append the whole - * string. - * remove_escapes int If true, remove the backslashes that escape - * spaces, tabs, backslashes etc.. - * Output: - * return char * The pathname string path->name[], which may - * have been reallocated, or NULL if there was - * insufficient memory to extend the pathname. - */ -char *_pn_append_to_path(PathName *path, const char *string, int slen, - int remove_escapes) -{ - int pathlen; /* The length of the pathname */ - int i; -/* - * Check the arguments. - */ - if(!path || !string) { - fprintf(stderr, "_pn_append_to_path: NULL argument(s).\n"); - return NULL; - }; -/* - * Get the current length of the pathname. - */ - pathlen = strlen(path->name); -/* - * How many characters should be appended? - */ - if(slen < 0 || slen > strlen(string)) - slen = strlen(string); -/* - * Resize the pathname if needed. - */ - if(!_pn_resize_path(path, pathlen + slen)) - return NULL; -/* - * Append the string to the output pathname, removing any escape - * characters found therein. - */ - if(remove_escapes) { - int is_escape = 0; - for(i=0; i<slen; i++) { - is_escape = !is_escape && string[i] == '\\'; - if(!is_escape) - path->name[pathlen++] = string[i]; - }; -/* - * Terminate the string. - */ - path->name[pathlen] = '\0'; - } else { -/* - * Append the string directly to the pathname. - */ - memcpy(path->name + pathlen, string, slen); - path->name[pathlen + slen] = '\0'; - }; - return path->name; -} - -/*....................................................................... - * Prepend a string to a pathname, increasing the size of the pathname - * buffer if needed. - * - * Input: - * path PathName * The pathname container. - * string const char * The string to be prepended to the pathname. - * Note that regardless of the slen argument, - * this should be a '\0' terminated string. - * slen int The maximum number of characters to prepend - * from string[], or -1 to append the whole - * string. - * remove_escapes int If true, remove the backslashes that escape - * spaces, tabs, backslashes etc.. - * Output: - * return char * The pathname string path->name[], which may - * have been reallocated, or NULL if there was - * insufficient memory to extend the pathname. - */ -char *_pn_prepend_to_path(PathName *path, const char *string, int slen, - int remove_escapes) -{ - int pathlen; /* The length of the pathname */ - int shift; /* The number of characters to shift the suffix by */ - int i,j; -/* - * Check the arguments. - */ - if(!path || !string) { - fprintf(stderr, "_pn_prepend_to_path: NULL argument(s).\n"); - return NULL; - }; -/* - * Get the current length of the pathname. - */ - pathlen = strlen(path->name); -/* - * How many characters should be appended? - */ - if(slen < 0 || slen > strlen(string)) - slen = strlen(string); -/* - * Work out how far we need to shift the original path string to make - * way for the new prefix. When removing escape characters, we need - * final length of the new prefix, after unescaped backslashes have - * been removed. - */ - if(remove_escapes) { - int is_escape = 0; - for(shift=0,i=0; i<slen; i++) { - is_escape = !is_escape && string[i] == '\\'; - if(!is_escape) - shift++; - }; - } else { - shift = slen; - }; -/* - * Resize the pathname if needed. - */ - if(!_pn_resize_path(path, pathlen + shift)) - return NULL; -/* - * Make room for the prefix at the beginning of the string. - */ - memmove(path->name + shift, path->name, pathlen+1); -/* - * Copy the new prefix into the vacated space at the beginning of the - * output pathname, removing any escape characters if needed. - */ - if(remove_escapes) { - int is_escape = 0; - for(i=j=0; i<slen; i++) { - is_escape = !is_escape && string[i] == '\\'; - if(!is_escape) - path->name[j++] = string[i]; - }; - } else { - memcpy(path->name, string, slen); - }; - return path->name; -} - -/*....................................................................... - * If needed reallocate a given pathname buffer to allow a string of - * a given length to be stored in it. - * - * Input: - * path PathName * The pathname container object. - * length size_t The required length of the pathname buffer, - * not including the terminating '\0'. - * Output: - * return char * The pathname buffer, or NULL if there was - * insufficient memory (this isn't reported - * to stderr). - */ -char *_pn_resize_path(PathName *path, size_t length) -{ -/* - * Check the arguments. - */ - if(!path) { - fprintf(stderr, "_pn_resize_path: NULL argument(s).\n"); - return NULL; - }; -/* - * If the pathname buffer isn't large enough to accomodate a string - * of the specified length, attempt to reallocate it with the new - * size, plus space for a terminating '\0'. Also add a bit of - * head room to prevent too many reallocations if the initial length - * turned out to be very optimistic. - */ - if(length + 1 > path->dim) { - size_t dim = length + 1 + PN_PATHNAME_INC; - char *name = (char *) realloc(path->name, dim); - if(!name) - return NULL; - path->name = name; - path->dim = dim; - }; - return path->name; -} - -/*....................................................................... - * Estimate the largest amount of space needed to store a pathname. - * - * Output: - * return size_t The number of bytes needed, including space for the - * terminating '\0'. - */ -size_t _pu_pathname_dim(void) -{ - int maxlen; /* The return value excluding space for the '\0' */ -/* - * If the POSIX PATH_MAX macro is defined in limits.h, use it. - */ -#ifdef PATH_MAX - maxlen = PATH_MAX; -/* - * If we have pathconf, use it. - */ -#elif defined(_PC_PATH_MAX) - errno = 0; - maxlen = pathconf(FS_ROOT_DIR, _PC_PATH_MAX); - if(maxlen <= 0 || errno) - maxlen = MAX_PATHLEN_FALLBACK; -/* - * None of the above approaches worked, so substitute our fallback - * guess. - */ -#else - maxlen = MAX_PATHLEN_FALLBACK; -#endif -/* - * Return the amount of space needed to accomodate a pathname plus - * a terminating '\0'. - */ - return maxlen + 1; -} - -/*....................................................................... - * Return non-zero if the specified path name refers to a directory. - * - * Input: - * pathname const char * The path to test. - * Output: - * return int 0 - Not a directory. - * 1 - pathname[] refers to a directory. - */ -int _pu_path_is_dir(const char *pathname) -{ - struct stat statbuf; /* The file-statistics return buffer */ -/* - * Look up the file attributes. - */ - if(stat(pathname, &statbuf) < 0) - return 0; -/* - * Is the file a directory? - */ - return S_ISDIR(statbuf.st_mode) != 0; -} - -/*....................................................................... - * Return non-zero if the specified path name refers to a regular file. - * - * Input: - * pathname const char * The path to test. - * Output: - * return int 0 - Not a regular file. - * 1 - pathname[] refers to a regular file. - */ -int _pu_path_is_file(const char *pathname) -{ - struct stat statbuf; /* The file-statistics return buffer */ -/* - * Look up the file attributes. - */ - if(stat(pathname, &statbuf) < 0) - return 0; -/* - * Is the file a regular file? - */ - return S_ISREG(statbuf.st_mode) != 0; -} - -/*....................................................................... - * Return non-zero if the specified path name refers to an executable. - * - * Input: - * pathname const char * The path to test. - * Output: - * return int 0 - Not an executable file. - * 1 - pathname[] refers to an executable file. - */ -int _pu_path_is_exe(const char *pathname) -{ - struct stat statbuf; /* The file-statistics return buffer */ -/* - * Look up the file attributes. - */ - if(stat(pathname, &statbuf) < 0) - return 0; -/* - * Is the file a regular file which is executable by the current user. - */ - return S_ISREG(statbuf.st_mode) != 0 && - (statbuf.st_mode & (S_IXOTH | S_IXGRP | S_IXUSR)) && - access(pathname, X_OK) == 0; -} - -/*....................................................................... - * Search backwards for the potential start of a filename. This - * looks backwards from the specified index in a given string, - * stopping at the first unescaped space or the start of the line. - * - * Input: - * string const char * The string to search backwards in. - * back_from int The index of the first character in string[] - * that follows the pathname. - * Output: - * return char * The pointer to the first character of - * the potential pathname, or NULL on error. - */ -char *_pu_start_of_path(const char *string, int back_from) -{ - int i, j; -/* - * Check the arguments. - */ - if(!string || back_from < 0) { - fprintf(stderr, "_pu_start_path: Invalid argument(s).\n"); - return NULL; - }; -/* - * Search backwards from the specified index. - */ - for(i=back_from-1; i>=0; i--) { - int c = string[i]; -/* - * Stop on unescaped spaces. - */ - if(isspace((int)(unsigned char)c)) { -/* - * The space can't be escaped if we are at the start of the line. - */ - if(i==0) - break; -/* - * Find the extent of the escape characters which precedes the space. - */ - for(j=i-1; j>=0 && string[j]=='\\'; j--) - ; -/* - * If there isn't an odd number of escape characters before the space, - * then the space isn't escaped. - */ - if((i - 1 - j) % 2 == 0) - break; - }; - }; - return (char *)string + i + 1; -} - -/*....................................................................... - * Find the length of a potential filename starting from a given - * point. This looks forwards from the specified index in a given string, - * stopping at the first unescaped space or the end of the line. - * - * Input: - * string const char * The string to search backwards in. - * start_from int The index of the first character of the pathname - * in string[]. - * Output: - * return char * The pointer to the character that follows - * the potential pathname, or NULL on error. - */ -char *_pu_end_of_path(const char *string, int start_from) -{ - int c; /* The character being examined */ - int escaped = 0; /* True when the next character is escaped */ - int i; -/* - * Check the arguments. - */ - if(!string || start_from < 0) { - fprintf(stderr, "_pu_end_path: Invalid argument(s).\n"); - return NULL; - }; -/* - * Search forwards from the specified index. - */ - for(i=start_from; (c=string[i]) != '\0'; i++) { - if(escaped) { - escaped = 0; - } else if(isspace(c)) { - break; - } else if(c == '\\') { - escaped = 1; - }; - }; - return (char *)string + i; -} - -/*....................................................................... - * Return non-zero if the specified path name refers to an existing file. - * - * Input: - * pathname const char * The path to test. - * Output: - * return int 0 - The file doesn't exist. - * 1 - The file does exist. - */ -int _pu_file_exists(const char *pathname) -{ - struct stat statbuf; - return stat(pathname, &statbuf) == 0; -} |