X-Git-Url: https://git.librecmc.org/?p=oweals%2Fopkg-lede.git;a=blobdiff_plain;f=libopkg%2Ffile_util.c;h=c54903c30b66907d126cd6ebb5ed0b58759e0f34;hp=41762575e56d9e94960cc5079590bec0775dd2b0;hb=733eb7729491810c346bbbecd31051ecc118fd82;hpb=29b3b9d76a8d6b9af6d6465a9f501c2e5066bea0 diff --git a/libopkg/file_util.c b/libopkg/file_util.c index 4176257..c54903c 100644 --- a/libopkg/file_util.c +++ b/libopkg/file_util.c @@ -1,7 +1,8 @@ /* file_util.c - convenience routines for common stat operations - Carl D. Worth + Copyright (C) 2009 Ubiq Technologies + Carl D. Worth Copyright (C) 2001 University of Southern California This program is free software; you can redistribute it and/or @@ -15,44 +16,45 @@ General Public License for more details. */ -#include "includes.h" +#include "config.h" + +#include #include #include +#include +#include #include "sprintf_alloc.h" #include "file_util.h" +#ifdef HAVE_MD5 #include "md5.h" +#endif #include "libbb/libbb.h" -#undef strlen #if defined HAVE_SHA256 #include "sha256.h" #endif -int file_exists(const char *file_name) +int +file_exists(const char *file_name) { - int err; - struct stat stat_buf; + struct stat st; + + if (stat(file_name, &st) == -1) + return 0; - err = stat(file_name, &stat_buf); - if (err == 0) { return 1; - } else { - return 0; - } } -int file_is_dir(const char *file_name) +int +file_is_dir(const char *file_name) { - int err; - struct stat stat_buf; + struct stat st; - err = stat(file_name, &stat_buf); - if (err) { - return 0; - } + if (stat(file_name, &st) == -1) + return 0; - return S_ISDIR(stat_buf.st_mode); + return S_ISDIR(st.st_mode); } /* read a single line from a file, stopping at a newline or EOF. @@ -62,74 +64,80 @@ int file_is_dir(const char *file_name) Return value is NULL if the file is at EOF when called. */ -#define FILE_READ_LINE_BUF_SIZE 1024 -char *file_read_line_alloc(FILE *file) +char * +file_read_line_alloc(FILE *fp) { - char buf[FILE_READ_LINE_BUF_SIZE]; - int buf_len; - char *line = NULL; - int line_size = 0; - - memset(buf, 0, FILE_READ_LINE_BUF_SIZE); - while (fgets(buf, FILE_READ_LINE_BUF_SIZE, file)) { - buf_len = strlen(buf); - if (line) { - line_size += buf_len; - line = realloc(line, line_size); - if (line == NULL) { - fprintf(stderr, "%s: out of memory\n", __FUNCTION__); - break; - } - strcat(line, buf); - } else { - line_size = buf_len + 1; - line = strdup(buf); - } - if (buf[buf_len - 1] == '\n') { - break; + char buf[BUFSIZ]; + unsigned int buf_len; + char *line = NULL; + unsigned int line_size = 0; + int got_nl = 0; + + buf[0] = '\0'; + + while (fgets(buf, BUFSIZ, fp)) { + buf_len = strlen(buf); + if (buf[buf_len - 1] == '\n') { + buf_len--; + buf[buf_len] = '\0'; + got_nl = 1; + } + if (line) { + line_size += buf_len; + line = xrealloc(line, line_size+1); + strncat(line, buf, line_size); + } else { + line_size = buf_len + 1; + line = xstrdup(buf); + } + if (got_nl) + break; } - } - return line; + return line; } -int file_move(const char *src, const char *dest) +int +file_move(const char *src, const char *dest) { - int err; - - err = rename(src, dest); - - if (err && errno == EXDEV) { - err = file_copy(src, dest); - unlink(src); - } else if (err) { - fprintf(stderr, "%s: ERROR: failed to rename %s to %s: %s\n", - __FUNCTION__, src, dest, strerror(errno)); - } + int err; + + err = rename(src, dest); + if (err == -1) { + if (errno == EXDEV) { + /* src & dest live on different file systems */ + err = file_copy(src, dest); + if (err == 0) + unlink(src); + } else { + opkg_perror(ERROR, "Failed to rename %s to %s", + src, dest); + } + } - return err; + return err; } -/* I put these here to keep libbb dependencies from creeping all over - the opkg code */ -int file_copy(const char *src, const char *dest) +int +file_copy(const char *src, const char *dest) { - int err; + int err; - err = copy_file(src, dest, FILEUTILS_FORCE | FILEUTILS_PRESERVE_STATUS); - if (err) { - fprintf(stderr, "%s: ERROR: failed to copy %s to %s\n", - __FUNCTION__, src, dest); - } + err = copy_file(src, dest, FILEUTILS_FORCE | FILEUTILS_PRESERVE_STATUS); + if (err) + opkg_msg(ERROR, "Failed to copy file %s to %s.\n", + src, dest); - return err; + return err; } -int file_mkdir_hier(const char *path, long mode) +int +file_mkdir_hier(const char *path, long mode) { - return make_directory(path, mode, FILEUTILS_RECUR); + return make_directory(path, mode, FILEUTILS_RECUR); } +#ifdef HAVE_MD5 char *file_md5sum_alloc(const char *file_name) { static const int md5sum_bin_len = 16; @@ -147,24 +155,21 @@ char *file_md5sum_alloc(const char *file_name) char *md5sum_hex; unsigned char md5sum_bin[md5sum_bin_len]; - md5sum_hex = calloc(1, md5sum_hex_len + 1); - if (md5sum_hex == NULL) { - fprintf(stderr, "%s: out of memory\n", __FUNCTION__); - return strdup(""); - } + md5sum_hex = xcalloc(1, md5sum_hex_len + 1); file = fopen(file_name, "r"); if (file == NULL) { - fprintf(stderr, "%s: Failed to open file %s: %s\n", - __FUNCTION__, file_name, strerror(errno)); - return strdup(""); + opkg_perror(ERROR, "Failed to open file %s", file_name); + free(md5sum_hex); + return NULL; } err = md5_stream(file, md5sum_bin); if (err) { - fprintf(stderr, "%s: ERROR computing md5sum for %s: %s\n", - __FUNCTION__, file_name, strerror(err)); - return strdup(""); + opkg_msg(ERROR, "Could't compute md5sum for %s.\n", file_name); + fclose(file); + free(md5sum_hex); + return NULL; } fclose(file); @@ -173,11 +178,12 @@ char *file_md5sum_alloc(const char *file_name) md5sum_hex[i*2] = bin2hex[md5sum_bin[i] >> 4]; md5sum_hex[i*2+1] = bin2hex[md5sum_bin[i] & 0xf]; } - + md5sum_hex[md5sum_hex_len] = '\0'; - + return md5sum_hex; } +#endif #ifdef HAVE_SHA256 char *file_sha256sum_alloc(const char *file_name) @@ -197,24 +203,21 @@ char *file_sha256sum_alloc(const char *file_name) char *sha256sum_hex; unsigned char sha256sum_bin[sha256sum_bin_len]; - sha256sum_hex = calloc(1, sha256sum_hex_len + 1); - if (sha256sum_hex == NULL) { - fprintf(stderr, "%s: out of memory\n", __FUNCTION__); - return strdup(""); - } + sha256sum_hex = xcalloc(1, sha256sum_hex_len + 1); file = fopen(file_name, "r"); if (file == NULL) { - fprintf(stderr, "%s: Failed to open file %s: %s\n", - __FUNCTION__, file_name, strerror(errno)); - return strdup(""); + opkg_perror(ERROR, "Failed to open file %s", file_name); + free(sha256sum_hex); + return NULL; } err = sha256_stream(file, sha256sum_bin); if (err) { - fprintf(stderr, "%s: ERROR computing sha256sum for %s: %s\n", - __FUNCTION__, file_name, strerror(err)); - return strdup(""); + opkg_msg(ERROR, "Could't compute sha256sum for %s.\n", file_name); + fclose(file); + free(sha256sum_hex); + return NULL; } fclose(file); @@ -223,10 +226,94 @@ char *file_sha256sum_alloc(const char *file_name) sha256sum_hex[i*2] = bin2hex[sha256sum_bin[i] >> 4]; sha256sum_hex[i*2+1] = bin2hex[sha256sum_bin[i] & 0xf]; } - + sha256sum_hex[sha256sum_hex_len] = '\0'; - + return sha256sum_hex; } #endif + + +int +rm_r(const char *path) +{ + int ret = 0; + DIR *dir; + struct dirent *dent; + + if (path == NULL) { + opkg_perror(ERROR, "Missing directory parameter"); + return -1; + } + + dir = opendir(path); + if (dir == NULL) { + opkg_perror(ERROR, "Failed to open dir %s", path); + return -1; + } + + if (fchdir(dirfd(dir)) == -1) { + opkg_perror(ERROR, "Failed to change to dir %s", path); + closedir(dir); + return -1; + } + + while (1) { + errno = 0; + if ((dent = readdir(dir)) == NULL) { + if (errno) { + opkg_perror(ERROR, "Failed to read dir %s", + path); + ret = -1; + } + break; + } + + if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) + continue; + +#ifdef _BSD_SOURCE + if (dent->d_type == DT_DIR) { + if ((ret = rm_r(dent->d_name)) == -1) + break; + continue; + } else if (dent->d_type == DT_UNKNOWN) +#endif + { + struct stat st; + if ((ret = lstat(dent->d_name, &st)) == -1) { + opkg_perror(ERROR, "Failed to lstat %s", + dent->d_name); + break; + } + if (S_ISDIR(st.st_mode)) { + if ((ret = rm_r(dent->d_name)) == -1) + break; + continue; + } + } + + if ((ret = unlink(dent->d_name)) == -1) { + opkg_perror(ERROR, "Failed to unlink %s", dent->d_name); + break; + } + } + + if (chdir("..") == -1) { + ret = -1; + opkg_perror(ERROR, "Failed to change to dir %s/..", path); + } + + if (rmdir(path) == -1 ) { + ret = -1; + opkg_perror(ERROR, "Failed to remove dir %s", path); + } + + if (closedir(dir) == -1) { + ret = -1; + opkg_perror(ERROR, "Failed to close dir %s", path); + } + + return ret; +}