4576911 [rkeene@sledge /home/rkeene/devel/dact-0.8.37]$ cat -n dact.c
  1 /*
  2  * Copyright (C) 2001, 2002, and 2003  Roy Keene
  3  *
  4  * This program is free software; you can redistribute it and/or
  5  * modify it under the terms of the GNU General Public License
  6  * as published by the Free Software Foundation; either version 2
  7  * of the License, or (at your option) any later version.
  8  *
  9  * This program is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12  * GNU General Public License for more details.
 13  *
 14  * You should have received a copy of the GNU General Public License
 15  * along with this program; if not, write to the Free Software
 16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 17  *
 18  *      email: dact@rkeene.org
 19  */
 20 
 21 #include "dact.h"
 22 #include <fcntl.h>
 23 #include <stdio.h>
 24 #include <ctype.h>
 25 #ifdef HAVE_UNISTD_H
 26 #include <unistd.h>
 27 #endif
 28 #ifdef HAVE_STDLIB_H
 29 #include <stdlib.h>
 30 #endif
 31 #ifdef HAVE_STRING_H
 32 #include <string.h>
 33 #endif
 34 #ifdef HAVE_SYS_STAT_H
 35 #include <sys/stat.h>
 36 #endif
 37 #ifdef HAVE_SYS_WAIT_H
 38 #include <sys/wait.h>
 39 #endif
 40 #ifdef HAVE_SYS_TYPES_H
 41 #include <sys/types.h>
 42 #endif
 43 #include "parse.h"
 44 #include "dendian.h"
 45 #include "crc.h"
 46 #include "math.h"
 47 #include "dact_common.h"
 48 #include "algorithms.h"
 49 #include "ciphers.h"
 50 #include "module.h"
 51 #include "header.h"
 52 #include "parse.h"
 53 #include "net.h"
 54 #include "ui.h"
 55 #ifdef HAVE_ZLIB_H
 56 #include <zlib.h>
 57 #endif
 58 #ifdef HAVE_BZLIB_H
 59 #include <bzlib.h>
 60 #endif
 61 
 62 
 63 int print_help(int argc, char **argv);
 64 int dact_shutdown(int retval);
 65 char *dact_getoutfilename(const char *orig, const int mode);
 66 uint32_t dact_process_other(int src, const int dest, const uint32_t magic, const char *options);
 67 int main(int argc, char **argv);
 68 
 69 extern char *optarg;
 70 extern int optind, opterr, optopt;
 71 char dact_nonetwork=0;
 72 
 73 int print_help(int argc, char **argv) {
 74     printf("DACT %i.%i.%i-%s by Keene Enterprises <dact@rkeene.org>\n", DACT_VER_MAJOR, DACT_VER_MINOR,
	DACT_VER_REVISION, DACT_VER_SUB);
 75     printf("usage: %s [options...] [file ...]\n",argv[0]);
 76     printf("Options:\n");
 77     printf("  -d          Decompress instead of compressing.\n");
 78     printf("  -s          Give statistics rather than compress or decompress.\n");
 79     printf("  -f          Force unsafe things to happen.\n");
 80     printf("  -c          (De)compress to stdout.\n");
 81     printf("  -v          Increase verbosity.\n");
 82     printf("  -l          List available algorithms.\n");
 83     printf("  -n          Toggle use of CRCs.\n");
 84     printf("  -i          Use stdin to read information from instead of /dev/tty.\n");
 85 #ifndef DACT_UNSAFE
 86     printf("  -C          Complain when compression errors occur.\n");
 87 #endif
 88     printf("  -H          Write only header (no data).\n");
 89     printf("  -O          Toggle writing original file name.\n");
 90     printf("  -S          Use speed-size as a metric rather than size.\n");
 91     printf("  -h          Give this help.\n");
 92     printf("  -V          Display DACT version (%i.%i.%i-%s).\n", DACT_VER_MAJOR, DACT_VER_MINOR, DACT_VER_REVISION,
	DACT_VER_SUB);
 93     printf("  -N          Upgrade DACT.\n");
 94     printf("  -a          Upgrade DACT modules.\n");
 95     printf("  -b NN       Use a block size of NN bytes for compression.\n");
 96     printf("  -e NN       Exclude algorithm NN from being used.\n");
 97     printf("  -m CONF     Load config file CONF.\n");
 98     printf("  -o FILE     Send output to FILE.\n");
 99     printf("  -u URL      Specify download location as URL.\n");
100     printf("  -p URL      Parse URL and print results, then exit.\n");
101     printf("  -M COMMAND  Execute COMMAND as if it had appeared in a config file.\n");
102     printf("  -D DESC     Specify a description of DESC.\n");
103     printf("  -I NN       Use ONLY 2 algorithms, NN and 0.\n");
104     printf("  -U FILE     Use FILE to select download location.\n");
105     printf("  -E CIPHER   Use CIPHER to encrypt data (LIST  lists available ciphers.)\n");
106     printf("  file...     File(s) to (de)compress.  (If none given, use standard input).\n");
107     return(0);
108 }
109 
110 int dact_blksize_calc(int fsize) {
111     if (fsize==0) return(DACT_BLK_SIZE_DEF);
112     if (fsize<(204800)) {
113         return(fsize+5);
114     }
115     return(((int) ((((float) fsize)/102400.0)-(0.9999999)))*65535);
116 }
117 
118 int dact_upgrade_file(const char *name, const char *url_get, const char *url_ver, uint32_t version, const char *dest,
	const char *options) {
119     int newver, ifd=-1, ofd=-1, x=-1;
120     char *real_dest, *real_url_get, buf[4096];
121 
122     if (dest==NULL) {
123         real_dest=parse_url_subst(DACT_BIN_DIR "@@FILE@@.so", name);
124     } else {
125         real_dest=parse_url_subst(dest, name);
126     }
127     real_url_get=parse_url_subst(url_get, name);
128 
129     newver=dact_upgrade_file_checkver(name, url_ver, options);
130     if (newver>version) {
131         if (options[DACT_OPT_UPGRADE]) {
132             fprintf(stderr, "There is a new version of %s.  NEW: %i.%i.%i, CURR: %i.%i.%i, fetching...\n", name,
	DACT_VER_PARTS(newver), DACT_VER_PARTS(version));
133             if ((ifd=open_net(real_url_get, O_RDONLY, 0))>=0) {
134                 if ((ofd=open_net(real_dest, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU))>=0) {
135                     while ((x=read(ifd, buf, sizeof(buf)))>0) {
136                         write(ofd, buf, x);
137                     }
138                     close(ifd);
139                     close(ofd);
140                     if (x<0) PERROR("read");
141                 } else {
142                     PERROR_L(ofd, "open");
143                 }
144             } else {
145                 PERROR_L(ifd, "open");
146             }
147         } else {
148             fprintf(stderr, "There is a new version of %s.  NEW: %i.%i.%i, CURR: %i.%i.%i\n", name,
	DACT_VER_PARTS(newver), DACT_VER_PARTS(version));
149         }
150     }
151     free(real_dest);
152     free(real_url_get);
153     return(x);
154 }
155 
156 int dact_upgrade_file_checkver(const char *name, const char *url_ver, const char *options) {
157 #ifdef CHECK_VERSION
158     uint32_t rem_ver[4]={0, 0, 0, 0};
159     int fd;
160     char rem_vers[3][4]={{0,0,0,0},{0,0,0,0},{0,0,0,0}};
161     char *urlbuf, verbuf[9];
162 
163     if (options[DACT_OPT_VERCHK]==0 && options[DACT_OPT_UPGRADE]==0) return(0);
164 
165     urlbuf=parse_url_subst(url_ver, name);
166     if ((fd=open_net(urlbuf, O_RDONLY, 0))>=0) {
167         read(fd, &verbuf, 9);
168         close(fd);
169         memcpy(rem_vers[0], verbuf, 3);
170         memcpy(rem_vers[1], verbuf+3, 3);
171         memcpy(rem_vers[2], verbuf+6, 3);
172         rem_ver[0]=atoi(rem_vers[0]);
173         rem_ver[1]=atoi(rem_vers[1]);
174         rem_ver[2]=atoi(rem_vers[2]);
175         rem_ver[3]=(rem_ver[0]<<16)|(rem_ver[1]<<8)|(rem_ver[2]);
176     }
177     free(urlbuf);
178     return(rem_ver[3]);
179 #else
180     return(0);
181 #endif
182 }
183 
184 int dact_upgrade(char *options) {
185 #ifdef DACT_DEBIAN_UPGRADE_PROC
186     char *buf;
187     int status=0, i;
188 
189     if (getuid()==0) {
190         buf=dact_ui_getuserinput("Executing `apt-get update' okay [y/N]? ", 5, 0);
191         if (toupper(buf[0])!='Y') {
192             PRINTERR("Failed to upgrade DACT.");
193             free(buf);
194             return(-1);
195         }
196         free(buf);
197 
198         if (fork()==0) {
199             execl("/usr/bin/apt-get","apt-get","update",NULL);
200             return(-1);  /* Couldn't run binary. */
201         } else {
202             i=wait(&status);
203             if (WIFEXITED(status)) {
204                 if (WEXITSTATUS(status)) {
205                     PRINTERR("Failed to run `apt-get update'");
206                     return(-1);
207                 }
208             }
209         }
210 
211         if (fork()==0) {
212             execl("/usr/bin/apt-get","apt-get","install","dact",NULL);
213             return(-1);  /* Couldn't run binary. */
214         } else {
215             i=wait(&status);
216             if (WIFEXITED(status)) {
217                 if (WEXITSTATUS(status)) {
218                     PRINTERR("Failed to run `apt-get install dact'");
219                     return(-1);
220                 }
221             }
222         }
223 
224         return(1);
225     }
226 #else
227     options[DACT_OPT_UPGRADE]=1;
228     return(dact_upgrade_file("dact", DACT_BIN_URL, DACT_BIN_URL_VER, DACT_BIN_VER, DACT_BIN, options));
229 #endif
230 }
231 
232 #if 0
233 int dact_upgrade(const char *options, uint32_t *crcs) {
234     char *urlsubst, *buf, *dact_binfilebuf;
235     char dact_binfile[256];
236     int inFd, outFd;
237     uint32_t i;
238 
239 
240 #ifdef DACT_DEBIAN_UPGRADE_PROC
241     int status=0;
242 
243     if (getuid()==0) {
244         buf=dact_ui_getuserinput("Executing `apt-get update' okay [y/N]? ", 5, 0);
245         if (toupper(buf[0])!='Y') {
246             PRINTERR("Failed to upgrade DACT.");
247             free(buf);
248             return(-1);
249         }
250         free(buf);
251 
252         if (fork()==0) {
253             execl("/usr/bin/apt-get","apt-get","update",NULL);
254             return(-1);  /* Couldn't run binary. */
255         } else {
256             i=wait(&status);
257             if (WIFEXITED(status)) {
258                 if (WEXITSTATUS(status)) {
259                     PRINTERR("Failed to run `apt-get update'");
260                     return(-1);
261                 }
262             }
263         }
264 
265         if (fork()==0) {
266             execl("/usr/bin/apt-get","apt-get","install","dact",NULL);
267             return(-1);  /* Couldn't run binary. */
268         } else {
269             i=wait(&status);
270             if (WIFEXITED(status)) {
271                 if (WEXITSTATUS(status)) {
272                     PRINTERR("Failed to run `apt-get install dact'");
273                     return(-1);
274                 }
275             }
276         }
277 
278         return(1);
279     }
280 #endif
281 
282     if ((i=is_latest(options))) {
283         PRINTERR("**+");
284         PRINT_LINE; fprintf(stderr, "dact: **> CURR: DACT %i.%i.%i\n",DACT_VER_MAJOR, DACT_VER_MINOR,
	DACT_VER_REVISION);
285         PRINT_LINE; fprintf(stderr, "dact: **> NEW:  DACT %i.%i.%i\n",i>>16,(i>>8)&0xff,i&0xff);
286         PRINTERR("**>");
287         PRINTERR("**-");
288     }
289     if ((inFd=open_net("http://www.rkeene.org/projects/rget/rget.cgi?project=dact&file=info", O_RDONLY))>=0) {
290         fprintf(stderr, "------------------------\n");
291         buf=malloc(1024);
292         while (1) {
293             i=read_f(inFd, buf, 1024);
294             write(STDERR_FILENO, buf, i);
295             if (i!=1024) break;
296         }
297         fprintf(stderr, "------------------------\n");
298         close(inFd);
299         free(buf);
300     }
301 
302 #ifdef GO32
303     mkdir("c:/dact/", 0755);
304     strcpy(dact_binfile,"c:/dact/dact.exe");
305 #else
306     strncpy(dact_binfile,getenv("HOME"),sizeof(dact_binfile)-1);
307     strncat(dact_binfile,"/.dact/",sizeof(dact_binfile)-strlen(dact_binfile)-1);
308     mkdir(dact_binfile, 0755);
309     dact_binfilebuf=parse_url_subst("@@OSNM@@-@@ARCH@@/", "");
310     strncat(dact_binfile,dact_binfilebuf,sizeof(dact_binfile)-strlen(dact_binfile)-1);
311     free(dact_binfilebuf);
312     mkdir(dact_binfile, 0755);
313     
314     strncat(dact_binfile,"dact.bin",sizeof(dact_binfile)-strlen(dact_binfile)-1);
315 #endif
316    
	urlsubst=parse_url_subst("http://www.rkeene.org/projects/rget/rget.cgi?os=@@OSNM@@&arch=@@ARCH@@&project=dact&file=bin&
	meth=gz","");
317     if ((outFd=open_net(dact_binfile, O_WRONLY|O_TRUNC|O_CREAT, 0755))<0) {
318         PERROR_L(outFd, "open_net");
319         return(-1);
320     }
321     if ((inFd=open_net(urlsubst, O_RDONLY, 0))<0) {
322         PERROR_L(inFd, "open_net");
323         return(-1);
324     }
325     if (!dact_process_file(inFd, outFd, DACT_MODE_DECMP, options, "dact", crcs, DACT_BLK_SIZE_DEF, -1)) {
326         close(inFd);
327         close(outFd);
328         unlink(dact_binfile);
329         PRINTERR("Failed to upgrade DACT.");
330         return(-1);
331     }
332     close(inFd);
333     close(outFd);
334     if (!options[DACT_OPT_BINCHK]) {
335         PRINTERR("Note: You do not have binary_check  set to `on' in your dact.conf.");
336     }
337     return(1);
338 }
339 
340 uint32_t is_latest (const char *options) {
341 #if defined(CHECK_VERSION)
342     int fd;
343     char ver_maj[4]={0,0,0,0}, ver_min[4]={0,0,0,0}, ver_rev[4]={0,0,0,0};
344     char bigbuf[1024];
345     int vers[3];
346 
347     if (options[DACT_OPT_VERCHK]==0) return(0);
348     if (getuid()==0) return(0);
349 
350     if ((fd=createconnection_tcp("www.rkeene.org", 80))<0) return(0);
351 
352     write(fd, "GET http://www.rkeene.org/devel/dact/VERSION\n", 45);
353     read(fd, &bigbuf,1024);
354 
355     memcpy(ver_maj,bigbuf,3);
356     memcpy(ver_min,bigbuf+3,3);
357     memcpy(ver_rev,bigbuf+6,3);
358 
359     closeconnection(fd);
360 
361     vers[0]=atoi(ver_maj);
362     vers[1]=atoi(ver_min);
363     vers[2]=atoi(ver_rev);
364 
365     if ( ((vers[0]<<16)|(vers[1]<<8)|vers[2]) > ((DACT_VER_MAJOR<<16)|(DACT_VER_MINOR<<8)|DACT_VER_REVISION) ) {
366         return((vers[0]<<16)|(vers[1]<<8)|vers[2]);
367     } else {
368         return(0);
369     }
370 #else
371     return(0);
372 #endif
373 }
374 #endif
375 
376 int dact_shutdown(int retval) {
377     unload_modules();
378     dact_ui_deinit();
379     return(retval);
380 }
381 
382 char *dact_getoutfilename(const char *orig, const int mode) {
383     char *ret=NULL;
384     int x=0;
385 
386     switch (mode) {
387         case DACT_MODE_COMPR:
388             ret=malloc(strlen(orig)+5);
389 #ifdef GO32
390             strncpy(ret,orig,8);
391             for (x=0;x<strlen(ret);x++) {
392                 if (ret[x]=='.') ret[x]='_';
393             }
394             strcat(ret,".dct");
395 #else
396             strcpy(ret,orig);
397             strcat(ret,".dct");
398 #endif
399             break;
400         case DACT_MODE_DECMP:
401             if (strcmp(&orig[strlen(orig)-4],".dct") && \
402                 strcmp(&orig[strlen(orig)-4], ".bz2") && \
403                 strcmp(&orig[strlen(orig)-5], ".tbz2") && \
404                 strcmp(&orig[strlen(orig)-4], ".tgz") && \
405                 strcmp(&orig[strlen(orig)-3], ".gz")) {
406                 return(NULL);
407             }
408 /* XXX: I wonder if this breaks easily... */
409             x=(strrchr(orig,'.')-orig);
410             ret=malloc(x+1);
411             strncpy(ret,orig,x);
412             ret[x]=0;
413             break;
414         case DACT_MODE_STAT:
415             return(NULL);
416             break;
417     }
418     return(ret);
419 }
420 
421 uint32_t dact_process_other(int src, const int dest, const uint32_t magic, const char *options) {
422     char *buf, tmpbuf[128]="/tmp/dactXXXXXX";
423     uint32_t filesize=0, x;
424     int tmpfd=0;
425 #if defined(HAVE_LIBBZ2) && (defined(HAVE_BZDOPEN) || defined(HAVE_NEW_BZDOPEN))
426     BZFILE *bzfd;
427 #endif
428 #if defined(HAVE_LIBZ) && defined(HAVE_GZDOPEN)
429     gzFile gzfd;
430 #endif
431 
432     filesize=0;  /* Fix a warning, that is all. */
433 
434 /*
435  * bad and broke stuff XXX FIXME XXX FIXME XXX FIXME
436  * There has to be a better way to do this... I just want
437  * to rewind my socket/pipe 4 bytes... 4 bytes is all I ask
438  * Is that so much to ask for?  Well?!  Is it?!  I don't
439  * think it is.
440  * I give up on this.
441  *
442  * Someone please fix it.
443  *  -- Roy Keene <dact@rkeene.org>
444  */
445     if (lseek_net(src, 0, SEEK_SET)<0) {
446         PRINTERR("This should not be happening.");
447 /*
448  * lseek_net() should make this obsolete.
449  *  ... EXCEPT! when reading from stdin.
450  */
451         tmpfd=mkstemp(tmpbuf);
452         write_de(tmpfd, magic, 4);
453         buf=malloc(1024);
454         while (1) {
455             x=read_f(src, buf, 1024);
456             write(tmpfd, buf, x);
457             if (x<1024) break;
458         }
459         close(src);
460         src=tmpfd;
461         lseek_net(src, 0, SEEK_SET); /* Now bitch. */
462         free(buf);
463     }
464 #if defined(HAVE_LIBZ) && defined(HAVE_GZDOPEN)
465 
466 
467     if ((magic&0xffff0000)==0x1f8b0000) { /* gzip */
468         dact_ui_status(DACT_UI_LVL_GEN, "Gunzipping...");
469         buf=malloc(1024);
470 
471         gzfd=gzdopen(src, "r");
472 /*XXX: need to dact_ui_setup() */
473         while (1) {
474             dact_ui_incrblkcnt(1);
475             x=gzread(gzfd,buf,1024);
476             filesize+=write(dest, buf, x);
477             if (x<1024) break;
478         }
479         free(buf);
480         if (tmpfd!=0) unlink(tmpbuf);
481         return(filesize);
482     }
483 #endif
484 
485 #if defined(HAVE_LIBBZ2) && (defined(HAVE_BZDOPEN) || defined(HAVE_NEW_BZDOPEN))
486     if ((magic&0xffffff00)==0x425a6800) { /* bzip2 */ 
487         dact_ui_status(DACT_UI_LVL_GEN, "Bunzipping...");
488         buf=malloc(1024);
489 
490 #ifdef HAVE_NEW_BZDOPEN
491         bzfd=BZ2_bzdopen(src, "r");
492 #else
493         bzfd=bzdopen(src, "r");
494 #endif
495 /*XXX: need to dact_ui_setup() */
496         while(1) {
497             dact_ui_incrblkcnt(1);
498 #ifdef HAVE_NEW_BZDOPEN
499             x=BZ2_bzread(bzfd, buf, 1024);
500 #else
501             x=bzread(bzfd, buf, 1024);
502 #endif
503             filesize+=write(dest, buf, x);
504             if (x<1024) break;
505         }
506         free(buf);
507         if (tmpfd!=0) unlink(tmpbuf);
508         return(filesize);
509     }
510 #endif
511     return(0);
512 }
513 
514 int main(int argc, char **argv) {
515     unsigned char options[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
516     signed char opt;
517     struct stat stat_buf;
518     char **in_files, *in_file=NULL, *out_file=NULL;
519     char dact_binfilebuf[256], *dact_binfile;
520     int filecnt=0;
521     int in_fd, out_fd;
522     int mode=DACT_MODE_COMPR, ciphernum=-1;
523     uint32_t dact_blk_size=0;
524     uint32_t crcs[6]={0,0,0,0,0,0};
525     uint32_t i,x;
526 
527 
528     dact_ui_init();
529 
530 
531 /* hack, to make upgrade work even if DACT_OPT_BINCHK is enabled, we must
532  *      get the new version before executing it.
533  */
534     if (argv[1]!=NULL) {
535         if (!strcmp(argv[1],"-N")) return(dact_upgrade(options));
536         if (!strcmp(argv[1],"-a")) options[DACT_OPT_UPGRADE]=1;
537     }
538 
539     dact_config_loadfile(DACT_CONFIG_FILE, options, &dact_blk_size);
540 #ifndef NO_BINCHECK
541     dact_binfilebuf[0]='\0';
542     if (getenv("HOME")) {
543         strncpy(dact_binfilebuf,getenv("HOME"),sizeof(dact_binfilebuf)-1);
544     }
545     strncat(dact_binfilebuf,"/.dact/dact.conf",sizeof(dact_binfilebuf)-strlen(dact_binfilebuf)-1);
546     dact_config_loadfile(dact_binfilebuf, options, &dact_blk_size);
547 #endif
548 
549     if (options[DACT_OPT_BINCHK]) {
550         dact_binfile=parse_url_subst(DACT_BIN, "");
551         if (strcmp(argv[0],dact_binfile)) {
552             if (!access(dact_binfile,X_OK)) {
553                 argv[0]=dact_binfile;
554                 /* This fixes a strange warning..*/
555 #ifndef __MINGW32__
556                 execv(dact_binfile, argv);
557 #else
558                 execv(dact_binfile, (const char **) argv);
559 #endif
560             }
561         }
562     }
563 
564     while ((opt=getopt(argc,argv,"adfsvcnhiNVHCM:E:p:I:m:e:lb:u:U:TPOD:o:"))!=-1) {
565         switch (opt) {
566             case 'a':
567                 options[DACT_OPT_UPGRADE]=1;
568                 break;
569             case 'd':
570                 mode=DACT_MODE_DECMP;
571                 break;
572             case 'f':
573                 options[DACT_OPT_FORCE]++;
574                 break;
575             case 's':
576                 mode=DACT_MODE_STAT;
577                 break;
578             case 'i':
579                 dact_ui_setopt(DACT_UI_OPT_PASSSTDIN, 1);
580                 break;
581             case 'c':
582                 options[DACT_OPT_STDOUT]=!options[DACT_OPT_STDOUT];
583                 break;
584             case 'b':
585                 i=atoi2(optarg);
586                 if (i<DACT_BLK_SIZE_MAX) dact_blk_size=i;
587                 break;
588             case 'v':
589                 options[DACT_OPT_VERB]++;
590                 dact_ui_setopt(DACT_UI_OPT_LEVEL,dact_ui_getopt(DACT_UI_OPT_LEVEL)+1);
591                 break;
592             case 'n':
593                 options[DACT_OPT_NOCRC]=!options[DACT_OPT_NOCRC];
594                 break;
595             case 'p':
596                 PRINT_LINE; fprintf(stderr, "dact: %s\n",parse_url_subst(optarg,"@@file@@"));
597                 mode=DACT_MODE_RET;
598                 break;
599             case 'C':
600                 options[DACT_OPT_COMPLN]++;
601                 break;
602             case 'm':
603                 dact_config_loadfile(optarg, options, &dact_blk_size);
604                 break;
605             case 'e':
606                 i=(atoi(optarg)&0xff);
607                 algorithms[i]=DACT_FAILED_ALGO;
608                 break;
609             case 'H':
610                 options[DACT_OPT_HDONLY]=!options[DACT_OPT_HDONLY];
611                 break;
612             case 'o':
613                 out_file=parse_url_subst(optarg, "");
614                 break;
615             case 'M':
616                 dact_config_execute(optarg, options, &dact_blk_size);
617                 break;
618             case 'N':
619                 PRINTERR("The `-N\' option must be the first and only argument passed to dact.");
620                 return(0);
621                 break;
622             case 'E':
623                 strtolower(optarg);
624                 x=hash_fourbyte(optarg, ' ');
625                 if (x==hash_fourbyte("list", ' ')) {
626                     PRINT_LINE; fprintf(stderr, "dact: Num | Name\n");
627                     for (i=0;i<CIPHER_COUNT;i++) {
628                         if (ciphers_name[i]!=NULL && ciphers[i]!=DACT_FAILED_ALGO) {
629                             PRINT_LINE; fprintf(stderr, "dact: %3i | %s\n",i,ciphers_name[i]);
630                         }
631                     }
632                     return(0);
633                 }
634                 for (i=0;i<CIPHER_COUNT;i++) {
635                     if (ciphers_name[i]!=NULL && ciphers[i]!=DACT_FAILED_ALGO) {
636                         if (x==hash_fourbyte(ciphers_name[i], ' ')) {
637                             break;
638                         }
639                     }
640                 }
641                 if (i==CIPHER_COUNT) i=-1;
642                 ciphernum=i;
643                 if (ciphernum==-1) {
644                     PRINTERR("No such cipher.");
645                     return(-1);
646                 }
647                 break;
648             case 'l':
649                 PRINT_LINE; fprintf(stderr, "dact: Num | Name\n");
650                 for (i=0;i<255;i++) {
651                     if (algorithms[i]==NULL || algorithms[i]==DACT_FAILED_ALGO) continue;
652                     PRINT_LINE; fprintf(stderr, "dact: %3i | %s\n",i,algorithm_names[i]);
653             
654                 }
655                 mode=DACT_MODE_RET;
656                 break;
657             case 'I':
658                 x=atoi(optarg);
659                 for (i=1;i<255;i++) {
660                     if (i!=x) algorithms[i]=NULL;
661                 }
662                 break;
663             case 'V':
664                 printf("DACT %i.%i.%i-%s", DACT_VER_MAJOR, DACT_VER_MINOR, DACT_VER_REVISION, DACT_VER_SUB);
665 #if defined(__DATE__) && defined(__TIME__)
666                 printf("  built on %s at %s",__DATE__,__TIME__);
667 #endif
668 #ifdef DACT_CONTACT
669                 printf(" %s",DACT_CONTACT);
670 #endif
671                 printf("\n");
672                 return(0);
673                 break;
674             case 'u':
675                 dact_hdr_ext_regs(DACT_HDR_URL, optarg, strlen(optarg));
676                 break;
677             case 'U':
678                 dact_hdr_ext_regs(DACT_HDR_URLFILE, optarg, strlen(optarg));
679                 break;
680             case 'D':
681                 dact_hdr_ext_regs(DACT_HDR_DESC, optarg, strlen(optarg));
682                 break;
683             case 'T':
684                 options[DACT_OPT_TIME]=!options[DACT_OPT_TIME];
685                 break;
686             case 'P':
687                 options[DACT_OPT_PERM]=!options[DACT_OPT_PERM];
688                 break;
689             case 'O':
690                 options[DACT_OPT_ORIG]=!options[DACT_OPT_ORIG];
691                 break;
692             case 'S':
693                 options[DACT_OPT_SZSPD]=!options[DACT_OPT_SZSPD];
694                 break;
695             case '?':
696             case ':':
697             case 'h':
698                 return(print_help(argc,argv));
699         }
700 
701     }
702 
703 /* 
704  * Check for a new version of DACT 
705  */
706     if ((i=dact_upgrade_file_checkver("dact", DACT_BIN_URL_VER, options))>DACT_BIN_VER) {
707         PRINTERR("**+");
708         PRINTERR("**> There is a new version of DACT available.");
709         PRINTERR("**>");
710         PRINT_LINE; fprintf(stderr, "dact: **> [CURR: DACT %i.%i.%i]\n",DACT_VER_MAJOR, DACT_VER_MINOR,
	DACT_VER_REVISION);
711         PRINT_LINE; fprintf(stderr, "dact: **> [NEW:  DACT %i.%i.%i]\n",i>>16,(i>>8)&0xff,i&0xff);
712         PRINTERR("**>");
713         PRINTERR("**> Run `dact -N' to get it.");
714         PRINTERR("**> or get the source at: http://www.rkeene.org/devel/dact.tar.gz");
715         PRINTERR("**>");
716         PRINTERR("**-");
717     }
718 
719     if (mode==DACT_MODE_RET) return(0);
720 
721     in_files=&argv[optind];
722 
723 /* Loop through extra parameters (files ...) and setup FDs for them */
724     do {
725         in_fd=-1;
726         out_fd=-1;
727 
728         in_file=in_files[filecnt];
729         if (in_file!=NULL) {
730 /* Determine resulting file name */
731             if (out_file==NULL) out_file=dact_getoutfilename(in_file,mode);
732             if (strcmp("-",in_file)==0) {
733                 in_fd=STDIN_FILENO;
734             } else {
735                 if (stat(in_file, &stat_buf)>=0) {
736                     if (S_ISDIR(stat_buf.st_mode)) {
737                         fprintf(stderr, "dact: %s is a directory.\n",in_file);
738                         continue;
739                     }
740                 }
741                 if ((in_fd=open_net(in_file, O_RDONLY, 0))<0) {
742                     fprintf(stderr, "dact: Can't open %s.\n",in_file);
743                     PERROR_L(in_fd, "open");
744                     continue;
745                 }
746             }
747             if (out_file!=NULL) {
748                 if (!strcmp("-",out_file)) options[DACT_OPT_STDOUT]=1;
749 /*
750  *
751  * This is a bad thing if this program is SUID root, which it NEVER EVER 
752  * should be.
753  *
754  *  DO NOT MAKE DACT SUID ROOT OR YOU WILL BE HACKED
755  * 
756  * that should be a suffcient warning.
757  * (this is a mere race condition, but a severe warning should prevent
758  *  people from complaining about it to me.)
759  *
760  */
761                 if (access(out_file,F_OK)!=-1 && options[DACT_OPT_FORCE]==0 && options[DACT_OPT_STDOUT]==0) {
762                     fprintf(stderr, "dact: %s exists.\n",out_file);
763                     close(in_fd);
764                     continue;
765                 }
766                 if (!options[DACT_OPT_STDOUT]) {
767                     if ((out_fd=open_net(out_file,O_WRONLY|O_CREAT|O_TRUNC,0644))<0) {
768                         fprintf(stderr, "dact: Can't open %s for writing.\n",out_file);
769                         PERROR_L(out_fd, "open");
770                         continue;
771                     }
772                 }
773             }
774             if (options[DACT_OPT_STDOUT]) out_fd=STDOUT_FILENO;
775         }
776 
777 /* Use STDIN/STDOUT if no files specified ... unless an outfile was specified... */
778         if (in_file==NULL && filecnt==0) {
779 /* ... But only if STDOUT isn't a terminal */
780             if (isatty(STDOUT_FILENO) && options[DACT_OPT_FORCE]==0) {
781                 fprintf(stderr, "dact: Refusing to write compressed output to a terminal.\n");
782             } else {
783                 out_fd=STDOUT_FILENO;
784                 in_fd=STDIN_FILENO;
785             }
786         }
787 
788 /* Okay, we're all done, now pass these to something to do the real stuff */
789         if (in_fd!=-1 && (out_fd!=-1 || mode==DACT_MODE_STAT)) {
790             crcs[1]=crcs[0]=0;
791             if (dact_process_file(in_fd, out_fd, mode, options, in_file, crcs, dact_blk_size, ciphernum)==0) {
792                 close(in_fd);
793                 close(out_fd);
794                 if (out_fd!=STDOUT_FILENO) {
795                     unlink(out_file);
796                 }
797                 return(dact_shutdown(-1));
798             }
799         }
800 /* Cleanup */
801         if (out_fd!=-1) close(out_fd);
802         if (in_fd!=-1) close(in_fd);
803     } while (in_files[filecnt++]!=NULL);
804 
805     return(dact_shutdown(0));
806 }
4576912 [rkeene@sledge /home/rkeene/devel/dact-0.8.37]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2004-04-04 07:01:51