В Unix v7 как и во многих других ОС для PDP-11 есть проблема Y2k. Решение было найдено в японском блоге. Попробуем это повторить.
В первую очередь нужно исправить часовой пояс т.к. по умолчанию стоит cевероамериканское восточное время EST (GMT–05). А мне нужно UTC+3. Для того чтобы изменить часовой пояс нужно изменить файл /usr/sys/h/param.h и пересобрать ядро.
# cat /usr/sys/h/param.h
/*
* tunable variables
*/
#define NBUF 29 /* size of buffer cache */
#define NINODE 200 /* number of in core inodes */
#define NFILE 175 /* number of in core file structures */
#define NMOUNT 8 /* number of mountable file systems */
#define MAXMEM (64*32) /* max core per process - first # is Kw */
#define MAXUPRC 25 /* max processes per user */
#define SSIZE 20 /* initial stack size (*64 bytes) */
#define SINCR 20 /* increment of stack (*64 bytes) */
#define NOFILE 20 /* max open files per process */
#define CANBSIZ 256 /* max size of typewriter line */
#define CMAPSIZ 50 /* size of core allocation area */
#define SMAPSIZ 50 /* size of swap allocation area */
#define NCALL 20 /* max simultaneous time callouts */
#define NPROC 150 /* max number of processes */
#define NTEXT 40 /* max number of pure texts */
#define NCLIST 100 /* max total clist size */
#define HZ 60 /* Ticks/second of the clock */
#define TIMEZONE (5*60) /* Minutes westward from Greenwich */
#define DSTFLAG 1 /* Daylight Saving Time applies in this locality */
#define MSGBUFS 128 /* Characters saved from error messages */
#define NCARGS 5120 /* # characters in exec arglist */
В этом файле нужно поменять значение TIMEZONE и DSTFLAG(0 - отключить летнее время) для UTC+3 это будет выглядеть так:
# ed /usr/sys/h/param.h
4411
22p
#define TIMEZONE (5*60) /* Minutes westward from Greenwich */
22c
#define TIMEZONE (-3*60) /* Minutes westward from Greenwich */
.<cr>
23c
#define DSTFLAG 0 /* Daylight Saving Time applies in this locality */
.<cr>
22,23p
#define TIMEZONE (-3*60) /* Minutes westward from Greenwich */
#define DSTFLAG 0 /* Daylight Saving Time applies in this locality */
w
4431
q
#
Затем нужно пересобрать ядро, выполнив сначала make all
# cd /usr/sys/conf
# make all
cd ../sys; cc -c -O *.c; mklib; rm *.o
acct.c:
...
# make
ld -o unix -X -i l.o mch.o c.o ../sys/LIB1 ../dev/LIB2
#
Часовой пояс будет установлен правильно, но не будет отображаться в системе, чтобы и это исправить придется добавить его в файл /usr/src/libc/gen/timezone.c
# cd /usr/src/libc/gen
# cat timezone.c
/*
* The arguments are the number of minutes of time
* you are westward from Greenwich and whether DST is in effect.
* It returns a string
* giving the name of the local timezone.
*
* Sorry, I don't know all the names.
*/
static struct zone {
int offset;
char *stdzone;
char *dlzone;
} zonetab[] = {
4*60, "AST", "ADT", /* Atlantic */
5*60, "EST", "EDT", /* Eastern */
6*60, "CST", "CDT", /* Central */
7*60, "MST", "MDT", /* Mountain */
8*60, "PST", "PDT", /* Pacific */
0, "GMT", 0, /* Greenwich */
-1
};
Отредактируем в этом файле часовой пояс
} zonetab[] = {
-3*60, "MSK", 0, /* Russia */
4*60, "AST", "ADT", /* Atlantic */
5*60, "EST", "EDT", /* Eastern */
6*60, "CST", "CDT", /* Central */
7*60, "MST", "MDT", /* Mountain */
8*60, "PST", "PDT", /* Pacific */
0, "GMT", 0, /* Greenwich */
-1
};
И скомпилируем исходник
# cc -c -O timezone.c
Поскольку часовой пояс является частью libc.a, замените содержимое libc.a на новый файл.
# cd /lib
# cp libc.a libc.a.org
# ar r libc.a /usr/src/libc/gen/timezone.o
С часовым поясом всё, но осталось решить проблему с годами больше 1999 и для этого нужно подправить команду date, исходник которой находится в /usr/src/cmd/date.c Подправим функцию gtime(), где укажем что если значение года меньше или равно 50, то это 2000-е годы.
gtime()
{
...
if (hour==24) {
hour=0; day++;
}
if (hour<0 hour="">23)
return(1);
timbuf = 0;
/* fix y2k */
/*year += 1900;*/ оригинальная строка
if (year > 50){
year += 1900;
}
else{
year += 2000;
}
/* fix y2k end */
for(i=1970; i<year; i++)
timbuf += dysize(i);
/* Leap year */
if (dysize(year)==366 && month >= 3)
timbuf++;
while(--month)
timbuf += dmsize[month-1];
timbuf += day-1;
timbuf = 24*timbuf + hour;
timbuf = 60*timbuf + mins;
timbuf = 60*timbuf + secs;
return(0);
}
# cd /usr/src/cmd
# ed date.c
Скомпилируем файл и заменим им /bin/date
# cc -o date date.c
# mv /bin/date /bin/date.org
# cp ./date /bin/
Заменим ядро на только что собранное и перезагрузим систему
# mv /unix /oldunix
# cp /usr/sys/conf/unix /unix
# sync;sync;sync;
# (Ctrl-E)
После загрузки проверяем что получилось.
# date 1801131607
Sat Jan 13 16:07:00 MSK 2018
# date -u
Sat Jan 13 13:07:05 GMT 2018
UPD. После каждого изменения timezone.c нужно заново компилировать date.c иначе изменения не применяться.