pacman/src/util.c

293 lines
5.3 KiB
C
Raw Normal View History

2002-08-09 18:03:48 +00:00
/*
2003-09-03 02:09:29 +00:00
* util.c
2002-08-09 18:03:48 +00:00
*
2004-03-02 04:49:15 +00:00
* Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org>
2002-08-09 18:03:48 +00:00
*
* 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 <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
2003-05-30 19:56:46 +00:00
#include <dirent.h>
#include <zlib.h>
#include <libtar.h>
2002-08-09 18:03:48 +00:00
#include "util.h"
2003-05-30 19:56:46 +00:00
/* borrowed and modified from Per Liden's pkgutils (http://crux.nu) */
int gzopen_frontend(char *pathname, int oflags, int mode)
2002-08-09 18:03:48 +00:00
{
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];
2003-05-30 19:56:46 +00:00
tartype_t gztype = {
(openfunc_t) gzopen_frontend,
(closefunc_t)gzclose,
(readfunc_t) gzread,
(writefunc_t)gzwrite
};
2002-08-09 18:03:48 +00:00
/* 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;
2002-09-16 05:22:13 +00:00
char buf[4097];
2002-08-09 18:03:48 +00:00
in = fopen(src, "r");
if(in == NULL) {
return(1);
}
out = fopen(dest, "w");
if(out == NULL) {
return(1);
}
2002-09-16 05:22:13 +00:00
while((len = fread(buf, 1, 4096, in))) {
2002-08-09 18:03:48 +00:00
fwrite(buf, 1, len, out);
}
fclose(in);
fclose(out);
return(0);
}
2003-09-03 02:09:29 +00:00
/* does the same thing as 'mkdir -p' */
2002-08-09 18:03:48 +00:00
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);
}
2003-09-03 02:09:29 +00:00
/* does the same thing as 'rm -rf' */
2002-08-09 18:03:48 +00:00
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 {
2003-09-03 02:09:29 +00:00
if(errno == ENOENT) {
2002-08-09 18:03:48 +00:00
return(0);
2003-09-03 02:09:29 +00:00
} else if(errno == EPERM) {
2002-08-09 18:03:48 +00:00
/* fallthrough */
2003-09-03 02:09:29 +00:00
} else if(errno == EISDIR) {
2002-08-09 18:03:48 +00:00
/* fallthrough */
2003-09-03 02:09:29 +00:00
} else if(errno == ENOTDIR) {
2002-08-09 18:03:48 +00:00
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)) {
2003-09-03 02:09:29 +00:00
if(dp->d_ino) {
2002-08-09 18:03:48 +00:00
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);
}
2003-09-03 02:09:29 +00:00
/* presents a prompt and gets a Y/N answer */
2002-08-09 18:03:48 +00:00
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);
}
2003-02-27 08:26:02 +00:00
/* 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++;
}
}
2002-08-09 18:03:48 +00:00
/* 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: */