/* xUp.c -- General XPK file-to-file unpacker * 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.1 Urban Dominik Müller) * Written by Dirk Stöcker * UNIX version by Vesa Halttunen */ #include #include #include #include #include char errbuf[XPKERRMSGSIZE + 1]; /* +1 to make room for '\n'*/ unsigned int chunkfunc(struct XpkProgress *prog) { unsigned int i; if(prog->xp_Type == XPKPROG_START) printf("\033[0 p"); if(prog->xp_Type != XPKPROG_END) printf("\r%4s: %-8s (%3ld%% done, %2ld%% CF, %6ld cps) %s\033[K", prog->xp_PackerName, prog->xp_Activity, prog->xp_Done, prog->xp_CF, prog->xp_Speed, prog->xp_FileName); else printf("\r%4s: %-8s (%3ldK, %2ld%% CF, %6ld cps) %s\033[K\n", prog->xp_PackerName, prog->xp_Activity, prog->xp_ULen >> 10, prog->xp_CF, prog->xp_Speed, prog->xp_FileName); if(prog->xp_Type == XPKPROG_END) printf("\033[1 p"); return 0; // return i; } struct Hook chunkhook = {{0}, (unsigned int (*) ()) chunkfunc}; char namebuf[200]; char *tempname(char *name) { unsigned int i = strlen(name); memcpy(namebuf, name, i); for(name = namebuf + i; name > namebuf; name--) if(name[-1] == '/' || name[-1] == ':') break; sprintf(name, "tmp%lx", &name); return namebuf; } void end(char *text) { if(text) printf(text); exit(text ? 10 : 0); } int main(int argc, char **argv) { int res, i, suffix, len, sufmode = 0; char *password = 0; if(argc == 1 || !strcmp (argv[1], "?")) end("Usage: xUp [-s|-S] [-p password] files\n"); /* find parameters */ for(i = 1; i + 1 < argc; ++i) { if(!strcmp(argv[i], "-s")) sufmode = 1; else if(!strcmp(argv[i], "-S")) sufmode = 2; else if(!strcmp(argv[i], "-p")) password = argv[++i]; else break; } for(; i < argc; i++) { tempname(argv[i]); len = strlen(argv[i]); suffix = 0; if(sufmode == 1 && len > 4 && !strcasecmp(argv[i] + len - 4, ".xpk")) { memcpy(namebuf, argv[i], len-4); namebuf[len-4] = 0; suffix = 1; } else if(sufmode == 2 && len > 2) { char *end = argv[i] + len-1; while(end > argv[i]) { if(*end == '.') { memcpy(namebuf, argv[i], end-argv[i]); namebuf[end-argv[i]] = 0; suffix = 1; break; } --end; } } if((res = XpkUnpackTags( XPK_InName, argv[i], XPK_FileName, (suffix ? namebuf : argv[i]), XPK_OutName, namebuf, XPK_ChunkHook, &chunkhook, XPK_Password, password, XPK_GetError, errbuf, XPK_NoClobber, 1, TAG_DONE )) && res != XPKERR_NOTPACKED) { if(errbuf) { unsigned int i = strlen(errbuf); errbuf[i++] = '\n'; errbuf[i] = 0; } end(errbuf); } if(res) { printf("%s\n", errbuf); if(unlink(namebuf)) end("Cannot delete outfile\n"); } else if(!suffix) { if(unlink(argv[i])) end("Cannot delete input file\n"); if(rename(namebuf, argv[i])) end("Cannot rename tempfile\n"); } } end(0); }