root@hobbes.UUCP (John Plocher) (07/16/87)
This is a note to report a few (more) problems with the System5 ARC which was posted back before May 87. These problems may also be in the BSD and MS-DOS versions. The reason I got into ARC again was that I wanted to add handling for PKarc's SCRUNCHING (compression type 9). I have not added the compression/decompression routines; all I did was modify arclst.c and arcunp.c to spit out helpful notes upon encountering type 9 headers. I also made System5 14 char filenames OPTIONAL and DOS 12 char filenames the DEFAULT! This program is primarily used to handle DOS stuff... Anyways, here is the stuff I found: To repeat: /usr/src/dos/ls> ls LS.C LS.OBJ LS.EXE LS.arc /usr/src/dos/ls> arc ai LS.arc LS* Segmentation violation core dumped /usr/src/dos/ls> Reason: Boundry condition! The file LS.arc is the LAST member of the arg[] list sent to sortarg(). Since LS.arc is the name of the *archive*, it is removed by: while (strcmp(arg[top],arcname) == 0) { for (seek = top; seek < num;seek++) arg[seek] = arg[seek + 1]; arg[--num] = '\0'; dups++; } When the loop goes into pass 2 after 'removing' LS.arc it does a strcmp(0, arcname). BTW: Change arg[--num] = '\0'; to arg[--num] = NULL; arg is declared as char *arg[]; An array of POINTERS to chars! The way it is coded is WRONG. The following loop which checks for duplicate names has the same problem. Fix: /* * arcmisc.c 1.2 ... sortarg(num,arg) /* sort argument list, remove dups */ int num; char *arg[]; { ... /* find any occurences of 'arcname', and remove them */ for (top = 0;top < num;top++) { ! while (arg[top] && strcmp(arg[top],arcname) == 0) { for (seek = top; seek < num;seek++) arg[seek] = arg[seek + 1]; ! arg[--num] = NULL; dups++; } } /* find any other duplicate arguments (ignoring pathnames), */ /* and remove the second and subsequent occurences */ for (top = 0;top < num-1;top++) { buf1 = arg[top]; buf2 = arg[top + 1]; if (i = strrchr(arg[top],'/')) buf1 = i + 1; if (i = strrchr(arg[top + 1],'/')) buf2 = i + 1; ! while (buf1 && buf2 && strcmp(buf1,buf2) == 0) { for (seek = top + 1;seek < num;seek++) arg[seek] = arg[seek + 1]; ! arg[--num] = NULL; buf2 = arg[top + 1]; if (i = strrchr(arg[top + 1],'/')) buf2 = i + 1; dups++; } } ... -- John Plocher uwvax!geowhiz!uwspan!plocher plocher%uwspan.UUCP@uwvax.CS.WISC.EDU