/* xDir.c -- xpk file lister * Copyright (C) 1996-2000 authors * This file is part of the xpk package. * * 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. */ /* * Author: SDI (before 1.2 Urban Dominik Müller) * Written by Dirk Stöcker * UNIX version by Vesa Halttunen */ /* FIX: this is incomplete and doesn't behave exactly like the original * version because the original version sucked. */ #include "config.h" #include #include #include #ifdef HAVE_DIRENT_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include #define MAX_PATH 1024 void fsize(char *); void dirwalk(char *, void (*fcn)(char *)); unsigned int utot = 0, ctot = 0; int main(int argc, char *argv[]) { if(argc == 2 && argv[1][0] == '?') { printf("Usage: xDir files/dirs\n"); exit(10); } printf("Original Packed Ratio Type Protection Name\n" "-------- -------- ----- ---- ---------- ----\n"); if(argc == 1) fsize("."); else { unsigned int i = 1; while(i < argc) { fsize(argv[i]); if(++i < argc) printf("\n"); } } printf("-------- -------- -----\n%8ld %8ld %2ld%%\n", utot, ctot, (utot && (utot > ctot)) ? 100 - (100 * ctot) / utot : 0); return 0; } void fsize(char *name) { struct stat stbuf; struct XpkFib xfib; char text[81]; int ulen=0, clen=0, fl=strlen(name); if(stat(name, &stbuf)==-1) { fprintf(stderr, "fsize: can't access %s\n", name); return; } if((stbuf.st_mode&S_IFMT)==S_IFDIR) dirwalk(name,fsize); memset(text, ' ', 40); if(!XpkExamineTags(&xfib, XPK_InName, name, TAG_DONE) && xfib.xf_Type == XPKTYPE_PACKED) { snprintf(text, 80, "%8d %8d %2d%% %4s", ulen = xfib.xf_ULen, clen = xfib.xf_CLen, xfib.xf_Ratio, xfib.xf_Packer); text[28] = ' '; } else { snprintf(text, 80, "%8d", clen = ulen = stbuf.st_size); text[8] = ' '; } utot+=ulen; ctot+=clen; strncpy(text+40, name, 40); text[40+fl] = '\n'; text[41+fl] = '\0'; printf("%s",text); } void dirwalk(char *dir, void (*fcn)(char *)) { char name[MAX_PATH]; struct dirent *dp; DIR *dfd; if((dfd=opendir(dir))==NULL) { fprintf(stderr, "dirwalk: can't open %s\n", dir); return; } while((dp=readdir(dfd))!=NULL) { if(strcmp(dp->d_name, ".")==0 || strcmp(dp->d_name, "..")==0) continue; if(strlen(dir)+strlen(dp->d_name)+2>sizeof(name)) fprintf(stderr, "dirwalk: name %s/%s too long\n", dir, dp->d_name); else { sprintf(name, "%s/%s", dir, dp->d_name); (*fcn)(name); } } closedir(dfd); }