2674507 [rkeene@sledge /home/rkeene/devel/dact]$ cat -n dact_common.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 #define __DACT_C
 23 #include <fcntl.h>
 24 #include <stdio.h>
 25 #include <ctype.h>
 26 #ifdef HAVE_UNISTD_H
 27 #include <unistd.h>
 28 #endif
 29 #ifdef HAVE_STDLIB_H
 30 #include <stdlib.h>
 31 #endif
 32 #ifdef HAVE_STRING_H
 33 #include <string.h>
 34 #endif
 35 #ifdef HAVE_SYS_STAT_H
 36 #include <sys/stat.h>
 37 #endif
 38 #ifdef HAVE_SYS_WAIT_H
 39 #include <sys/wait.h>
 40 #endif
 41 #ifdef HAVE_SYS_TYPES_H
 42 #include <sys/types.h>
 43 #endif
 44 #include "parse.h"
 45 #include "dendian.h"
 46 #include "crc.h"
 47 #include "math.h"
 48 #include "dact_common.h"
 49 #include "algorithms.h"
 50 #include "ciphers.h"
 51 #include "module.h"
 52 #include "header.h"
 53 #include "parse.h"
 54 #include "net.h"
 55 #include "ui.h"
 56 #ifdef HAVE_ZLIB_H
 57 #include <zlib.h>
 58 #endif
 59 #ifdef HAVE_BZLIB_H
 60 #include <bzlib.h>
 61 #endif
 62 
 63 int dact_config_execute(const char *cmd, char *options, uint32_t *blksize) {
 64     char *line=NULL, *line_s, *item_buf[4]={NULL, NULL, NULL, NULL};
 65     int i;
 66 
 67     line_s=line=strdup(cmd);
 68     if (line[0]=='#') return(0);
 69     while (line[strlen(line)-1]<32) line[strlen(line)-1]='\0';
 70     for (i=0;i<4;i++) item_buf[i]=NULL;
 71     for (i=0;i<4;i++) {
 72         if ((item_buf[i]=strsep(&line, "\t "))==NULL)  break;
 73         if (item_buf[i][0]==0) i--;
 74     }
 75     if (item_buf[0]==NULL || item_buf[1]==NULL) return(0); /* This means all commands must have arguments. */
 76 
 77     switch (ELFCRC(0, item_buf[0], strlen(item_buf[0]))) {
 78         case 164209419: /* binary_check */
 79             options[DACT_OPT_BINCHK]=!!strcmp(item_buf[1],"off");
 80             break;
 81         case 9456603: /* version_check */
 82             options[DACT_OPT_VERCHK]=!!strcmp(item_buf[1],"off");
 83             break;
 84         case 204349618: /* module_dir */
 85             if ((sizeof(moduledirectory)-strlen(moduledirectory)-1)<=0) break;
 86             strncat(moduledirectory,":",sizeof(moduledirectory)-strlen(moduledirectory)-1);
 87             strncat(moduledirectory,item_buf[1],sizeof(moduledirectory)-strlen(moduledirectory)-1);
 88             break;
 89         case 247248556: /* module_load_all */
 90             if (strcmp(item_buf[1], "on")==0) {
 91                 init_modules();
 92                 load_modules_all(options);
 93             }
 94             break;
 95         case 48402100:  /* module_load */
 96         case 106360197: /* load_module */
 97             init_modules();
 98             load_module(item_buf[1], options);
 99             break;
100         case 164097267: /* network_access */
101 #ifndef NO_NETWORK
102             dact_nonetwork=!strcmp(item_buf[1],"off");
103 #endif
104             break;
105         case 209445231: /* exclude_algo */
106             i=(atoi(item_buf[1])&0xff);
107             algorithms[i]=DACT_FAILED_ALGO;
108             break;
109         case 168825941: /* block_size */
110             if (blksize!=NULL) {
111                 *blksize=atoi2(item_buf[1]);
112             }
113             break;
114         case 162975987: /* use_urls */
115             options[DACT_OPT_URL]=!!strcmp(item_buf[1],"off");
116             break;
117         case 104235033: /* color_ui */
118             dact_ui_setopt(DACT_UI_OPT_COLOR,!!strcmp(item_buf[1],"off"));
119             break;
120         case 164800901: /* module_upgrade */
121             if (strcmp(item_buf[1],"on")==0) options[DACT_OPT_UPGRADE]=1;
122             break;
123         case 63160590: /* pass_use_stdin */
124         case 191551086: /* use_stdin */
125             dact_ui_setopt(DACT_UI_OPT_PASSSTDIN, 1);
126             break;
127 #ifdef DEBUG
128         default:
129             fprintf(stderr, "Unknown command %s (%i)\n",item_buf[0],ELFCRC(0,item_buf[0],strlen(item_buf[0])));
130             break;
131 #endif
132     }
133     free(line_s);
134     return(1);
135 }
136 
137 void dact_config_loadfile(const char *path, char *options, uint32_t *blksize) {
138     char *line=NULL;
139     FILE *cfd;
140 
141     line=malloc(512);
142     if ((cfd=fopen(path,"r"))==NULL) return;
143     while (!feof(cfd)) {
144         fgets(line, 511, cfd);
145         dact_config_execute(line, options, blksize);
146     }
147     free(line);
148     fclose(cfd);
149 }
150 
151 uint32_t dact_blk_decompress(char *ret, const char *srcbuf, const uint32_t size, const char *options, const int algo,
	uint32_t bufsize) {
152     uint32_t retval;
153 
154     if (algo==0xff) return(0);
155 
156     if (algorithms[algo]==NULL) {
157         PRINTERR("Algorithm unavailble.");
158         return(0);
159     }
160 
161     retval=algorithms[algo](DACT_MODE_DECMP, NULL, srcbuf, ret, size, bufsize);
162 
163     return(retval);
164 }
165 
166 
167 uint32_t dact_blk_compress(char *algo, char *ret, const char *srcbuf, const uint32_t size, const char *options, uint32_t
	bufsize) {
168     char *tmpbuf, *smallbuf=NULL;
169     int i, highest_algo=0;
170     char smallest_algo;
171     uint32_t smallest_size=-1, x;
172 #ifndef DACT_UNSAFE
173     char *verif_bf=NULL;
174     uint32_t m;
175     if ((verif_bf=malloc(size))==NULL) { PERROR("malloc"); return(0); }
176 #endif
177 
178     if ((tmpbuf=malloc(bufsize))==NULL) { PERROR("malloc"); return(0); }
179 
180     for (i=0;i<256;i++) {
181         if (algorithms[i]!=NULL && algorithms[i]!=DACT_FAILED_ALGO) highest_algo=i;
182     }
183 
184     for (i=0;i<=highest_algo;i++) {
185         if (algorithms[i]!=NULL && algorithms[i]!=DACT_FAILED_ALGO) {
186             x=algorithms[i](DACT_MODE_COMPR, NULL, srcbuf, tmpbuf, size, bufsize);
187 #ifndef DACT_UNSAFE
188             if ((x<smallest_size || smallest_size==-1) && x!=-1) {
189                 m=algorithms[i](DACT_MODE_DECMP, NULL, tmpbuf, verif_bf, x, size);
190                 if (memcmp(verif_bf, srcbuf,m) || m!=size) {
191                     x=-1;
192                     if (options[DACT_OPT_COMPLN]) {
193                         dact_ui_status(DACT_UI_LVL_ALL, "Compression verification failed (ignoring)");
194                     }
195                 }
196             }
197 #endif
198             if ((x<smallest_size || smallest_size==-1) && x!=-1) {
199                 smallest_size=x;
200                 smallest_algo=i;
201                 if (smallbuf!=NULL) free(smallbuf);
202                 if ((smallbuf=malloc(smallest_size))==NULL) { 
203                     PERROR("malloc");
204                     free(tmpbuf);
205 #ifndef DACT_UNSAFE
206                     free(verif_bf);
207 #endif
208                     return(0);
209                 }
210                 memcpy(smallbuf, tmpbuf, smallest_size);
211             }
212 
213             if (options[DACT_OPT_VERB]>2) {
214                 PRINT_LINE; fprintf(stderr, "dact: \033[%im----| %03i  | %-7i | %s\033[0m\n", (smallest_algo==i)*7 , i,
	x, algorithm_names[i]);
215             }
216 
217         }
218     }
219 
220     free(tmpbuf);
221 #ifndef DACT_UNSAFE
222     free(verif_bf);
223 #endif
224     if (smallest_size==-1) {
225         return(0);
226     }
227     memcpy(algo, &smallest_algo, sizeof(char));
228     memcpy(ret, smallbuf, smallest_size);
229 /* This was MISSING !  memory leak. */
230     free(smallbuf);
231     return(smallest_size);
232 }
233 
234 uint32_t dact_process_file(const int src, const int dest, const int mode, const char *options, const char *filename,
	uint32_t *crcs, uint32_t dact_blksize, int cipher) {
235     struct stat filestats;
236     FILE *extd_urlfile;
237     char *file_extd_urls[256];
238     unsigned char algo;
239     char ch;
240     char *in_buf, *out_buf, *hdr_buf, *keybuf=NULL, *tmpbuf=NULL;
241     char version[3]={DACT_VER_MAJOR, DACT_VER_MINOR, DACT_VER_REVISION};
242     char file_opts=0;
243     uint32_t bytes_read, retsize;
244     uint32_t filesize=0, blk_cnt=0, file_extd_size=0, blksize=0, fileoutsize=0, out_bufsize=0;
245     uint32_t magic=0, file_extd_read=0, file_extd_urlcnt=0;
246     int blksize_size;
247     int x=0, new_fd, canlseek=0;
248 
249     fstat(src,&filestats);
250 
251     if (mode==DACT_MODE_COMPR) {
252 /*
253  * Calculate the default block size.
254  */
255         blksize=dact_blksize;
256         if (blksize==0) {
257             blksize=dact_blksize_calc(filestats.st_size);
258         }
259         out_bufsize=blksize*2;
260         if (((in_buf=malloc(blksize))==NULL) || \
261             ((out_buf=malloc(out_bufsize))==NULL)) {
262                 PERROR("malloc");
263                 return(0);
264         }
265 
266         dact_ui_setup(((float) (filestats.st_size/blksize)+0.9999));
267         if (cipher!=-1) {
268             dact_hdr_ext_regn(DACT_HDR_CIPHER, cipher, sizeof(cipher));
269             keybuf=malloc(DACT_KEY_SIZE);
270             ciphers[cipher](NULL, NULL, 0, keybuf, DACT_MODE_CINIT+DACT_MODE_CENC);
271             
272         }
273         blksize_size=BYTESIZE(blksize);
274 
275         if (!options[DACT_OPT_ORIG] && filename!=NULL)
276             dact_hdr_ext_regs(DACT_HDR_NAME, filename, strlen(filename));
277         file_extd_size=(dact_hdr_ext_size()+14); /* The +14 is for crc0 and crc1 */
278         write_de(dest, DACT_MAGIC_NUMBER, 4);
279         write(dest, &version[0], 1);
280         write(dest, &version[1], 1);
281         write(dest, &version[2], 1);
282         write_de(dest, 0, 4); /* Place holder for ORIG FILE SIZE */
283         write_de(dest, 0, 4); /* Place holder for NUM BLOCKS */
284         write_de(dest, blksize, 4);
285         write_de(dest, file_opts, 1); /* XXX: Option byte... Or not? */
286         write_de(dest, file_extd_size, 4); /* Place holder for SIZEOF EXTENDED DTA */
287 /* Fill the header with NOPs incase we can't come back and put the CRCs */
288         ch=DACT_HDR_NOP;
289         for (x=0;x<file_extd_size;x++) write(dest, &ch, 1);
290 
291         if (options[DACT_OPT_VERB]>1) {
292             PRINTERR("Blk | Algo | Size    | Name");
293             PRINTERR("----+------+---------+---------------------------");
294         }
295 
296         memset(in_buf, 0, blksize);
297         while ( (bytes_read=read_f(src, in_buf, blksize))>0) {
298             filesize+=bytes_read;
299             blk_cnt++;
300 
301             retsize=dact_blk_compress(&algo, out_buf, in_buf, blksize, options, out_bufsize);
302 
303 /* CIPHER the data if an encryption algorithm is specified. */
304             if (cipher!=-1) {
305                 tmpbuf=malloc(retsize*2);
306                 x=ciphers[cipher](out_buf, tmpbuf, retsize, keybuf, DACT_MODE_CENC);
307                 memcpy(out_buf,tmpbuf,x);
308                 free(tmpbuf);
309             }
310 
311             if (retsize>0) {
312                 if (options[DACT_OPT_VERB]>1) {
313                     if (options[DACT_OPT_VERB]>2) {
314                         PRINTERR("^^^\\ /^^^^\\ /^^^^^^^\\ /^^^^^^^^^^^^^^^^^^^^^^^^^^");
315                     }
316                     PRINT_LINE; fprintf(stderr, "dact: %03i | %03i  | %-7i |
	%s\n",blk_cnt,algo,retsize,algorithm_names[algo]);
317                     if (options[DACT_OPT_VERB]>2) {
318                         PRINTERR("___/ \\____/ \\_______/ \\__________________________");
319                     }
320                 }
321 
322 
323                 dact_ui_incrblkcnt(1);
324                 dact_ui_status(DACT_UI_LVL_GEN, "Algorithm ");
325                 dact_ui_status_append(DACT_UI_LVL_GEN,algorithm_names[algo]);
326 
327                 crcs[0]=ELFCRC(crcs[0], out_buf, retsize);
328 /* Do not generate a CRC of the plaintext if encrypting */
329                 if (cipher==-1) {
330                     crcs[1]=ELFCRC(crcs[1], in_buf, blksize);
331                 }
332 
333                 if (!options[DACT_OPT_HDONLY]) {
334                     write(dest, &algo, 1);
335                     write_de(dest, retsize, blksize_size);
336 
337                     if (write(dest, out_buf, retsize)!=retsize) {
338                         PERROR("write");
339                         free(in_buf);
340                         free(out_buf);
341                         return(0);
342                     }
343                 }
344             } else {
345                 PRINTERR("Compression resulted in 0-byte block.");
346                 free(in_buf);
347                 free(out_buf);
348                 return(0);
349             }
350             memset(in_buf, 0, blksize);
351         }
352 
353         if (bytes_read<0) {
354             PERROR("read");
355         }
356 
357         free(in_buf);
358         free(out_buf);
359 
360         if (lseek_net(dest, 7, SEEK_SET)<0) {
361 /* If we can't rewind the stream, put magic+fileisze */
362             write_de(dest, DACT_MAGIC_PEOF, 4);
363             write_de(dest, filesize, 4);
364         } else {
365             write_de(dest, filesize, 4);
366             write_de(dest, blk_cnt, 4);
367         } 
368 
369         if (lseek_net(dest, DACT_HDR_REG_SIZE, SEEK_SET)>0) {
370             if (!options[DACT_OPT_NOCRC]) {
371                 dact_hdr_ext_regn(DACT_HDR_CRC0, crcs[0], 4);
372                 dact_hdr_ext_regn(DACT_HDR_CRC1, crcs[1], 4);
373             }
374             write(dest, dact_hdr_ext_data(), dact_hdr_ext_size());
375         }
376 
377         dact_hdr_ext_clear();
378 
379         return(filesize);
380     }
381 
382     if (mode==DACT_MODE_DECMP) {
383 
384         dact_ui_status(DACT_UI_LVL_GEN, "Decompressing.");
385 
386         dact_hdr_ext_clear();
387 
388         read_de(src, &magic, 4, sizeof(magic));
389 
390         if (magic!=DACT_MAGIC_NUMBER) {
391             dact_ui_status(DACT_UI_LVL_GEN, "Bad DACT magic, checking others...");
392             return(dact_process_other(src,dest,magic,options));
393         }
394 
395         read(src, &version[0], 1);
396         read(src, &version[1], 1);
397         read(src, &version[2], 1);
398         read_de(src, &filesize, 4, sizeof(filesize));
399         read_de(src, &blk_cnt, 4, sizeof(blk_cnt));
400         read_de(src, &blksize, 4, sizeof(blksize));
401         read(src, &file_opts, 1);
402         read_de(src, &file_extd_size, 4, sizeof(file_extd_size));
403 
404 
405 
406         while (file_extd_read<file_extd_size) {
407             x=0;
408             read(src, &ch, 1);
409             if (ch!=DACT_HDR_NOP) read_de(src, &x, 2, sizeof(x)); 
410             switch (ch) {
411                 case DACT_HDR_CRC0:
412                     read_de(src, &crcs[2], 4, sizeof(crcs[2]));
413                     if (crcs[4]!=0 && crcs[2]!=crcs[4]) {
414                         dact_ui_status(DACT_UI_LVL_GEN, "CRC error.");
415                         if (!options[DACT_OPT_NOCRC])
416                             return(0);
417                     }
418                     break;
419                 case DACT_HDR_CRC1:
420                     read_de(src, &crcs[3], 4, sizeof(crcs[3]));
421                     if (crcs[5]!=0 && crcs[3]!=crcs[5]) {
422                         dact_ui_status(DACT_UI_LVL_GEN, "CRC error.");
423                         if (!options[DACT_OPT_NOCRC])
424                             return(0);
425                     }
426                     break;
427 /*
428 
429 XXX: Todo, make this do something...
430                 case DACT_HDR_NAME:
431                     break;
432 */
433                 case DACT_HDR_URL:
434                     hdr_buf=malloc(x+1);
435                     read_f(src, hdr_buf, x);
436                     hdr_buf[x]=0;
437                     file_extd_urls[file_extd_urlcnt++]=parse_url_subst(hdr_buf,filename);
438                     free(hdr_buf);
439                     break;
440                 case DACT_HDR_URLFILE:
441                     hdr_buf=malloc(x+1);
442                     read_f(src, hdr_buf, x);
443                     hdr_buf[x]=0;
444                     extd_urlfile=fopen(hdr_buf, "r");
445                     free(hdr_buf);   /* We shouldn't need this anymore. */
446                     if (extd_urlfile==NULL) break;
447                     hdr_buf=malloc(4096);
448                     while (1) {
449                         fgets(hdr_buf, 4095, extd_urlfile);
450                         if (feof(extd_urlfile)) break;
451                         hdr_buf=strsep(&hdr_buf,"\n");
452                         file_extd_urls[file_extd_urlcnt++]=parse_url_subst(hdr_buf,filename);
453                     }
454                     free(hdr_buf);
455                     break;
456                 case DACT_HDR_DESC:
457                     hdr_buf=malloc(x+1);
458                     read_f(src, hdr_buf, x);
459                     hdr_buf[x]=0;
460                     fprintf(stderr, "DESC: %s\n",hdr_buf);
461                     free(hdr_buf);
462                     break;
463                 case DACT_HDR_CIPHER:
464                     read_de(src,&cipher,x,sizeof(cipher));
465                     break;
466                 case DACT_HDR_NOP:
467                     x=-2;
468                     break;
469                 default:
470                     hdr_buf=malloc(x);
471                     read_f(src, hdr_buf, x);
472                     free(hdr_buf);
473                     break;
474             }
475 
476 
477 
478             file_extd_read+=(x+3);
479         }
480 
481         if (options[DACT_OPT_URL]) {
482             for (x=0;x<file_extd_urlcnt;x++) {
483                 dact_ui_status(DACT_UI_LVL_GEN,"Trying to get remote url ");
484                 dact_ui_status_append(DACT_UI_LVL_SPEC, file_extd_urls[x]);
485                 if ((new_fd=open_net(file_extd_urls[x],O_RDONLY,0))<0) {
486                     dact_ui_status(DACT_UI_LVL_GEN, "Failed.");
487                     continue;
488                 }
489                 close(src);
490                 crcs[4]=crcs[2];
491                 crcs[5]=crcs[3];
492                 return(dact_process_file(new_fd, dest, mode, options, filename, crcs, blksize, cipher));
493             }
494         }
495 
496 
497 /* 
498    XXX: Even if we don't resolve it here, we can resolve it later...
499    Should we even bother to do it here if we can?
500 
501    XXX: When CAN'T we rewind a read stream?
502         When it's a pipe
503 
504 */
505         if (filesize==0) {
506 /* See if we can rewind our stream, so when we get to the end, we can come back! */
507             if (lseek_net(src, 1, SEEK_SET)==1) { /* MAJOR BUG HERE! was: lseek(src,1,SEEK_SET)==0 which will always be
	false. */
508                 canlseek=1;
509                 lseek_net(src, -8, SEEK_END);
510                 read_de(src, &magic, 4, sizeof(magic));
511                 if (magic!=DACT_MAGIC_PEOF) {
512                     dact_ui_status(DACT_UI_LVL_GEN, "File is corrupt.");
513                     return(0);
514                 }
515                 read_de(src, &filesize, 4, sizeof(filesize));
516                 lseek_net(src, DACT_HDR_REG_SIZE+file_extd_size, SEEK_SET);
517             } else {
518                 canlseek=0;
519             }
520         }
521 
522         out_bufsize=blksize;
523         if (((out_buf=malloc(out_bufsize))==NULL) ) {
524                 PERROR("malloc");
525                 return(0);
526         }
527 
528 
529         blksize_size=BYTESIZE(blksize);
530 
531         dact_ui_setup((int)(((float) filesize/(float) blksize)+0.9999));
532 
533         if (cipher!=-1) {
534             keybuf=malloc(DACT_KEY_SIZE);
535             ciphers[cipher](NULL, NULL, 0, keybuf, DACT_MODE_CINIT+DACT_MODE_CDEC);
536             
537         }
538 
539 
540 
541         while (1) {
542             if (read(src, &algo, 1)==0) break;
543             if (algo==0xff) break; /* 0xff is reserved for EOF */
544 
545             read_de(src, &blksize, blksize_size, sizeof(blksize));
546 
547             if ((in_buf=malloc(blksize))==NULL) {
548                 PERROR("malloc");
549                 free(out_buf);
550                 return(0);
551             }
552 
553             read_f(src, in_buf, blksize);
554 
555             crcs[0]=ELFCRC(crcs[0],in_buf,blksize);
556 
557             if (cipher!=-1) {
558                 tmpbuf=malloc(blksize*2);
559                 x=ciphers[cipher](in_buf, tmpbuf, blksize, keybuf, DACT_MODE_CDEC);
560                 memcpy(in_buf,tmpbuf,x);
561                 free(tmpbuf);
562             }
563 
564 /*
565  * If the filesize is not specified, try to find it in the stream...
566  * this is pretty stupid, because if we can't rewind OUR read stream
567  * we're SOL... do we really need the filesize that badly?  I guess
568  * we do to truncate the last of it...  Adding more checks in here..
569  *
570  * This will never get used, canlseek will be 1 only if we can sucessfully
571  * seek, in which case, we have done it above.
572  */
573 #if 0
574             if (filesize==0 && canlseek) {
575                 read_de(src, &magic, 4);
576                 read_de(src, &filesize, 4);
577                 if (read(src, &x, 1)==0) {
578                     if (magic!=DACT_MAGIC_PEOF) {
579                         dact_ui_status(DACT_UI_LVL_GEN, "Stream is corrupt.");
580                         free(in_buf);
581                         free(out_buf);
582                         return(0);
583                     }
584                 } else {
585                     lseek(src, -9, SEEK_CUR);
586                     filesize=0;
587                 }
588             }
589 #endif
590 
591 
592             if ((bytes_read=dact_blk_decompress(out_buf, in_buf, blksize, 0, algo, out_bufsize))==0) {
593                 if (cipher!=-1) {
594                     PRINTERR("Decompression resulted in 0-byte block.  Invalid key?");
595                 } else {
596                     PRINTERR("Decompression resulted in 0-byte block.");
597                 }
598             }
599             fileoutsize+=bytes_read;
600 
601 /* If ciphering, don't try to calculate this CRC. */
602             if (cipher==-1) {
603                 crcs[1]=ELFCRC(crcs[1],out_buf,bytes_read);
604             }
605 
606             dact_ui_incrblkcnt(1);
607 
608             if (fileoutsize>filesize && filesize!=0) {
609                 write(dest, out_buf, blksize-(fileoutsize-filesize));
610             } else {
611                 write(dest, out_buf, bytes_read);
612             }
613 
614 
615 
616             free(in_buf);
617 
618             
619         }
620 
621         free(out_buf);
622 
623         if ((crcs[0]!=crcs[2] && crcs[0]!=0 && crcs[2]!=0) \
624           || (crcs[1]!=crcs[3] && crcs[1]!=0 && crcs[3]!=0)) {
625             dact_ui_status(DACT_UI_LVL_GEN, "CRC error.");
626             if (!options[DACT_OPT_NOCRC] || options[DACT_OPT_FORCE]<1)
627                 return(0);
628         }
629 
630         dact_hdr_ext_clear();
631 
632         return(filesize);
633 
634     }
635 
636 
637     if (mode==DACT_MODE_STAT) {
638         read_de(src, &magic, 4, sizeof(magic));
639         read(src, &version[0], 1);
640         read(src, &version[1], 1);
641         read(src, &version[2], 1);
642         read_de(src, &filesize, 4, sizeof(filesize));
643         read_de(src, &blk_cnt, 4, sizeof(blk_cnt));
644         read_de(src, &blksize, 4, sizeof(blksize));
645         read(src, &file_opts, 1);
646         read_de(src, &file_extd_size, 4, sizeof(file_extd_size));
647 
648         printf("File              :   %s\n", filename);
649         printf("Magic             :   0x%08x",magic);
650         if (magic!=DACT_MAGIC_NUMBER) {
651             printf(" (bad magic)\n");
652             return(0);
653         } else {
654             printf("\n");
655         }
656 
657         if (filesize==0) {
658             lseek_net(src, -8, SEEK_END);
659             read_de(src, &magic, 4, sizeof(magic));
660             read_de(src, &filesize, 4, sizeof(filesize));
661             if (magic!=DACT_MAGIC_PEOF) {
662                 PRINTERR("Bad magic, corrupt stream.");
663                 return(0);
664             }
665         }
666         fileoutsize=lseek_net(src, 0, SEEK_END);
667 
668         printf("Dact Version      :   %i.%i.%i\n",version[0],version[1],version[2]);
669         printf("Block Size        :   %i\n", blksize);
670         printf("Block Header Size :   %i\n", BYTESIZE(blksize)+1);
671         printf("Compressed Size   :   %i\n", fileoutsize);
672         printf("Uncompressed Size :   %i\n", filesize);
673         printf("Ratio             :   %2.3f to 1.0\n", ((float) filesize)/((float) fileoutsize) );
674         lseek_net(src, DACT_HDR_REG_SIZE, SEEK_SET);
675         while (file_extd_read<file_extd_size) {
676             x=0;
677             read(src, &ch, 1);
678             if (ch!=DACT_HDR_NOP) read_de(src, &x, 2, sizeof(x)); 
679             switch (ch) {
680                 case DACT_HDR_CRC0:
681                     read_de(src, &crcs[2], 4, sizeof(crcs[2]));
682                     printf("CRC 0             :   0x%08x\n", crcs[2]);
683                     break;
684                 case DACT_HDR_CRC1:
685                     read_de(src, &crcs[3], 4, sizeof(crcs[3]));
686                     printf("CRC 1             :   0x%08x\n", crcs[3]);
687                     break;
688                 case DACT_HDR_NAME:
689                     hdr_buf=malloc(x+1);
690                     read_f(src, hdr_buf, x);
691                     hdr_buf[x]=0;
692                     printf("Original Name     :   %s\n", hdr_buf);
693                     free(hdr_buf);
694                     break;
695                 case DACT_HDR_URL:
696                     hdr_buf=malloc(x+1);
697                     read_f(src, hdr_buf, x);
698                     hdr_buf[x]=0;
699                     file_extd_urls[file_extd_urlcnt++]=parse_url_subst(hdr_buf,filename);
700                     free(hdr_buf);
701                     break;
702                 case DACT_HDR_URLFILE:
703                     hdr_buf=malloc(x+1);
704                     read_f(src, hdr_buf, x);
705                     hdr_buf[x]=0;
706                     printf("Download Loc File :   %s\n", hdr_buf);
707                     extd_urlfile=fopen(hdr_buf, "r");
708                     free(hdr_buf);   /* We shouldn't need this anymore. */
709                     if (extd_urlfile==NULL) break;
710                     hdr_buf=malloc(4096);
711                     while (1) {
712                         fgets(hdr_buf, 4095, extd_urlfile);
713                         if (feof(extd_urlfile)) break;
714                         hdr_buf=strsep(&hdr_buf,"\n");
715                         file_extd_urls[file_extd_urlcnt++]=parse_url_subst(hdr_buf,filename);
716                     }
717                     free(hdr_buf);
718                     break;
719                 case DACT_HDR_DESC:
720                     hdr_buf=malloc(x+1);
721                     read_f(src, hdr_buf, x);
722                     hdr_buf[x]=0;
723                     printf("Description       :   %s\n", hdr_buf);
724                     free(hdr_buf);
725                     break;
726                 case DACT_HDR_CIPHER:
727                     read_de(src, &cipher, x, sizeof(cipher));
728                     printf("Ciphered using    :   %s\n", ciphers_name[cipher]);
729                     break;
730                 case DACT_HDR_NOP:
731                     x=-2;
732                     break;
733                 default:
734                     hdr_buf=malloc(x);
735                     read_f(src, hdr_buf, x);
736                     free(hdr_buf);
737                     break;
738             }
739 
740 
741             file_extd_read+=(x+3);
742         }
743 
744         for (x=0;x<file_extd_urlcnt;x++) {
745             printf("Download Location :   %s",file_extd_urls[x]);
746             if (options[DACT_OPT_VERB]) {
747                 if ((new_fd=open_net(file_extd_urls[x],O_RDONLY, 0))<0) {
748                     printf(" [broken]\n");
749                     continue;
750                 }
751                 close(new_fd);
752             }
753             printf("\n");
754         }
755 
756         blk_cnt=0;
757         blksize_size=BYTESIZE(blksize);
758         if (options[DACT_OPT_VERB]) {
759             lseek_net(src, DACT_HDR_REG_SIZE+file_extd_size, SEEK_SET);
760             printf("\n");
761             printf("Break down: \n");
762             printf("  Blk | Algo | Size    | Name\n");
763             printf("  ----+------+---------+---------------------------\n");
764             while (1) {
765                 if (read(src, &algo, 1)==0) break;
766                 if (algo==0xff) break; /* 0xff is reserved for EOF */
767 
768                 read_de(src, &blksize, blksize_size, sizeof(blksize));
769                 lseek_net(src, blksize, SEEK_CUR);
770                 printf("  %03i | %03i  | %-7i | %s\n",blk_cnt,algo,blksize,algorithm_names[algo]);
771                 blk_cnt++;
772             }
773         }
774 
775         printf("\n");
776 
777 
778         return(1);
779     }
780 
781     return(0);
782 }
2674508 [rkeene@sledge /home/rkeene/devel/dact]$

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