hedrick@athos.rutgers.edu (Charles Hedrick) (04/05/88)
The following is only for the adventuresome: Here's my proposed fix for the DST problem in SV/AT. This is only intended for SV/AT. It presumably will not work on the 386 version. (Judging by the Uport bbs system, the 386 version does have the problem, but it's very unlikely that ctime.o will use the exact code sequence that this program is looking for.) This consists of a program that will patch executables to change the start date of DST to the first Sunday in April. Unfortunately, it has to be called on every executable on the system that uses the routine ctime, and there are a lot of them. So I also supply a shell script that will apply it to a whole directory (actually any wildcard spec). Typically I do something like cd /bin fixdstdir * It needs to be done on /bin, /usr/bin, /usr/lib, /usr/lib/uucp, /etc, /lib/large, /lib/small, /lib/libp/large, and /lib/libp/small. This is on a system that has the base Unix and the development system. I haven't loaded the word-processing software, so I don't know what additional things might need to be fixed up there. Some caveats: - the C program searches for specific executable code sequences. It appears to work for 2.3.0-L, but could fail for other releases if ctime.o happens to compile differently. - in theory the program could trigger falsely, if some other piece of code happened to generate the right code sequence. I sort of doubt it. The test is for loading 119 and then 303 into two specific registers (these are the day numbers for the start and end of DST), but you never know. So back up your system software being doing this. - when I was using this, the system crashed once with a general protection failure. I presume there was just too much disk I/O going on. So I suggest doing this when nobody is logged in who will get upset with a crash. - it will fail on any files that are currently in use (another argument for doing it single-user) - for some reason I got a wierd error message in /etc. I ended up doing fixdstdir [a-g]* fixdstdir [h-z]* which worked fine. - this program will change the last-write dates on any files that are updated. This appears to be reasonable, but note that if you do incremental backups, your next backup will have lots of files in it. (I count about 70 files that get changed.) - if you have directories with your own software, e.g. /usr/local/bin, you'll want to do them as well. - the C program is quite inefficient. It's the way it is because it was easy to design that way. Debugging printout is still present. Since it's only going to be run once, none of this matters. #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # fixdst.c # fixdstdir # This archive created: Tue Apr 5 06:06:08 1988 export PATH; PATH=/bin:$PATH if test -f 'fixdst.c' then echo shar: will not over-write existing file "'fixdst.c'" else cat << \SHAR_EOF > 'fixdst.c' #include <stdio.h> int buffer[16]; main (argc,argv) int argc; char **argv; { register int *pt; register int i; FILE *f; int target; long pos; f = fopen(argv[1],"r"); if (f == NULL) { printf("can't open file\n"); exit(2); } while (! feof(f)) { for (pt = buffer, i = 0; i < 15; pt++, i++) *pt = *(pt+1); buffer[15] = getw(f); if (buffer[0] == 0x46c7 && buffer[1] == 0x77fc && buffer[2] == 0xc700 && buffer[3] == 0xfa46 && buffer[4] == 0x012f) { for (i = 0; i < 16; i++) printf("%d ", buffer[i]); printf("\n"); pos = ftell(f); f = fopen(argv[1],"r+"); if (f == NULL) { printf("can't reopen file for update\n"); exit(2); } fseek(f, pos-30, 0); putw(0x60fc, f); fclose(f); exit(0); } else if (buffer[0] == 0xfc46 && buffer[1] == 0x0077 && buffer[2] == 0x46c7 && buffer[3] == 0x2ffa) { for (i = 0; i < 16; i++) printf("%d ", buffer[i]); printf("\n"); printf("\n"); pos = ftell(f); f = fopen(argv[1],"r+"); if (f == NULL) { printf("can't reopen file for update\n"); exit(2); } fseek(f, pos-30, 0); putw(0x0060, f); fclose(f); exit(0); } } exit(1); } SHAR_EOF chmod +x 'fixdst.c' fi # end of overwriting check if test -f 'fixdstdir' then echo shar: will not over-write existing file "'fixdstdir'" else cat << \SHAR_EOF > 'fixdstdir' #!/bin/csh foreach i ($*) fixdst $i if ($status == 0) then echo $i endif end SHAR_EOF chmod +x 'fixdstdir' fi # end of overwriting check # End of shell archive exit 0