home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************/
- /* LSTARC.C - This program gives you a quick and easy display of the */
- /* contents of and .ARC file. It will show you the member name, */
- /* extracted file size, and the creation date. Also displayed is the */
- /* total disk space ALL of the members will take if extracted. And */
- /* the program will tell you which program will be needed to extract */
- /* the members ( ARC or PKXARC). */
- /* */
- /* Richard Nichols */
- /* CIS : [7134,3607] */
- /* This was edited with TABS set to 8, Using Turbo C version 1.0 */
- /* */
- /************************************************************************/
-
- #include <stdio.h>
-
- #define MARK 0x1A /* This marks the beginning of a header. */
-
- /************************************************************************/
- /* We use this array to convert the month from its numeric value */
- /* to one easier on the eye. */
- /************************************************************************/
- char *months[] = {
- "Jan", "Feb", "Mar", "Apr",
- "May", "Jun", "Jul", "Aug",
- "Sep", "Oct", "Nov", "Dec"
- };
-
- /************************************************************************/
- /* This is the internal member header format used by ARC and PKARC. */
- /************************************************************************/
- struct arc_ent {
- char comp; /* Compression Type (see do_name) */
- char name[13]; /* Filename */
- long arc_size; /* File size in .ARC */
- unsigned int date; /* Creation Date for member file */
- unsigned int time; /* Creation Time for member file */
- unsigned int crc; /* CRC */
- long file_size; /* Actual File Size when Extracted */
- }*entry;
-
- char fname[64]; /* Full filename (with path) */
- FILE *in_file; /* File pointer to .ARC file */
-
- int ch; /* Used when looking for header mark */
- int count = 0; /* Number of members found in the .ARC */
- int c_line = 0; /* Current line count for screen pause */
- int de_arc = 0; /* 0 = ARC, 1 = PKXARC */
- long t_size = 0L; /* Size of ALL members when extracted */
-
- main(int argc, char *argv[])
- {
-
- if(argc < 1)
- {
- printf("Syntax:\n\t%s Filename\n",argv[0]);
- exit(1);
- }
- strcpy(fname, argv[1]);
-
- /************************************************************************/
- /* Now Check the Filename for an extension. All we care about is the */
- /* '.' if we find one we assume a full filename and if not we add the */
- /* ".ARC" extension. So if you have archives that do not end with the */
- /* standard ".ARC" extension you must enter the entire filename. If it */
- /* does not have an extension the be sure to put a '.' at the end of */
- /* the filename. Also remember you can enter the entire path name if */
- /* you wish (63 characters max). */
- /************************************************************************/
- if(strchr(fname,'.') == NULL)
- strcat(fname,".ARC");
-
- /************************************************************************/
- /* Make the filename all Uppercase so the display looks nice. */
- /************************************************************************/
- strupr(fname);
-
- /************************************************************************/
- /* Try to open the file. If we fail tell the operator and show the */
- /* filename we used (incase the operator entered the wrong drive or */
- /* name) the exit back to DOS. */
- /************************************************************************/
- if((in_file = fopen(fname,"rb")) == NULL)
- {
- printf("Sorry, could not find %s\n", fname);
- exit(2);
- }
-
- /************************************************************************/
- /* Now Display the header and get to work! */
- /************************************************************************/
- printf("\nARC Directory for : %-13s",fname);
- printf("\nMember Name Actual Size Creation Date");
- while(( ch = fgetc( in_file)) != EOF )
- {
- if(ch == MARK)
- do_name();
- }
- printf("\n ==== ========");
- printf("\nTotal %4d %8ld\n",count, t_size);
-
- /************************************************************************/
- /* Now tell the operator what program(s) can be used to extract the */
- /* members. */
- /************************************************************************/
- if(de_arc)
- printf("You MUST use PKXARC on this Archive.\n");
- else
- printf("You May use ARC or PKXARC on this Archive.\n");
-
- /************************************************************************/
- /* Close the file and return to DOS. */
- /************************************************************************/
- fclose(in_file);
- }
-
- /************************************************************************/
- /* After we have found what we think is a valid header mark we come */
- /* here to get the actual information about the file. If the header */
- /* does not contain what ARC and PKARC considers a valid compression */
- /* style flag we return. If we find a valid flag we get the information */
- /* we are going to display and skip to the end of the member. */
- /************************************************************************/
- do_name()
- {
- static int val;
- static int month;
- static int day;
- static int year;
- static char s_date[12];
-
- /************************************************************************/
- /* Read in what we think is the member's header. */
- /************************************************************************/
- val = fread(entry, sizeof( struct arc_ent),1,in_file);
-
- /************************************************************************/
- /* Check the entry, if it is not between 1 to 9 then it isn't valid. */
- /* */
- /* These are the valid compression types and their meanings. I will not */
- /* go it to a detailed explaination of each type here. */
- /* */
- /* 1 = Old, no compression */
- /* 2 = New, no compression */
- /* 3 = DLE for repeat chars */
- /* 4 = Huffman encoding */
- /* 5 = LZ, no CRC */
- /* 6 = LZ with CRC */
- /* 7 = Internal SEA use */
- /* 8 = New lz with crc */
- /* 9 = PK squashing */
- /* */
- /************************************************************************/
- if((entry->comp > 9) || (entry->comp < 1))
- return;
-
- /************************************************************************/
- /* Check to see if ARC or PKARC is needed to de-ARC the Archive. */
- /************************************************************************/
- if(entry->comp == 9)
- de_arc = 1; /* Signal PKXARC Only */
-
- /************************************************************************/
- /* Increment the member count. */
- /************************************************************************/
- count++;
-
- /************************************************************************/
- /* Now get the Creation Date. This information is stored in the DOS */
- /* format. So we do Shifting and ANDing to get to the bit fileds we */
- /* want. You could also extract the Time information from the Time */
- /* entry in the structure if you wanted. */
- /************************************************************************/
- day = entry->date & 0x1F;
- month = (entry->date >>5) &0x0F;
- year = ((entry->date >> 9) &0x7F) +80;
-
- /************************************************************************/
- /* Now put the date information into a string to be displayed. This */
- /* information could be combined into the printf line below instead. */
- /************************************************************************/
- sprintf(s_date, "%2d %3s %2d",day, months[month-1], year);
-
- /************************************************************************/
- /* Don't forget the file size! This is NOT the size of the member, it */
- /* the size of the file AFTER it is extracted from the Archive. */
- /************************************************************************/
- t_size += entry->file_size;
-
- /************************************************************************/
- /* Now Dispaly the Information using the same display format as ARC. */
- /************************************************************************/
- printf("\n%-13s %9ld\t\t%s", entry->name, entry->file_size, s_date);
-
- /************************************************************************/
- /* ARC does not pause when displaying the members, but I like to pause */
- /* after a screen full. */
- /************************************************************************/
- c_line++;
- if(c_line > 23)
- {
- c_line = 0;
- printf("\nPress Any Key for More...");
- getch();
- }
-
- /************************************************************************/
- /* Since we have displayed the information now we want to skip past the */
- /* actual file. So we tell DOS to do a FAST seek from the current file */
- /* location to the actual end of the file data. This will put us at the */
- /* beginning of the next header (or the end of the file) so we can */
- /* continue working. */
- /************************************************************************/
- val = fseek(in_file, entry->arc_size, SEEK_CUR);
- }