summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--TODO19
-rwxr-xr-xinstallworld25
-rwxr-xr-xmakepkg56
-rwxr-xr-xmakeworld60
-rw-r--r--pacman.8.in12
-rw-r--r--pacman.c170
-rw-r--r--pacman.h10
8 files changed, 232 insertions, 122 deletions
diff --git a/Makefile b/Makefile
index 58de8a2a..5184a572 100644
--- a/Makefile
+++ b/Makefile
@@ -27,7 +27,7 @@ BINDIR = /usr/bin
MANDIR = /usr/man
ETCDIR = /etc
-VERSION = 1.0
+VERSION = 1.1
LIBTAR_VERSION = 1.2.4
CXX = gcc
diff --git a/TODO b/TODO
index a08e2597..72b739d7 100644
--- a/TODO
+++ b/TODO
@@ -1,24 +1,19 @@
-These are things that should get done at some point. Some are simple,
-others are more complex and could be a while in development.
+Some of these items kinda belong on more of a wishlist than a todo list. ;)
+> make sure program consistently returns a non-zero return code on
+ error, so scripts can rely on it
- add a [sibling] option to .PKGINFO -- used when only one of
the siblings can be installed at a time (eg, bsdinit,sysvinit)
-- handle wildcards on the command line
+> handle wildcards on the command line
- sort packages by package name in pacman.db
-- manage conditional file installs (ie, 'info' pages)
-- make sure program consistently returns a non-zero return code on
- error, so scripts can rely on it
+? manage conditional file installs (ie, 'info' pages)
- maybe add a 'confirm every action' option for doing paranoid installs
-- add better directory tracking
- - use crux's pkgmk technique. $(make prefix=$PKG/usr install) then just
- $(cd $PKG; tar czf $pkg.tar.gz *)
- add a consistency check operation
- change char[xxx] to char[PATH_MAX]
- add file locking to db
- add a --dbpath option
-- dependency checking
-- fetch files via ftp
++ dependency checking
++ fetch files via ftp
- need to manage foreign package lists like apt
-- handle .save files better (for more than just .conf files)
- upgrade currently does a double db backup; not really desirable
diff --git a/installworld b/installworld
deleted file mode 100755
index fd155622..00000000
--- a/installworld
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-if [ "$1" = "" ]; then
- echo "usage: $0 <pkg_directory>"
- echo ""
- echo "call this while in the root of the install tree and"
- echo "pass it the path of the directory containing packages"
- echo "to be installed"
- echo ""
- exit
-fi
-
-echo "Initializing pacman database..."
-mkdir -p var/lib/pacman && touch var/lib/pacman/pacman.db
-
-for pkg in `find $1/*`; do
- echo "==> $pkg" >>install.log
- echo "==> $pkg"
- pacman -A -r . $pkg 2>&1 >>install.log
-done
-
-echo "Syncing..."
-sync
-
-echo "Done."
diff --git a/makepkg b/makepkg
index b9ad4bcb..c286d7fc 100755
--- a/makepkg
+++ b/makepkg
@@ -1,7 +1,7 @@
#!/bin/bash
me=`basename $0`
-myver='1.0'
+myver='1.1'
startdir=`pwd`
[ -f /etc/makepkg.conf ] && . /etc/makepkg.conf
@@ -11,30 +11,34 @@ strip_url() {
}
if [ ! -f $startdir/PKGBUILD ]; then
- echo "error: $startdir/PKGBUILD does not exist!"
- exit
+ echo "error: $startdir/PKGBUILD does not exist!" >&2
+ exit 1
fi
. $startdir/PKGBUILD
+echo
+d=`date`
+echo "==> Building package $pkgname ($d)" >&2
+
# extract source
-echo "==> Acquiring/Extracting Sources..."
+echo "==> Acquiring/Extracting Sources..." >&2
mkdir -p src pkg
cd $startdir/src
for netfile in ${source[@]}; do
file=`strip_url $netfile`
if [ -f ../$file ]; then
- echo "==> Found $file in build dir"
+ echo "==> Found $file in build dir" >&2
cp ../$file .
elif [ -f /var/cache/pkg/$file ]; then
- echo "==> Using local copy of $file"
+ echo "==> Using local copy of $file" >&2
cp /var/cache/pkg/$file .
else
- echo "==> Downloading $file"
- wget --passive-ftp --no-directories --tries=3 --waitretry=3 $netfile
+ echo "==> Downloading $file" >&2
+ wget --passive-ftp --no-directories --tries=3 --waitretry=3 $netfile 2>&1
if [ ! -f $file ]; then
- echo "==> ERROR: Failed to download $file"
- echo "==> Aborting..."
+ echo "==> ERROR: Failed to download $file" >&2
+ echo "==> Aborting..." >&2
exit 1
fi
mkdir -p /var/cache/pkg && cp $file /var/cache/pkg
@@ -49,40 +53,50 @@ for netfile in ${source[@]}; do
*)
cmd="cp ../$file ." ;;
esac
- echo "$cmd"
+ echo "==> $cmd" >&2
$cmd
done
# build
-echo "==> Building Package..."
-build
+echo "==> Building Package..." >&2
+build 2>&1
+if [ $? -gt 0 ]; then
+ echo "==> Build Failed. Aborting..." >&2
+ exit 2
+fi
# write the .PKGINFO file
-echo "==> Generating .PKGINFO file..."
+echo "==> Generating .PKGINFO file..." >&2
cd $startdir/pkg
echo "# Generated by makepkg $myver" >.PKGINFO
echo -n "# " >>.PKGINFO
date >>.PKGINFO
echo "pkgname = $pkgname" >>.PKGINFO
echo "pkgver = $pkgver-$pkgrel" >>.PKGINFO
+for bakfile in "${backup[@]}"; do
+ echo "backup = $bakfile" >>.PKGINFO
+done
-# remove info files
+# remove info/doc files
cd $startdir
rm -rf pkg/usr/info pkg/usr/share/info
+rm -rf pkg/usr/doc pkg/usr/share/doc
# strip binaries
cd $startdir
-echo "==> Stripping debugging symbols from libraries..."
+echo "==> Stripping debugging symbols from libraries..." >&2
find pkg/{,usr,usr/local}/lib -type f \
- -exec /usr/bin/strip --strip-debug '{}' ';'
-echo "==> Stripping symbols from binaries..."
+ -exec /usr/bin/strip --strip-debug '{}' ';' 2>&1
+echo "==> Stripping symbols from binaries..." >&2
find pkg/{,usr,usr/local}/{bin,sbin} -type f \
- -exec /usr/bin/strip '{}' ';'
+ -exec /usr/bin/strip '{}' ';' 2>&1
# tar it up
-echo "==> Compressing package..."
+echo "==> Compressing package..." >&2
cd $startdir/pkg
tar czvf $startdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz .PKGINFO * >../filelist
cd $startdir
-echo "==> Finished";
+d=`date`
+echo "==> Finished ($d)" >&2
+exit 0
diff --git a/makeworld b/makeworld
index a6c0b470..883e5ad5 100755
--- a/makeworld
+++ b/makeworld
@@ -2,28 +2,48 @@
toplevel=`pwd`
-if [ $# -lt 1 ]; then
- echo "usage: $0 <destdir>"
+if [ $# -lt 2 ]; then
+ echo "usage: $0 <destdir> <category> [category] ..."
+ echo " where <category> is base, opt, etc."
+ echo " eg: makeworld /packages base opt extra"
exit 1
fi
-for port in `find $toplevel -type d -maxdepth 1 -mindepth 1 | sort`; do
- cd $port
- if [ -f PKGBUILD ]; then
- . PKGBUILD
- donebuild=0
- if [ ! -f $1/$pkgname-$pkgver-$pkgrel.pkg.tar.gz ]; then
- makepkg
- rm -rf pkg src
- mv -v $pkgname-$pkgver-$pkgrel.pkg.tar.gz $1/
- donebuild=1
- fi
- d=`date +"[%b %d %H:%M]"`
- echo -n "$d " >>$toplevel/build.log
- if [ $donebuild = 1 ]; then
- echo "$pkgname was built successfully" >>$toplevel/build.log
- else
- echo "$pkgname already built -- skipping" >>$toplevel/build.log
+dest=$1
+shift
+
+sd=`date +"[%b %d %H:%M]"`
+
+for category in $*; do
+ for port in `find $toplevel/$category -type d -maxdepth 1 -mindepth 1 | sort`; do
+ cd $port
+ if [ -f PKGBUILD ]; then
+ . PKGBUILD
+ buildstatus=0
+ if [ ! -f $dest/$pkgname-$pkgver-$pkgrel.pkg.tar.gz ]; then
+ makepkg
+ if [ $? -gt 0 ]; then
+ buildstatus=2
+ else
+ rm -rf pkg src
+ # some packages (mozilla) have been split into multiple packages
+ mv -v $pkgname-*.pkg.tar.gz $dest/
+ buildstatus=1
+ fi
+ fi
+ d=`date +"[%b %d %H:%M]"`
+ echo -n "$d " >>$toplevel/build.log
+ case $buildstatus in
+ 0) echo "$pkgname already built -- skipping" >>$toplevel/build.log ;;
+ 1) echo "$pkgname was built successfully" >>$toplevel/build.log ;;
+ 2) echo "$pkgname build failed" >>$toplevel/build.log ;;
+ esac
fi
- fi
+ done
done
+ed=`date +"[%b %d %H:%M]"`
+
+echo "makeworld complete." >>$toplevel/build.log
+echo " started: $sd" >>$toplevel/build.log
+echo " finished: $ed" >>$toplevel/build.log
+
diff --git a/pacman.8.in b/pacman.8.in
index 2db57ced..a7e720ed 100644
--- a/pacman.8.in
+++ b/pacman.8.in
@@ -47,6 +47,11 @@ files owned by the package.
.B "\-i, \-\-info"
Output the .PKGINFO file contained in <package>. This option
can only be used with the \fB-p\fP option.
+.TP
+.B "\-p, \-\-file"
+Tells pacman that the package supplied on the command line is a
+file, not an entry in the database. Pacman will decompress the
+file and query it. This is useful with \fB--info\fP and \fB--list\fP.
.SH OPTIONS
.TP
.B "\-v, \-\-verbose"
@@ -58,6 +63,13 @@ that is about to be installed contains files that are already
installed this option will cause all those files to be overwritten.
This option should be used with care, preferably not at all.
.TP
+.B "\-n, \-\-nosave"
+Instructs pacman to ignore file backup designations. Normally, when
+a file is about to be removed from the system, the database is first
+checked to see if the file should be renamed to a .save extension
+(indicated by a '\fB*\fP' prefix in the pacman database). The \fB--nosave\fP
+will turn off all file backups.
+.TP
.B "\-r, \-\-root <path>"
Specify alternative installation root (default is "/"). This
should \fInot\fP be used as a way to install software into
diff --git a/pacman.c b/pacman.c
index 60c99726..0a686925 100644
--- a/pacman.c
+++ b/pacman.c
@@ -1,4 +1,4 @@
-/**
+/*
* pacman
*
* Copyright (c) 2002 by Judd Vinet <jvinet@zeroflux.org>
@@ -18,6 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
+
#include "pacman.h"
#include <stdio.h>
#include <stdarg.h>
@@ -191,11 +192,12 @@ int pacman_add(char* pkgfile)
char* expath = NULL;
char* newpath = NULL;
fileset_t files = NULL;
- unsigned int filecount = 0;
+ unsigned int filecount = 0, nb = 0;
struct stat buf;
/* Populate the file list */
filecount = load_pkg(pkgfile, &files, 0);
+
if(filecount == 0) {
return(1);
}
@@ -244,16 +246,18 @@ int pacman_add(char* pkgfile)
strcpy(expath, pmo_root);
strcat(expath, "/");
strcat(expath, th_get_pathname(tar));
+
+ /* see if this file should be backed up */
+ nb = needbackup(expath, files, filecount);
+
vprint(" %s\n", expath);
- if(!stat(expath, &buf)) {
- /* if the file ends in .conf, back it up */
- if(!strcmp((char*)(expath+strlen(expath)-5), ".conf")) {
- newpath = (char*)realloc(newpath, strlen(expath)+6);
- strcpy(newpath, expath);
- strcat(newpath, ".save");
- rename(expath, newpath);
- printf("%s renamed to %s\n", expath, newpath);
- }
+ if(!pmo_nosave && nb && !stat(expath, &buf)) {
+ /* backup this file */
+ newpath = (char*)realloc(newpath, strlen(expath)+6);
+ strcpy(newpath, expath);
+ strcat(newpath, ".save");
+ rename(expath, newpath);
+ printf("%s renamed to %s\n", expath, newpath);
}
if(tar_extract_file(tar, expath)) {
errmsg = strerror(errno);
@@ -284,9 +288,10 @@ int pacman_remove(char* pkgfile)
int i;
char line[255];
fileset_t files = NULL;
- unsigned int filecount = 0;
+ unsigned int filecount = 0, nb = 0;
struct stat buf;
char* newpath = NULL;
+ char* file = NULL;
if(pkgfile == NULL) {
return(0);
@@ -322,27 +327,36 @@ int pacman_remove(char* pkgfile)
}
/* iterate through the list backwards, unlinking files */
for(i = filecount-1; i >= 0; i--) {
- if(lstat(files[i], &buf)) {
- vprint("file %s does not exist\n", files[i]);
+ file = (char*)realloc(file, strlen(files[i])+strlen(pmo_root)+1);
+ strcpy(file, pmo_root);
+ if(files[i][0] == '*') {
+ nb = 1;
+ strcat(file, (char*)(files[i]+1));
+ } else {
+ nb = 0;
+ strcat(file, files[i]);
+ }
+ if(lstat(file, &buf)) {
+ vprint("file %s does not exist\n", file);
continue;
}
if(S_ISDIR(buf.st_mode)) {
- vprint(" removing directory %s\n", files[i]);
- if(rmdir(files[i])) {
+ vprint(" removing directory %s\n", file);
+ if(rmdir(file)) {
/* this is okay, other packages are probably using it. */
/* perror("cannot remove directory"); */
}
} else {
/* if the file ends in .conf, back it up */
- if(!pmo_nosave && !strcmp((char*)(files[i]+strlen(files[i])-5), ".conf")) {
- newpath = (char*)realloc(newpath, strlen(files[i])+6);
- strcpy(newpath, files[i]);
+ if(!pmo_nosave && nb) {
+ newpath = (char*)realloc(newpath, strlen(file)+6);
+ strcpy(newpath, file);
strcat(newpath, ".save");
- rename(files[i], newpath);
- printf("%s renamed to %s\n", files[i], newpath);
+ rename(file, newpath);
+ printf("%s renamed to %s\n", file, newpath);
} else {
- vprint(" unlinking %s\n", files[i]);
- if(unlink(files[i])) {
+ vprint(" unlinking %s\n", file);
+ if(unlink(file)) {
perror("cannot remove file");
}
}
@@ -388,7 +402,11 @@ int pacman_query(char* pkgfile)
if(pmo_q_list) {
for(i = 0; i < filecount; i++) {
if(strcmp(files[i], ".PKGINFO")) {
- printf("%s\n", files[i]);
+ if(files[i][0] == '*') {
+ printf("%s\n", (char*)(files[i]+1));
+ } else {
+ printf("%s\n", files[i]);
+ }
}
}
} else {
@@ -451,7 +469,11 @@ int pacman_query(char* pkgfile)
strcpy(line, trim(line));
if(strlen(line)) {
if(pmo_q_list) {
- printf("%s%s\n", pmo_root, line);
+ if(line[0] == '*') {
+ printf("%s%s\n", pmo_root, (char*)(line+1));
+ } else {
+ printf("%s%s\n", pmo_root, line);
+ }
}
} else {
found = 1;
@@ -493,6 +515,8 @@ int load_pkg(char* pkgfile, fileset_t* listptr, unsigned short output)
TAR* tar;
unsigned int filecount = 0;
fileset_t files = NULL;
+ fileset_t backup = NULL;
+ unsigned int bakct = 0;
descfile = (char*)malloc(strlen("/tmp/pacman_XXXXXX")+1);
strcpy(descfile, "/tmp/pacman_XXXXXX");
@@ -508,12 +532,19 @@ int load_pkg(char* pkgfile, fileset_t* listptr, unsigned short output)
vprint("Found package description file.\n");
mkstemp(descfile);
tar_extract_file(tar, descfile);
- parse_descfile(descfile, output);
+ parse_descfile(descfile, output, &backup, &bakct);
continue;
}
/* build the new pathname relative to pmo_root */
- expath = (char*)malloc(strlen(th_get_pathname(tar))+strlen(pmo_root)+2);
- strcpy(expath, pmo_root);
+ if(is_in(th_get_pathname(tar), backup, bakct)) {
+ expath = (char*)malloc(strlen(th_get_pathname(tar))+strlen(pmo_root)+3);
+ // prepend the backup symbol
+ strcpy(expath, "*");
+ } else {
+ expath = (char*)malloc(strlen(th_get_pathname(tar))+strlen(pmo_root)+2);
+ expath[0] = '\0';
+ }
+ strcat(expath, pmo_root);
strcat(expath, "/");
strcat(expath, th_get_pathname(tar));
/* add the path to the list */
@@ -522,7 +553,7 @@ int load_pkg(char* pkgfile, fileset_t* listptr, unsigned short output)
if(TH_ISREG(tar) && tar_skip_regfile(tar)) {
perror("bad package file");
- return(0);
+ return(1);
}
expath = NULL;
}
@@ -657,6 +688,10 @@ int db_update(fileset_t files, unsigned int filecount)
for(i = 0; i < filecount; i++) {
str = files[i];
str += strlen(pmo_root);
+ if(files[i][0] == '*') {
+ fputc('*', dbfp);
+ str++;
+ }
fputs(str, dbfp);
fputc('\n', dbfp);
}
@@ -680,6 +715,8 @@ int db_find_conflicts(fileset_t files, unsigned int filecount)
int i;
char line[255];
char name[255];
+ char* dbstr = NULL;
+ char* filestr = NULL;
struct stat buf;
int conflicts = 0;
@@ -697,17 +734,25 @@ int db_find_conflicts(fileset_t files, unsigned int filecount)
while(!feof(dbfp)) {
fgets(line, 255, dbfp);
strcpy(line, trim(line));
- if(!strlen(line)) {
+ dbstr = line;
+ if(dbstr[0] == '*') {
+ dbstr++;
+ }
+ if(!strlen(dbstr)) {
break;
}
- if(index(line, '/') == (char*)line && (!pmo_upgrade || strcmp(name,pkgname))) {
+ if(index(dbstr, '/') == dbstr && (!pmo_upgrade || strcmp(name,pkgname))) {
for(i = 0; i < filecount; i++) {
- if(!strcmp(line, files[i])) {
- if(rindex(files[i], '/') == files[i]+strlen(files[i])-1) {
+ filestr = files[i];
+ if(filestr[0] == '*') {
+ filestr++;
+ }
+ if(!strcmp(dbstr, filestr)) {
+ if(rindex(files[i], '/') == filestr+strlen(filestr)-1) {
/* this filename has a trailing '/', so it's a directory -- skip it. */
continue;
}
- printf("conflict: %s already exists in package \"%s\"\n", line, name);
+ printf("conflict: %s already exists in package \"%s\"\n", dbstr, name);
conflicts = 1;
}
}
@@ -718,8 +763,12 @@ int db_find_conflicts(fileset_t files, unsigned int filecount)
/* CHECK 2: checking filesystem conflicts */
/* TODO: run filesystem checks for upgrades */
for(i = 0; i < filecount && !pmo_upgrade; i++) {
- if(!stat(files[i], &buf) && !S_ISDIR(buf.st_mode)) {
- printf("conflict: %s already exists in filesystem\n", files[i]);
+ filestr = files[i];
+ if(filestr[0] == '*') {
+ filestr++;
+ }
+ if(!stat(filestr, &buf) && !S_ISDIR(buf.st_mode)) {
+ printf("conflict: %s already exists in filesystem\n", filestr);
conflicts = 1;
}
}
@@ -733,13 +782,16 @@ int db_find_conflicts(fileset_t files, unsigned int filecount)
* Returns: 0 on success, 1 on error
*
*/
-int parse_descfile(char* descfile, unsigned short output)
+int parse_descfile(char* descfile, unsigned short output, fileset_t *bakptr,
+ unsigned int* bakct)
{
FILE* fp;
char line[255];
char* ptr = NULL;
char* key = NULL;
int linenum = 0;
+ fileset_t backup = NULL;
+ unsigned int count = 0;
if((fp = fopen(descfile, "r")) == NULL) {
perror(descfile);
@@ -775,6 +827,10 @@ int parse_descfile(char* descfile, unsigned short output)
strcpy(pkgver, ptr);
} else if(!strcmp(key, "PKGDESC")) {
/* Not used yet */
+ } else if(!strcmp(key, "BACKUP")) {
+ backup = (fileset_t)realloc(backup, (++count) * sizeof(char*));
+ backup[count-1] = (char*)malloc(strlen(ptr)+1);
+ strcpy(backup[count-1], ptr);
} else {
printf("Syntax error in description file line %d\n", linenum);
}
@@ -783,6 +839,12 @@ int parse_descfile(char* descfile, unsigned short output)
}
fclose(fp);
unlink(descfile);
+
+ if(count > 0) {
+ (*bakptr) = backup;
+ (*bakct) = count;
+ }
+
return(0);
}
@@ -879,20 +941,20 @@ void usage(int op, char* myname)
printf("usage: %s {-A --add} [options] <file>\n", myname);
printf("options:\n");
printf(" -f, --force force install, overwrite conflicting files\n");
- printf(" -n, --nosave do not save .conf files\n");
+ printf(" -n, --nosave do not save configuration files\n");
printf(" -v, --verbose be verbose\n");
printf(" -r, --root <path> set an alternative installation root\n");
} else if(op == PM_REMOVE) {
printf("usage: %s {-R --remove} [options] <package>\n", myname);
printf("options:\n");
- printf(" -n, --nosave do not save .conf files\n");
+ printf(" -n, --nosave do not save configuration files\n");
printf(" -v, --verbose be verbose\n");
printf(" -r, --root <path> set an alternative installation root\n");
} else if(op == PM_UPGRADE) {
printf("usage: %s {-U --upgrade} [options] <file>\n", myname);
printf("options:\n");
printf(" -f, --force force install, overwrite conflicting files\n");
- printf(" -n, --nosave do not save .conf files\n");
+ printf(" -n, --nosave do not save configuration files\n");
printf(" -v, --verbose be verbose\n");
printf(" -r, --root <path> set an alternative installation root\n");
} else if(op == PM_QUERY) {
@@ -934,6 +996,34 @@ int vprint(char* fmt, ...)
return(0);
}
+/* See if a file should be backed up or not
+ */
+int needbackup(char* file, fileset_t files, unsigned int filect)
+{
+ int i;
+
+ for(i = 0; i < filect; i++) {
+ if(files[i][0] == '*' && !strcmp((char*)(files[i]+1), file)) {
+ return(1);
+ }
+ }
+ return(0);
+}
+
+/* Test for existence of a string in a fileset
+ */
+int is_in(char* needle, fileset_t haystack, unsigned int hayct)
+{
+ int i;
+
+ for(i = 0; i < hayct; i++) {
+ if(!strcmp(haystack[i], needle)) {
+ return(1);
+ }
+ }
+ return(0);
+}
+
/* Convert a string to uppercase
*/
char* strtoupper(char* str)
diff --git a/pacman.h b/pacman.h
index c9f4fdb0..76914964 100644
--- a/pacman.h
+++ b/pacman.h
@@ -21,7 +21,7 @@
#ifndef PACMAN_H
#define PACMAN_H
-#define VERSION "1.0"
+#define VERSION "1.1"
#define PKGEXT ".tar.gz"
#define PKGDB "/var/lib/pacman/pacman.db"
@@ -50,11 +50,15 @@ int db_update(fileset_t files, unsigned int filecount);
int db_find_conflicts(fileset_t files, unsigned int filecount);
int load_pkg(char* pkgfile, fileset_t* listptr, unsigned short output);
+char* parseargs(int op, int argc, char** argv);
+int parse_descfile(char* descfile, unsigned short output, fileset_t* bakptr,
+ unsigned int* bakct);
+
int vprint(char* fmt, ...);
void usage(int op, char* myname);
void version(void);
-char* parseargs(int op, int argc, char** argv);
-int parse_descfile(char* descfile, unsigned short output);
+int is_in(char* needle, fileset_t haystack, unsigned int hayct);
+int needbackup(char* file, fileset_t files, unsigned int filect);
char* trim(char* str);
char* strtoupper(char* str);
static int gzopen_frontend(char *pathname, int oflags, int mode);