/* * util.c * * Copyright (c) 2002-2004 by Judd Vinet * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "util.h" /* borrowed and modified from Per Liden's pkgutils (http://crux.nu) */ int gzopen_frontend(char *pathname, int oflags, int mode) { char* gzoflags; int fd; gzFile gzf; switch (oflags & O_ACCMODE) { case O_WRONLY: gzoflags = "w"; break; case O_RDONLY: gzoflags = "r"; break; case O_RDWR: default: errno = EINVAL; return -1; } if((fd = open(pathname, oflags, mode)) == -1) { return -1; } if((oflags & O_CREAT) && fchmod(fd, mode)) { return -1; } if(!(gzf = gzdopen(fd, gzoflags))) { errno = ENOMEM; return -1; } return (int)gzf; } int unpack(char *archive, char *prefix) { TAR *tar = NULL; char expath[PATH_MAX]; tartype_t gztype = { (openfunc_t) gzopen_frontend, (closefunc_t)gzclose, (readfunc_t) gzread, (writefunc_t)gzwrite }; /* open the .tar.gz package */ if(tar_open(&tar, archive, &gztype, O_RDONLY, 0, TAR_GNU) == -1) { perror(archive); return(1); } while(!th_read(tar)) { snprintf(expath, PATH_MAX, "%s/%s", prefix, th_get_pathname(tar)); if(tar_extract_file(tar, expath)) { fprintf(stderr, "could not extract %s: %s\n", th_get_pathname(tar), strerror(errno)); } } tar_close(tar); return(0); } int copyfile(char *src, char *dest) { FILE *in, *out; size_t len; char buf[4097]; in = fopen(src, "r"); if(in == NULL) { return(1); } out = fopen(dest, "w"); if(out == NULL) { return(1); } while((len = fread(buf, 1, 4096, in))) { fwrite(buf, 1, len, out); } fclose(in); fclose(out); return(0); } /* does the same thing as 'mkdir -p' */ int makepath(char *path) { char *orig, *str, *ptr; char full[PATH_MAX] = ""; mode_t oldmask; oldmask = umask(0000); orig = strdup(path); str = orig; while((ptr = strsep(&str, "/"))) { if(strlen(ptr)) { struct stat buf; strcat(full, "/"); strcat(full, ptr); if(stat(full, &buf)) { if(mkdir(full, 0755)) { free(orig); return(1); } } } } free(orig); umask(oldmask); return(0); } /* does the same thing as 'rm -rf' */ int rmrf(char *path) { int errflag = 0; struct dirent *dp; DIR *dirp; char name[PATH_MAX]; extern int errno; if(!unlink(path)) { return(0); } else { if(errno == ENOENT) { return(0); } else if(errno == EPERM) { /* fallthrough */ } else if(errno == EISDIR) { /* fallthrough */ } else if(errno == ENOTDIR) { return(1); } else { /* not a directory */ return(1); } if((dirp = opendir(path)) == (DIR *)-1) { return(1); } for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { if(dp->d_ino) { sprintf(name, "%s/%s", path, dp->d_name); if(strcmp(dp->d_name, "..") && strcmp(dp->d_name, ".")) { errflag += rmrf(name); } } } closedir(dirp); if(rmdir(path)) { errflag++; } return(errflag); } return(0); } /* presents a prompt and gets a Y/N answer */ int yesno(char *fmt, ...) { char response[32]; va_list args; va_start(args, fmt); vprintf(fmt, args); va_end(args); fflush(stdout); if(fgets(response, 32, stdin)) { trim(response); if(!strcasecmp(response, "Y") || !strcasecmp(response, "YES") || !strlen(response)) { return(1); } } return(0); } /* output a string, but wrap words properly with a specified indentation */ void indentprint(char *str, int indent) { char *p = str; char *cenv = NULL; int cols = 80; int cidx = indent; cenv = getenv("COLUMNS"); if(cenv) { cols = atoi(cenv); } while(*p) { if(*p == ' ') { char *next = NULL; int len; p++; if(p == NULL || *p == ' ') continue; next = strchr(p, ' '); if(next == NULL) { next = p + strlen(p); } len = next - p; if(len > (cols-cidx-1)) { /* newline */ int i; printf("\n"); for(i = 0; i < indent; i++) { printf(" "); } cidx = indent; } else { printf(" "); cidx++; } } printf("%c", *p); p++; cidx++; } } /* Convert a string to uppercase */ char* strtoupper(char *str) { char *ptr = str; while(*ptr) { (*ptr) = toupper(*ptr); ptr++; } return str; } /* Trim whitespace and newlines from a string */ char* trim(char *str) { char *pch = str; while(isspace(*pch)) { pch++; } if(pch != str) { memmove(str, pch, (strlen(pch) + 1)); } pch = (char*)(str + (strlen(str) - 1)); while(isspace(*pch)) { pch--; } *++pch = '\0'; return str; } /* vim: set ts=2 sw=2 noet: */