home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 9 Archive
/
09-Archive.zip
/
testzp13.zip
/
testzip.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-04-30
|
25KB
|
721 lines
/*****************************************************************
* Testzip version 1.13 *
* Test zip file integrity, Nuke Bad Zips *
* Also prints a list of what it deleted in optional logfile. *
* *
* Programmer: Madman, with suggestions from Pantera *
* Date: 12/6/96 Version 1.0 *
* *
* Modified by: Jeff Hamilton, hjeffrey@wam.umd.edu *
* Date: 12/8/96 Version 1.01 *
* Date: 12/12/96 Version 1.02 *
* Date: 12/13/96 Version 1.03 *
* Date: 12/15/96 Version 1.04 *
* Date: 1/5/97 Version 1.1 *
* *
* Queue functions by John Dowdal (queue.c and queue.h) *
* *
* See the readme.txt included with this source code for more *
* information, and instructions for compiling and using this *
* program. *
* *
* Disclaimer: DISCLAIM THIS!!!! *
* This program and source code are distributed as is. There is *
* NO guarantee that it will work on all systems. Please test *
* it out before using. The programmers take no responsibilty *
* for lost or damaged files, or any other problems that use of *
* this software might cause. *
* *
* Bug Reports: *
* If you find a bug, please e-mail a description of your *
* operating system, what the bug does, and how to reproduce it *
* to hjeffrey@wam.umd.edu I will make every effort to find and *
* correct the bug. *
*****************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include "queue.h"
#include "testzip.h"
#ifdef OS2
#include <os2.h>
#include "which2.h"
#endif
FILE *outfile, *notefile;
config testzipcfg;
int main(int argc, char *argv[]) {
#ifdef OS2
if (_osmode != OS2_MODE) {
fprintf(stderr, "This program cannot be run in DOS mode.\n");
exit(1);
}
#endif
load_config_defaults();
read_config();
read_options(&argc, argv);
notefile = fopen("/dev/tty","w");
freopen("/dev/null","w",stdout);
freopen("/dev/null","w",stderr);
open_log();
check_a_command();
if (testzipcfg.recursive) {
recursive_check();
} else {
single_check();
}
print_totals();
if (testzipcfg.loglevel > 0)
fclose(outfile);
fclose(notefile);
fclose(stdout);
fclose(stderr);
return 0;
}
void recursive_check() {
char tempdir[MAXPATHLEN];
short int i;
queue dirq;
qeltt *elt;
struct dirent *dp;
struct stat sb;
DIR *dirp;
initq(&dirq);
addq(&dirq, testzipcfg.dir);
while(!emptyq(&dirq)) {
elt = delq(&dirq);
dirp = opendir(elt->data);
if (dirp == NULL) {
perror(elt->data);
exit(1);
}
#if defined(OS2)
_chdir2(elt->data);
#elif defined(UNIX)
chdir(elt->data);
#endif
while ((dp = readdir(dirp)) != NULL) {
if (!memcmp(dp->d_name, "..", 2) || !memcmp(dp->d_name, ".", 1))
continue;
if (stat(dp->d_name, &sb)) {
fprintf(notefile, "Error: Can't get file info. Skipping.\n");
if (testzipcfg.loglevel > 0)
fprintf(outfile, "Error: Can't get file info. Skipping.\n");
continue;
}
if (sb.st_mode >= S_IFDIR && sb.st_mode < 0050000) {
#if defined(OS2)
_getcwd2(tempdir, MAXPATHLEN);
#elif defined(UNIX)
getcwd(tempdir, MAXPATHLEN);
#endif
check_dir(tempdir);
strcat(tempdir, dp->d_name);
addq(&dirq, tempdir);
} else {
if (testzipcfg.do_all == TRUE) {
for (i = 0; i < testzipcfg.num_archivers; i++) {
testzipcfg.default_num = i;
do_archive_test(dp->d_name);
}
} else {
do_archive_test(dp->d_name);
}
}
}
closedir(dirp);
}
}
void single_check() {
short int i;
struct dirent *dp;
DIR *dirp;
dirp = opendir(testzipcfg.dir);
if (dirp == NULL) {
perror(testzipcfg.dir);
exit(1);
}
while ((dp = readdir(dirp)) != NULL) {
if (testzipcfg.do_all == TRUE) {
for (i = 0; i < testzipcfg.num_archivers; i++) {
testzipcfg.default_num = i;
do_archive_test(dp->d_name);
}
} else {
do_archive_test(dp->d_name);
}
}
closedir(dirp);
}
void do_archive_test(char filename[]) {
char tmpfilename[255], tmpcommand[255], *tmpptr, tmpdir[MAXPATHLEN];
int status;
FILE *shit;
strncpy(tmpfilename, filename, 254);
strtoupper(tmpfilename);
tmpptr = strrchr(tmpfilename, '.');
if (tmpptr && strstr(tmpptr, testzipcfg.archive[testzipcfg.default_num].extension) != NULL) {
testzipcfg.archive[testzipcfg.default_num].total_tested++;
#if defined(OS2)
_getcwd2(tmpdir, MAXPATHLEN);
#elif defined(UNIX)
getcwd(tmpdir, MAXPATHLEN);
#endif
check_dir(tmpdir);
if (testzipcfg.recursive) {
fprintf(notefile,"Testing '%s%s'", tmpdir, filename);
if (testzipcfg.loglevel > 0)
fprintf(outfile, "Testing '%s%s'", tmpdir, filename);
} else {
fprintf(notefile, "Testing '%s'", filename);
if (testzipcfg.loglevel > 0)
fprintf(outfile, "Testing '%s'", filename);
}
fflush(notefile);
/* Check for read/write permission for file to be tested */
shit = fopen(filename, "r");
if (shit == NULL) {
#if defined(OS2)
fprintf(notefile, "....File locked or in use. Skipping.\n");
if (testzipcfg.loglevel > 0)
fprintf(outfile, "....File locked or in use. Skipping.\n");
#elif defined(UNIX)
fprintf(notefile, "....Permission Denied. Skipping.\n");
if (testzipcfg.loglevel > 0)
fprintf(outfile, "....Permission Denied. Skipping.\n");
#endif
fflush(notefile);
return;
}
fclose(shit);
sprintf(tmpcommand,"%s %s\"%s\"",testzipcfg.archive[testzipcfg.default_num].command, tmpdir, filename);
if ((status = system(tmpcommand)) != 0) {
if (testzipcfg.loglevel > 0)
fprintf(outfile,"....Bad File. Status: %d\n", status);
fprintf(notefile,"....Bad File. Status: %d\n", status);
fflush(notefile);
if (testzipcfg.do_delete == TRUE) {
fprintf(notefile,"*** Deleting Bad File: '%s' Status: %d\n", filename, status);
fflush(notefile);
testzipcfg.total_del++;
if (testzipcfg.loglevel > 0)
fprintf(outfile, "*** Deleting Bad File: '%s' Status: %d\n", filename, status);
unlink(filename);
}
testzipcfg.total_bad++;
} else {
fprintf(notefile,"....Good File.\n");
fflush(notefile);
testzipcfg.total_good++;
if (testzipcfg.loglevel == 2)
fprintf(outfile, "Testing '%s'....Good File.\n", filename);
}
if (testzipcfg.loglevel > 0)
fflush(outfile);
}
}
void open_log() {
if (testzipcfg.append == TRUE && testzipcfg.overwrite == TRUE) {
fprintf(notefile, "testzip: Append (-a) and Overwrite (-o) are incompatible options. Exiting.\n");
exit(1);
}
if (testzipcfg.overwrite == TRUE)
unlink(testzipcfg.logname);
if (testzipcfg.loglevel > 0) {
if ((outfile = fopen(testzipcfg.logname,"a+")) == NULL ) {
#if READONLY_LOG
fprintf(notefile, "testzip: Can not open logfile. Disabling all logging.\n");
testzipcfg.loglevel = 0;
#else
fprintf(notefile, "testzip: Can not open logfile. Exiting.\n");
exit(1);
#endif
} else {
fprintf(outfile,"*** Begin Testing Run ***\n");
fflush(outfile);
}
}
}
void print_totals() {
short int i;
for (i = 0; i < testzipcfg.num_archivers; i++) {
if (testzipcfg.archive[i].total_tested > 0)
testzipcfg.total_tested += testzipcfg.archive[i].total_tested;
}
if (testzipcfg.total_tested == 0)
return;
fprintf(notefile, "\n");
for (i = 0; i < testzipcfg.num_archivers; i++) {
if (testzipcfg.archive[i].total_tested > 0)
fprintf(notefile, "%-4s Files: %-3d ", testzipcfg.archive[i].name, testzipcfg.archive[i].total_tested);
}
fprintf(notefile, "\n");
fprintf(notefile, "Total Files: %-3d Total Good: %-3d Total Bad: %-3d", testzipcfg.total_tested, testzipcfg.total_good, testzipcfg.total_bad);
if (testzipcfg.do_delete == TRUE)
fprintf(notefile, " Total Deleted: %-3d", testzipcfg.total_del);
fprintf(notefile, "\n");
if (testzipcfg.loglevel > 0) {
fprintf(outfile, "\n");
for (i = 0; i < testzipcfg.num_archivers; i++) {
if (testzipcfg.archive[i].total_tested > 0)
fprintf(outfile, "%-4s Files: %-3d ", testzipcfg.archive[i].name, testzipcfg.archive[i].total_tested);
}
fprintf(outfile, "\n");
fprintf(outfile, "Total Files: %-3d Total Good: %-3d Total Bad: %-3d",
testzipcfg.total_tested, testzipcfg.total_good, testzipcfg.total_bad);
if (testzipcfg.do_delete == TRUE)
fprintf(outfile, " Total Deleted: %-3d", testzipcfg.total_del);
fprintf(outfile,"\n*** End Testing Run ***\n\n");
}
}
void check_a_command() {
short int i;
int status;
char command[MAX_TEST_COMMAND], t[MAX_TEST_COMMAND];
for (i = 0; i < testzipcfg.num_archivers; i++) {
sscanf(testzipcfg.archive[i].command, "%s", command);
#if defined(OS2)
if ((status = which(command)) >= 1) {
fprintf(notefile, "Error: '%s' not recognized as an operable command. Exiting.\n", command);
exit(1);
}
#elif defined(UNIX)
strcpy(t, "which ");
strcat(t, command);
if ((status = system(t)) >= 1) {
fprintf(notefile, "Error: '%s' not recognized as on operable command. Exiting.\n", command);
exit(1);
}
#endif
}
}
void read_config() {
FILE *configfile;
char tmpstr[MAX_LINE_LEN+1], option[25], value[MAX_LINE_LEN], configpath[3][MAX_DIR_LEN + MAX_CONFIG_NAME + 2];
char *homepath, *tmp, *shit;
int i, count = 0;
#if defined(OS2)
char *testzippath;
testzippath = getenv("TESTZIP");
if (testzippath != NULL) {
strncpy(configpath[2], testzippath, MAX_DIR_LEN);
strncat(configpath[2], "/", 1);
strncat(configpath[2], CONFIG_NAME, MAX_CONFIG_NAME);
}
#elif defined(UNIX)
strncpy(configpath[2], CONFIG_PATH, MAX_DIR_LEN);
strncat(configpath[2], "/", 1);
strncat(configpath[2], CONFIG_NAME, MAX_CONFIG_NAME);
#endif
homepath = getenv("HOME");
if (homepath != NULL) {
strncpy(configpath[1], homepath, MAX_DIR_LEN);
strncat(configpath[1], "/", 1);
strncat(configpath[1], CONFIG_NAME, MAX_CONFIG_NAME);
}
strncpy(configpath[0], CONFIG_NAME, MAX_CONFIG_NAME);
for (i = 0; i < 3; i++) {
configfile = fopen(configpath[i], "r");
if (configfile != NULL)
break;
}
if (configfile == NULL) {
#if CONFIG_DEFAULTS
printf("testzip: Config File not found. Using default configuration.\n");
return;
#else
printf("testzip: Config File not found. Exiting.\n");
exit(1);
#endif
}
tmp = &tmpstr[12];
while (fgets(tmpstr, MAX_LINE_LEN, configfile) != NULL) {
if (tmpstr[0] == '#' || tmpstr[0] == '\n' || tmpstr[0] == ' ')
continue;
shit = strstr(tmpstr, "#");
if (shit != NULL)
*shit = '\0';
sscanf(tmpstr, "%24s %s", option, value);
strtoupper(option);
if (strcmp(option, "DELETE") == 0) {
if (strlen(value) > 0) {
strtoupper(value);
if (strcmp(value, "YES") == 0) {
testzipcfg.do_delete = TRUE;
} else if (strcmp(value, "NO") == 0) {
testzipcfg.do_delete = FALSE;
} else {
printf("Config Error: %s is not a valid value for option %s.\n", value, option);
exit(1);
}
} else {
printf("Config Error: %s requires a value.\n", option);
exit(1);
}
} else if (strcmp(option, "DIR") == 0) {
if (strlen(value) > 0) {
check_dir(value);
strncpy(testzipcfg.dir, value, MAX_DIR_LEN);
} else {
printf("Config Error: %s requires a value.\n", option);
exit(1);
}
} else if (strcmp(option, "LOGNAME") == 0) {
if (strlen(value) > 0) {
strncpy(testzipcfg.logname, value, MAX_LOG_NAME);
} else {
printf("Config Error: %s requires a value.\n", option);
exit(1);
}
} else if (strcmp(option, "LOGLEVEL") == 0) {
if (strlen(value) > 0) {
if (strcmp(value, "0") == 0) {
testzipcfg.loglevel = 0;
} else if (strcmp(value, "1") == 0) {
testzipcfg.loglevel = 1;
} else if (strcmp(value, "2") == 0) {
testzipcfg.loglevel = 2;
} else {
printf("Config Error: %s is not a valid value for option %s.\n", value, option);
exit(1);
}
} else {
printf("Config Error: %s requires a value.\n", option);
exit(1);
}
} else if (strcmp(option, "OVERWRITE") ==0) {
if (strlen(value) > 0) {
strtoupper(value);
if (strcmp(value, "YES") == 0) {
testzipcfg.overwrite = TRUE;
} else if (strcmp(value, "NO") == 0) {
testzipcfg.overwrite = FALSE;
} else {
printf("Config Error: \'%s\' is not a valid value for option %s.\n", value, option);
exit(1);
}
} else {
printf("Config Error: %s requires a value.\n", option);
exit(1);
}
} else if (strcmp(option, "APPEND") == 0) {
strtoupper(value);
if (strcmp(value, "YES") == 0) {
testzipcfg.append = TRUE;
} else if (strcmp(value, "NO") == 0) {
testzipcfg.append = FALSE;
} else {
printf("Config Error: \'%s\' is not a valid value for option %s.\n", value, option);
exit(1);
}
} else if (strcmp(option, "ARCHIVER") == 0) {
count++;
if (count == MAX_ARCHIVERS) {
printf("Config Error: Can not set more than %d archivers.\n", MAX_ARCHIVERS);
exit(1);
}
testzipcfg.num_archivers++;
} else if (strcmp(option, "DEFAULT") == 0) {
if (strlen(value) > 0) {
strtoupper(value);
if (strcmp(value, "YES") == 0) {
testzipcfg.default_num = count;
} else if (strcmp(value, "NO") == 0) {
;
} else {
printf("Config Error: %s is not a valid value for option %s.\n", value, option);
exit(1);
}
} else {
printf("Config Error: %s requires a value.\n", option);
exit(1);
}
} else if (strcmp(option, "NAME") == 0) {
if (strlen(value) > 0) {
strncpy(testzipcfg.archive[count].name, value, MAX_ARCHIVER_NAME);
} else {
printf("Config Error: %s requires a value.\n", option);
exit(1);
}
} else if (strcmp(option, "EXTENSION") == 0) {
strtoupper(value);
if (strlen(value) > 0) {
strncpy(testzipcfg.archive[count].extension, value, MAX_EXTENSION);
} else {
printf("Config Error: %s requires a value.\n", option);
exit(1);
}
} else if (strcmp(option, "TESTCOMMAND") == 0) {
if (strlen(value) > 0) {
strcpy(value, tmp);
value[strlen(value) - 1] = '\0';
strncpy(testzipcfg.archive[count].command, value, MAX_TEST_COMMAND);
} else {
printf("Config Error: %s requires a value.\n", option);
exit(1);
}
} else if (strcmp(option, "OPTION") == 0) {
if (value[0] != '\0') {
testzipcfg.archive[count].option = value[0];
} else {
printf("Config Error: %s requires a value.\n", option);
exit(1);
}
} else if (strcmp(option, "DOALL") == 0) {
if (strlen(value) > 0) {
strtoupper(value);
if (strcmp(value, "YES") == 0) {
testzipcfg.do_all = TRUE;
} else if (strcmp(value, "NO") == 0) {
testzipcfg.do_all = FALSE;
} else {
printf("Config Error: %s is not a valid value for option %s.\n", value, option);
exit(1);
}
}
} else if (strcmp(option, "RECURSIVE") == 0) {
if (strlen(value) > 0) {
strtoupper(value);
if (strcmp(value, "YES") == 0) {
testzipcfg.recursive = TRUE;
} else if (strcmp(value, "NO") == 0) {
testzipcfg.recursive = FALSE;
} else {
printf("Config Error: %s is not a valid value for option %s.\n", value, option);
exit(1);
}
}
} else {
printf("Config Error: Unrecognized option: %s", option);
exit(1);
}
}
fclose(configfile);
}
void load_config_defaults()
{
testzipcfg.do_delete=FALSE;
testzipcfg.do_all=TRUE;
testzipcfg.recursive=FALSE;
testzipcfg.loglevel=1;
testzipcfg.overwrite=FALSE;
testzipcfg.append=TRUE;
testzipcfg.default_num=0;
testzipcfg.num_archivers=1;
strncpy(testzipcfg.dir, ".", MAX_DIR_LEN);
strncpy(testzipcfg.logname, "testzip.log", MAX_LOG_NAME);
testzipcfg.archive[0].option='z';
strncpy(testzipcfg.archive[0].name, "Zip", MAX_ARCHIVER_NAME);
strncpy(testzipcfg.archive[0].extension, ".ZIP", MAX_EXTENSION);
strncpy(testzipcfg.archive[0].command, "unzip -t", MAX_TEST_COMMAND);
}
void print_config()
{
short int i;
printf("Testzip %s Configuration\n\n(1 = True 0 = False)\n", TZ_VERSION);
printf("delete = %d\n", testzipcfg.do_delete);
printf("test all = %d\n", testzipcfg.do_all);
printf("recursive checking = %d\n", testzipcfg.recursive);
printf("overwrite = %d\n", testzipcfg.overwrite);
printf("append = %d\n\n", testzipcfg.append);
printf("loglevel = %d\n", testzipcfg.loglevel);
printf("default archiver = %s\n", testzipcfg.archive[testzipcfg.default_num].name);
printf("number of archivers = %d\n", testzipcfg.num_archivers);
printf("dir = %s\n", testzipcfg.dir);
printf("logname = %s\n", testzipcfg.logname);
for (i = 0; i < testzipcfg.num_archivers; i++) {
if (i % 4 == 0) {
printf("\nPress Enter to continue...");
getchar();
}
printf("\nname = %s\n", testzipcfg.archive[i].name);
printf("extension = %s\n", testzipcfg.archive[i].extension);
printf("command = %s\n", testzipcfg.archive[i].command);
printf("option = %c\n", testzipcfg.archive[i].option);
}
}
void strtoupper(char *string)
{
int i;
for (i = 0; i < strlen(string); i++)
string[i] = toupper(string[i]);
}
void check_dir(char *string)
{
int i;
for (i = 0; i < strlen(string); i++) {
if (string[i] == '\\')
string[i] = '/';
}
if (string[strlen(string) - 1] != '/')
strcat(string, "/");
}
void read_options(int *argc, char *argv[])
{
short int i, options;
Bool done = FALSE;
extern char *optarg;
while ((options = getopt(*argc, argv, "?hvDdEeRraol:f:c:t:p")) != EOF)
{
switch(options)
{
case 'D':
testzipcfg.do_delete = TRUE;
break;
case 'd':
testzipcfg.do_delete = FALSE;
break;
case 'E':
testzipcfg.do_all = TRUE;
break;
case 'e':
testzipcfg.do_all = FALSE;
break;
case 'R':
testzipcfg.recursive = TRUE;
break;
case 'r':
testzipcfg.recursive = FALSE;
break;
case 't':
strncpy(testzipcfg.dir, optarg, MAX_DIR_LEN);
check_dir(testzipcfg.dir);
break;
case 'l':
if (optarg[0] == '0') {
testzipcfg.loglevel = 0;
break;
} else if (optarg[0] == '1') {
testzipcfg.loglevel = 1;
break;
} else if (optarg[0] == '2') {
testzipcfg.loglevel = 2;
break;
} else {
fprintf(stderr, "testzip: Illegal argument for the '-l' option.\n\n");
exit(1);
break;
}
break;
case 'f':
strncpy(testzipcfg.logname, optarg, MAX_LOG_NAME);
break;
case 'a':
testzipcfg.append = TRUE;
testzipcfg.overwrite = FALSE;
break;
case 'o':
testzipcfg.append = FALSE;
testzipcfg.overwrite = TRUE;
break;
case 'c':
for (i = 0; i < testzipcfg.num_archivers; i++) {
if (optarg[0] == testzipcfg.archive[i].option) {
testzipcfg.default_num = i;
done = TRUE;
}
}
if (done == FALSE) {
fprintf(stderr, "testzip: Illegal argument for the '-c' option.\n\n");
exit(1);
}
break;
case 'p':
print_config();
exit(0);
case 'v':
printf("\nTestZip Version %s\n\n", TZ_VERSION);
printf("Programmed by MadMan with suggestions from Pantera: 12/6/96\n");
printf("Modified by [Gandolf]: 12/8/96, - 2/24/97\n\n");
exit(0);
break;
case 'h':
case '?':
printf("\nTestZip Version %s Help:\n\n", TZ_VERSION);
printf("-? or -h Display this help text.\n");
printf("-v\t Display version information.\n");
printf("-p\t Print testzip's configuration to screen.\n");
printf("-D\t Delete any bad zip files.\n");
printf("-d\t Do Not delete bad files.\n");
printf("-E\t Test all defined archive types.\n");
printf("-e\t Test only archive type specified by -c.\n");
printf("-R\t Recursively check directories.\n");
printf("-r\t Do not recursively check directories.\n");
printf("-t dir\t Test all zip files in 'dir' (Default: %s)\n", testzipcfg.dir);
printf("-f name Use 'name' as the log file. (Default: %s)\n", testzipcfg.logname);
printf("-o\t Overwrite the log file if it already exists.\n");
printf("-a\t Append to the log file if it already exists.\n");
printf("-l 0\t Log Level 0: No logging.\n");
printf("-l 1\t Log Level 1: Only bad files logged.\n");
printf("-l 2\t Log Level 2: All files logged.\n");
for (i = 0; i < testzipcfg.num_archivers; i++)
printf("-c %c\t Test files compressed using %s.\n", testzipcfg.archive[i].option, testzipcfg.archive[i].name);
printf("\n");
exit(0);
}
}
}