1 /*
2  * main.c -- TODAY main for MS-DOS & Human68k & unix & Windows version
3  *
4  * Copyright (C) 1989,1997,1999,2001,2003 by Yoshifumi Mori
5  *
6  * tab:4
7  */
8 
9 #include "cdefs.h"
10 #include "extern.h"
11 
12 const char	*fmt_sep1 = "/\t ";
13 const char	*fmt_sep2 = ",\t ";
14 const char	*fmt_sep3 = "\t ";
15 const char	*fmt_sep4 = "";
16 
17 const char	*todaycnf_file = "today.cnf";
18 
19 char	msgbuf[MAXMSGBUF];					/* �Ƽ��å��������ϥХåե� */
20 int		screen_max_columns = _T_MAXWIDTH;	/* ���̤κ����� */
21 int		screen_max_rows    = _T_MAXROWS;	/* ���̤κ���Կ� */
22 struct NOWDATE	calendar;
23 struct MONTHTBL	monthtbl[MAX_MONTH_TBL];
24 #if defined(_T_WINDOWS)
25 int	win_colormap[MAX_COLORMAP] = {
26 	0x000000, 0x0000AA, 0x00AA00, 0x0055AA,
27 	0xAA0000, 0xAA00AA, 0xAAAA00, 0xAAAAAA,
28 	0x555555, 0x5555FF, 0x55FF55, 0x55FFFF,
29 	0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF,
30 };									/* ���� RGB */
31 int	win_default_color = 0x07;		/* �ǥե���ȿ� */
32 
33 int	sysflags = 0;
34 int	extflags = 0;
35 char	*disp_fontname;
36 int	disp_fontsize;
37 #endif /* _T_WINDOWS */
38 
39 int	birthday_flag = TRUE;	/* ������ɽ������ */
40 int	date_flag     = TRUE;	/* ����ɽ������ */
41 int	event_flag    = TRUE;	/* ���٥��ɽ������ */
42 int	history_flag  = TRUE;	/* ���ɽ������ */
43 int	schedule_flag = TRUE;	/* �������塼��ɽ������ */
44 int	display_order[MAX_DISPLAY_ORDER];	/* ɽ����� */
45 #if !defined(_T_WINDOWS)
46 static int	verbose_flag  = FALSE;	/* �С������ɽ������ */
47 #else /* !_T_WINDOWS */
48 static HWND	ghWnd;
49 #endif
50 static char	cmdpathbuf[_T_MAXPATHNAME];
51 #if defined(_T_UNIX)
52 static char	defpathbuf[_T_MAXPATHBUF];
53 #endif
54 
55 static const struct OPERAND_TABLE	optbl_yesno[] = {
56 	{ "yes", TRUE  },
57 	{ "no",  FALSE },
58 	{ NULL,  0     }
59 };
60 
61 static const struct OPERAND_TABLE	optbl_notice[] = {
62 	{ "mark_only", NOTICE_MARK_ONLY },
63 	{ "all",       NOTICE_ALL       },
64 	{ "no",        NOTICE_NO        },
65 	{ NULL,        0                }
66 };
67 
68 static const struct OPERAND_TABLE	optbl_sortorder[] = {
69 	{ "����", SORT_UP_ORDER   },
70 	{ "�߽�", SORT_DOWN_ORDER },
71 	{ "�ʤ�", SORT_NO_ORDER   },
72 	{ NULL,   0               }
73 };
74 
75 static const struct OPERAND_TABLE	optbl_birth_age[] = {
76 	{ "all",        BIRTHDAY_AGE_ALL        },
77 	{ "man_only",   BIRTHDAY_AGE_MAN_ONLY   },
78 	{ "young_only", BIRTHDAY_AGE_YOUNG_ONLY },
79 	{ "no",         BIRTHDAY_AGE_NO         },
80 	{ NULL,         0                       }
81 };
82 
83 static const struct OPERAND_TABLE	optbl_date_year[] = {
84 	{ "����", DATE_YEAR_JC },
85 	{ "����", DATE_YEAR_AD },
86 	{ NULL,   0            }
87 };
88 
89 static const struct OPERAND_TABLE	optbl_date_time[] = {
90 	{ "12h", DATE_TIMESYSTEM_12H },
91 	{ "24h", DATE_TIMESYSTEM_24H },
92 	{ NULL,  0                   }
93 };
94 
95 static const struct OPERAND_TABLE	optbl_msg_fold[] = {
96 	{ "type", MSG_FOLDTYPE_BASE },
97 	{ NULL,   0                 }
98 };
99 
100 #if defined(_T_MSDOS)
101 static const struct OPERAND_TABLE	optbl_machine[] = {
102 	{ "ibm",  MACHINE_IBM  },
103 	{ "pc98", MACHINE_PC98 },
104 	{ "none", MACHINE_NONE },
105 	{ NULL,   0            }
106 };
107 #endif /* _T_MSDOS */
108 
109 static struct CONFIG_VARIABLE_TABLE	conf_tbl[] = {
110 	{ "12choku",                VAR_OP,     { optbl_yesno             }, { &date_12_flag           } },
111 	{ "28syuku",                VAR_OP,     { optbl_yesno             }, { &date_28_flag           } },
112 	{ "birthday",               VAR_OP,     { optbl_yesno             }, { &birthday_flag          } },
113 	{ "birthday_addinfo",       VAR_INT,    { NULL                    }, { &birthday_addinfo       } },
114 	{ "birthday_age_class",     VAR_OP,     { optbl_birth_age         }, { &birthday_agelevel      } },
115 	{ "birthday_age_sort",      VAR_OP,     { optbl_sortorder         }, { &birthday_agesort       } },
116 	{ "birthday_file",          VAR_DIMSTR, { (void *)MAXBIRTHFILE    }, { birthday_filetbl        } },
117 	{ "birthday_flower_always", VAR_OP,     { optbl_yesno             }, { &birthday_flower        } },
118 	{ "birthday_notice",        VAR_OP,     { optbl_notice            }, { &birthday_notice_flag   } },
119 	{ "birthday_notice_range",  VAR_INT,    { NULL                    }, { &birthday_notice_range  } },
120 	{ "birthday_sort",          VAR_STR,    { NULL                    }, { &birthday_sortorder     } },
121 	{ "date",                   VAR_OP,     { optbl_yesno             }, { &date_flag              } },
122 	{ "deathday",               VAR_OP,     { optbl_yesno             }, { &deathday_flag          } },
123 	{ "deathday_age",           VAR_INT,    { NULL                    }, { &deathday_agelevel      } },
124 	{ "deathday_notice",        VAR_OP,     { optbl_notice            }, { &deathday_notice_flag   } },
125 	{ "deathday_notice_range",  VAR_INT,    { NULL                    }, { &deathday_notice_range  } },
126 	{ "display_order_birthday", VAR_INT,    { NULL                    }, { &display_order[2]       } },
127 	{ "display_order_date",     VAR_INT,    { NULL                    }, { &display_order[0]       } },
128 	{ "display_order_event",    VAR_INT,    { NULL                    }, { &display_order[1]       } },
129 	{ "display_order_history",  VAR_INT,    { NULL                    }, { &display_order[3]       } },
130 	{ "display_order_schedule", VAR_INT,    { NULL                    }, { &display_order[4]       } },
131 	{ "eto",                    VAR_OP,     { optbl_yesno             }, { &date_eto_flag          } },
132 	{ "eto2",                   VAR_OP,     { optbl_yesno             }, { &date_eto2_flag         } },
133 	{ "event",                  VAR_OP,     { optbl_yesno             }, { &event_flag             } },
134 	{ "event_file",             VAR_DIMSTR, { (void *)MAXEVENTFILE    }, { event_filetbl           } },
135 	{ "event_level",            VAR_STR,    { NULL                    }, { &event_level_str        } },
136 	{ "event_notice",           VAR_OP,     { optbl_notice            }, { &event_notice_flag      } },
137 	{ "event_notice_range",     VAR_INT,    { NULL                    }, { &event_notice_range     } },
138 	{ "event_range",            VAR_OP,     { optbl_yesno             }, { &event_range_flag       } },
139 	{ "event_sort",             VAR_STR,    { NULL                    }, { &event_sortorder        } },
140 	{ "history",                VAR_OP,     { optbl_yesno             }, { &history_flag           } },
141 	{ "history_addinfo",        VAR_INT,    { NULL                    }, { &history_addinfo        } },
142 	{ "history_both_date",      VAR_OP,     { optbl_yesno             }, { &history_both_date      } },
143 	{ "history_file",           VAR_DIMSTR, { (void *)MAXHISTORYFILE  }, { history_filetbl         } },
144 	{ "history_foldtype",       VAR_OPNUM,  { optbl_msg_fold          }, { &history_foldtype       } },
145 	{ "history_sort",           VAR_OP,     { optbl_sortorder         }, { &history_sort           } },
146 	{ "history_year_comment",   VAR_INT,    { NULL                    }, { &history_year_comment   } },
147 	{ "kyureki",                VAR_OP,     { optbl_yesno             }, { &date_kyureki_flag      } },
148 	{ "kyusei",                 VAR_OP,     { optbl_yesno             }, { &date_kyusei_flag       } },
149 #if defined(_T_MSDOS)
150 	{ "machine",                VAR_OP,     { optbl_machine           }, { &machine_type           } },
151 #else /* _T_HUMAN68K || _T_UNIX || _T_WIN32CONSOLE || _T_WINDOWS */
152 	{ "machine",                VAR_NONE,   { NULL                    }, { NULL                    } },
153 #endif
154 	{ "outputfile",             VAR_STR,    { NULL                    }, { &pager_outputfile       } },
155 	{ "outputfile_keep",        VAR_OP,     { optbl_yesno             }, { &pager_filekeep         } },
156 	{ "outputfile_path",        VAR_STR,    { NULL                    }, { &pager_filelog_path     } },
157 	{ "pager",                  VAR_STR,    { NULL                    }, { &pager_cmd              } },
158 	{ "pause",                  VAR_OP,     { optbl_yesno             }, { &pager_pause            } },
159 	{ "pause_last",             VAR_OP,     { optbl_yesno             }, { &pager_lastpause        } },
160 	{ "rekichu",                VAR_STR,    { NULL                    }, { &rekichu_f_string       } },
161 	{ "rekichu_kadan",          VAR_STR,    { NULL                    }, { &rekichu_kadan_f_string } },
162 	{ "replace_pathenv",        VAR_OP,     { optbl_yesno             }, { &replace_pathenv        } },
163 	{ "schedule",               VAR_OP,     { optbl_yesno             }, { &schedule_flag          } },
164 	{ "schedule_file",          VAR_DIMSTR, { (void *)MAXSCHEDULEFILE }, { schedule_filetbl        } },
165 	{ "schedule_foldtype",      VAR_OPNUM,  { optbl_msg_fold          }, { &schedule_foldtype      } },
166 	{ "schedule_limit",         VAR_INT,    { NULL                    }, { &schedule_limit         } },
167 #if defined(_T_MSDOS) || defined(_T_UNIX) || defined(_T_WIN32CONSOLE) || defined(_T_WINDOWS)
168 	{ "screen_columns",         VAR_INT,    { NULL                    }, { &screen_max_columns     } },
169 	{ "screen_rows",            VAR_INT,    { NULL                    }, { &screen_max_rows        } },
170 #else /* _T_HUMAN68K */
171 	{ "screen_columns",         VAR_NONE,   { NULL                    }, { NULL                    } },
172 	{ "screen_rows",            VAR_NONE,   { NULL                    }, { NULL                    } },
173 #endif
174 	{ "suffix_file",            VAR_STR,    { NULL                    }, { &suffix_file            } },
175 #if defined(_T_HUMAN68K) || defined(_T_MSDOS) || defined(_T_WIN32CONSOLE) || defined(_T_WINDOWS)
176 	{ "table_path",             VAR_STR,    { NULL                    }, { &search_path            } },
177 #else /* _T_UNIX */
178 	{ "table_path",             VAR_PATH,   { NULL                    }, { &search_path            } },
179 #endif
180 	{ "time",                   VAR_OP,     { optbl_yesno             }, { &date_time_flag         } },
181 	{ "timesystem",             VAR_OP,     { optbl_date_time         }, { &date_timesystem_type   } },
182 	{ "week_file",              VAR_DIMSTR, { (void *)MAXWEEKFILE     }, { week_filetbl            } },
183 	{ "year_type",              VAR_OP,     { optbl_date_year         }, { &date_yeartype          } },
184 #if defined(_T_WINDOWS)
185 	{ "colormap",               VAR_DIMINT, { (void *)MAX_COLORMAP    }, { win_colormap            }, 0x61 },
186 	{ "default_color",          VAR_INT,    { NULL                    }, { &win_default_color      }, 0x21 },
187 	{ "extflags",               VAR_INT,    { NULL                    }, { &extflags               }, 0x81 },
188 	{ "file_editor",            VAR_STR,    { NULL                    }, { &file_editor_cmd        } },
189 	{ "find_editor",            VAR_STR,    { NULL                    }, { &find_editor_cmd        } },
190 	{ "screen_fontname",        VAR_STR,    { NULL                    }, { &disp_fontname          } },
191 	{ "screen_fontsize",        VAR_INT,    { NULL                    }, { &disp_fontsize          } },
192 	{ "sysflags",               VAR_INT,    { NULL                    }, { &sysflags               }, 0x81 },
193 #endif /* _T_WINDOWS */
194 	{ NULL,                     VAR_NONE,   { NULL                    }, { NULL                    } }
195 };
196 
197 #if defined(_T_WINDOWS)
198 static const char	*readblock[] = { "today", "common", "windows", "wintoday", NULL };
199 #else
200 static const char	*readblock[] = { "today", "common", NULL };
201 #endif
202 
203 #if !defined(_T_WINDOWS)
204 /*
205  * ���ꥨ�顼����
206  */
memerr(const char * func)207 void memerr(const char *func)
208 {
209 	errprint(func, ERR_PANIC, "virtual memory exhausted, program stop.");
210 	terminate_program(TERM_MEMERROR);
211 }
212 #endif /* !_T_WINDOWS */
213 
214 #if !defined(_T_WINDOWS)
215 /*
216  * �¹���Υ��顼ɽ��
217  *
218  * func:  �¹Դؿ�̾
219  * level: ���顼��٥� (information, warning, debug, error, panic)
220  * fmt:   ���顼��å�����
221  */
errprint(const char * func,int level,const char * fmt,...)222 void errprint(const char *func, int level, const char *fmt, ...)
223 {
224 	static const char	*statname[] = {
225 		"warning", "debug", "error", "panic",
226 	};
227 	va_list	ap;
228 
229 	va_start(ap, fmt);
230 
231 	fprintf(stderr, "today: %s");
232 	if (level != ERR_INFO) {
233 		fprintf(stderr, "%s: ", statname[level - ERR_WARN]);
234 	}
235 	if (func != NULL) {
236 		fprintf(stderr, "%s: ", func);
237 	}
238 	vfprintf(stderr, fmt, ap);
239 	fputc('\n', stderr);
240 
241 	va_end(ap);
242 }
243 #endif /* !_T_WINDOWS */
244 
245 #if !defined(_T_WINDOWS)
246 /*
247  * ������ץȤ䥨�顼�ˤ��ץ�������ǽ���
248  */
terminate_program(int sig)249 void terminate_program(int sig)
250 {
251 	switch (sig) {
252 	case SIGINT:
253 		pager_clean(TRUE);
254 		exit(4);
255 		break;
256 	case TERM_MEMERROR:
257 		pager_clean(FALSE);
258 		exit(1);
259 		break;
260 	case TERM_FILEERROR:
261 		pager_clean(FALSE);
262 		exit(2);
263 		break;
264 	}
265 	exit(99);
266 }
267 #endif /* !_T_WINDOWS */
268 
269 /*
270  * ����ˡ��ɽ��
271  *
272  * ɽ���塢�ץ�������
273  */
274 static
usage(void)275 void usage(void)
276 {
277 #if !defined(_T_WINDOWS)
278 	fprintf(stderr, "usage: today [options] [[YYYY|YY]MMDD]\n"
279 			"options:"
280 			  " -a|-A\t������ɽ������\t\t-a��ɽ��(-dbeh��Ʊ��)\n"
281 			"\t -d|-D\t���դ�ɽ������\t\t-d��ɽ��\n"
282 			"\t -b|-B\t��������ɽ������\t-b��ɽ��\n"
283 			"\t -e|-E\t���٥�Ȥ�ɽ������\t-e��ɽ��\n"
284 			"\t -h|-H\t��ˤ�ɽ������\t\t-h��ɽ��\n"
285 			"\t -s|-S\t�������塼���ɽ������\t-s��ɽ��\n"
286 			"\t -p|-P\t�ڡ����㡼��ư������\t-p�Ǻ�ư\n"
287 			"\t -w|-W\t��������ɽ������\t-w������\n"
288 			"\t -v\t�С������ɽ��\n\n"
289 			"\t -@file\t���Ū��%s(file)���ɤ߹���\n"
290 			"\t -rvarname=value ���Ū���ѿ����ѹ�\n", todaycnf_file);
291 	exit(3);
292 #else /* !_T_WINDOWS */
293 	char	szMsg[512];
294 	char	szTitle[64];
295 
296 	sprintf(szMsg, "%s [options] [[YYYY|YY]MMDD]\n\n"
297 		"options:"
298 		"\t-a | -A\t\t������ɽ������\n\t\t\t-a��ɽ��(-dbeh��Ʊ��)\n"
299 		"\t-d | -D\t\t���դ�ɽ������\n\t\t\t-d��ɽ��\n"
300 		"\t-b | -B\t\t��������ɽ������\n\t\t\t-b��ɽ��\n"
301 		"\t-e | -E\t\t���٥�Ȥ�ɽ������\n\t\t\t-e��ɽ��\n"
302 		"\t-h | -H\t\t��ˤ�ɽ������\n\t\t\t-h��ɽ��\n"
303 		"\t-s | -S\t\t�������塼���ɽ������\n\t\t\t-s��ɽ��\n"
304 		"\t-w | -W\t\t��������ɽ������\n\t\t\t-w������\n"
305 		"\t-@file\t\t���Ū�� %s(file) ���ɤ߹���\n"
306 		"\t-rvarname=value\t���Ū���ѿ����ѹ�",
307 		szAppName, todaycnf_file);
308 	sprintf(szTitle, "%s�Υ��ץ����", szAppName);
309 
310 	MessageBox(ghWnd, szMsg, szTitle, MB_OK);
311 /*	exit(3);	*/
312 #endif /* !_T_WINDOWS */
313 }
314 
315 /*
316  * ���դ�������Ƚ��
317  *
318  * return value:
319  *   TRUE  ��������
320  *   FALSE ���ե��顼
321  */
322 #if !defined(_T_WINDOWS)
323 static
324 #endif
isDate(int year,int month,int day)325 int isDate(int year, int month, int day)
326 {
327 	if (year < SUPPORT_MIN_YEAR || year > SUPPORT_MAX_YEAR) {
328 		return (FALSE);
329 	}
330 	if (month < 1 || month > 12) {
331 		return (FALSE);
332 	}
333 	if (day < 1 || day > GetDayofMonth(year, month)) {
334 		return (FALSE);
335 	}
336 	return (TRUE);
337 }
338 
339 /*
340  * ��������Ƚ�Ǥ���
341  *
342  * return value:
343  *   TRUE  ������ or �̥�ʸ����
344  *   FALSE ����ʳ�
345  */
346 static
isNumstring(const char * s)347 int isNumstring(const char *s)
348 {
349 	while (*s != '\0') {
350 		if (isdigit((unsigned char)*s) == 0) {
351 			return (FALSE);
352 		}
353 		s++;
354 	}
355 
356 	return (TRUE);
357 }
358 
359 /*
360  * ���դ��ɤ߼��
361  *
362  * return value:
363  *   TRUE  �ɤ߼������
364  *   FALSE ���顼ȯ��
365  */
366 static
readDate(const char * param)367 int readDate(const char *param)
368 {
369 	int	err = FALSE;
370 
371 	if (isNumstring(param) == FALSE) {
372 		err = TRUE;
373 	} else {
374 		switch (strlen(param)) {
375 		case 8:	/* YYYYMMDD */
376 			sscanf(param, "%04d%02d%02d", &calendar.year, &calendar.month, &calendar.day);
377 			break;
378 		case 6:	/* YYMMDD */
379 			sscanf(param, "%02d%02d%02d", &calendar.year, &calendar.month, &calendar.day);
380 			if (calendar.year < 50) {
381 				calendar.year += 2000;	/* 00-49 -> 2000-2049 */
382 			} else {
383 				calendar.year += 1900;	/* 50-99 -> 1950-1999 */
384 			}
385 			break;
386 		case 4:	/* MMDD */
387 			sscanf(param, "%02d%02d", &calendar.month, &calendar.day);
388 			break;
389 		case 2:	/* DD */
390 			calendar.day = atoi(param);
391 			break;
392 		default:
393 			err = TRUE;
394 			break;
395 		}
396 	}
397 
398 	if (err == TRUE) {
399 		errprint(NULL, ERR_ERROR, "invalid DATE format %s", param);
400 		return (FALSE);
401 	}
402 
403 	if (isDate(calendar.year, calendar.month, calendar.day) == FALSE) {
404 		errprint(NULL, ERR_ERROR, "illegal DATE %d/%02d/%02d", calendar.year, calendar.month, calendar.day);
405 		return (FALSE);
406 	}
407 
408 	return (TRUE);
409 }
410 
411 /*
412  * ���դ��ѹ�����
413  */
414 static
changes_date(int argc,char ** argv)415 void changes_date(int argc, char **argv)
416 {
417 	int	phase = 0;
418 
419 	while (argc > 0) {
420 		if (**argv == '+') {
421 			++*argv;
422 			date_inc((struct DATE_T *)&calendar, atoi(*argv));
423 			/*
424 			 * struct NOWDATE ����Ƭ 4���ܤ�
425 			 * struct DATE_T ��Ʊ�����Ȥ�����
426 			 */
427 			phase = 1;
428 		} else {
429 			if (phase == 0) {
430 				if (readDate(*argv) != FALSE) {
431 					phase = 1;
432 					date_time_inhibit = TRUE;	/* ���դ��ѹ�����������ɽ�����ʤ� date.c */
433 #if !defined(_T_WINDOWS)
434 				} else {
435 					usage();
436 #endif
437 				}
438 			}
439 		}
440 		argc--;
441 		argv++;
442 	}
443 }
444 
445 /*
446  * ���ץ����ѥ�᡼���β���
447  *
448  * return value:
449  *   TRUE  �ѥ�᡼��OK
450  *   FALSE ���顼
451  */
452 static
option_check(int argc,char ** argv)453 int option_check(int argc, char **argv)
454 {
455 	int	c;
456 	int	flag;
457 
458 	while ((c = getopt(argc, argv, "0@::AaBbDdEeHhPpq::r::SsTtvWw?")) != EOF) {
459 		flag = islower(c) ? TRUE : FALSE;
460 		switch (c) {
461 		case 'A': case 'a':	/* ������ɽ������ */
462 			birthday_flag = flag;
463 			date_flag = flag;
464 			event_flag = flag;
465 			history_flag = flag;
466 			break;
467 		case 'D': case 'd':	/* ����ɽ������ */
468 			date_flag = flag;
469 			break;
470 		case 'T': case 't':	/* ���������� */
471 			date_timesystem_type = (c == 'T') ? DATE_TIMESYSTEM_24H : DATE_TIMESYSTEM_12H;
472 			break;
473 		case 'B': case 'b':	/* ������ɽ������ */
474 			birthday_flag = flag;
475 			break;
476 		case '0':	/* ǯ��ɽ�� */
477 			birthday_agelevel = BIRTHDAY_AGE_ALL;
478 			break;
479 		case 'E': case 'e':	/* ���٥��ɽ������ */
480 			event_flag = flag;
481 			break;
482 		case 'H': case 'h':	/* ���ɽ������ */
483 			history_flag = flag;
484 			break;
485 		case 'S': case 's':	/* �������塼��ɽ������ */
486 			schedule_flag = flag;
487 			break;
488 #if !defined(_T_WINDOWS)
489 		case 'P': case 'p':	/* �ڡ����㡼ư������ */
490 			pager_action = flag;
491 			break;
492 #endif
493 		case 'W': case 'w':	/* ����ɽ��������ɽ�� */
494 			date_yeartype = (c == 'W') ? DATE_YEAR_AD : DATE_YEAR_JC;
495 			break;
496 #if !defined(_T_WINDOWS)
497 		case 'v':	/* �С������ɽ�� */
498 			verbose_flag = TRUE;
499 			break;
500 #endif
501 #if defined(_T_WINDOWS)
502 		case'q':	/* quick(skip splash window) */
503 			if (optarg == NULL) {
504 				splash_timeout = 0;
505 			} else {
506 				splash_timeout = strtol(optarg, NULL, 0) * 1000;
507 			}
508 			break;
509 #endif
510 		case 'r':	/* ���Ū���ѿ������� */
511 			if (optarg != NULL) {
512 				config_oneline("cmdline", &conf_tbl[0], optarg);
513 			}
514 			break;
515 		case '@':	/* ���Ū�� TODAY.CNF ���ɤ߹��� */
516 			config(optarg, &conf_tbl[0], &readblock[0]);
517 			break;
518 		case '?':	/* ����ˡɽ�� */
519 		default:
520 			usage();
521 			return (FALSE);
522 		}
523 	}
524 
525 	return (TRUE);
526 }
527 
528 /*
529  * TODAY configuration procedure
530  *
531  * ����ե�������ɤ߹���
532  * ���������ɤ߹���
533  * ���ץ��������å�
534  *
535  * return value:
536  *   TRUE  ���ェλ
537  *   FALSE ���顼ȯ��
538  */
539 #if !defined(_T_WINDOWS)
540 static
541 #endif
configuration_today(int argc,char ** argv)542 int configuration_today(int argc, char **argv)
543 {
544 	int	c_rtc;
545 
546 #if defined(_T_HUMAN68K) || defined(_T_MSDOS) || defined(_T_WIN32CONSOLE) || defined(_T_WINDOWS)
547 	{
548 		char	*p;
549 
550 		strncpy(cmdpathbuf, argv[0], sizeof(cmdpathbuf) - 1);
551 		p = strrchr(cmdpathbuf, _T_FS_CHR);
552 		if (p == NULL) {
553 			p = strrchr(cmdpathbuf, '/');
554 			if (p == NULL) {
555 				p = strrchr(cmdpathbuf, ':');
556 			}
557 		}
558 		if (p != NULL) {
559 			p[1] = '\0';
560 			search_cmdpath = cmdpathbuf;
561 		}
562 	}
563 #else /* _T_UNIX */
564 	if (readlink(_T_PROCSELFEXE_PATH, cmdpathbuf, sizeof(cmdpathbuf) - 1) > 0 &&
565 	    cmdpathbuf[0] == '/') {
566 		char	*p;
567 
568 		p = strrchr(cmdpathbuf, '/');
569 		if (p != NULL) {
570 			p[1] = '\0';
571 		}
572 		search_cmdpath = cmdpathbuf;
573 	}
574 
575 	(void)setlocale(LC_ALL, "");
576 	strncpy(defpathbuf, _T_SEARCH_DEFPATHS, sizeof(defpathbuf) - 1);
577 	search_defpath = defpathbuf;
578 #endif
579 
580 	search_envname = "TODAYTBL";
581 	replace_pathenv = TRUE;
582 
583 	c_rtc = config(todaycnf_file, &conf_tbl[0], &readblock[0]);
584 
585 #if defined(_T_UNIX)
586 /*
587  * unix �Ǥ� _T_SEARCH_DEFPATH �� today.cnf ���ɤ᤿�� HOME ��
588  * today.cnf ���ɤ߹���
589  *
590  * table_path �� & �� HOME �ˤ��� today.cnf �� table_path �����ꤷ�Ƥ�
591  * ��� & ����ʬ������Υѥ����֤�������
592  *
593  * �� table_path = &:/home/mori/tbl
594  */
595 	if (c_rtc == 0 && search_hitphase == 1) {	/* _T_SEARCH_DEFPATH ��ȯ���Ǥ��� */
596 		search_errignore = TRUE;
597 		search_gophase = 6;	/* _T_HOMEENV ��Ĵ�٤� */
598 		(void)config(todaycnf_file, &conf_tbl[0], &readblock[0]);
599 		search_gophase = 0;
600 		search_errignore = FALSE;
601 	}
602 #endif /* _T_UNIX */
603 
604 	rdcalendar((struct CALENDAR *)&calendar);
605 	/*
606 	 * struct NOWDATE ����Ƭ 7���ܤ� struct CALENDAR ��Ʊ�����Ȥ�����
607 	 */
608 
609 	if (option_check(argc, argv) == FALSE) {
610 		return (FALSE);
611 	}
612 	argc -= optind;
613 	argv += optind;
614 	changes_date(argc, argv);
615 
616 	if (Loading_GengoTbl() != LOAD_OK) {
617 		errprint(NULL, ERR_ERROR, "ǯ���Ѵ��ϤǤ��ޤ���");
618 	}
619 	if (Loading_SuffixTbl() != LOAD_OK) {
620 		errprint(NULL, ERR_ERROR, "�������Ѵ��ϤǤ��ޤ���");
621 	}
622 	if (Loading_HolidayTbl() != LOAD_OK) {
623 		errprint(NULL, ERR_ERROR, "�����������ν����ϤǤ��ޤ���");
624 	}
625 
626 #if !defined(_T_WINDOWS)
627 	machine_setup();
628 #endif
629 
630 	return (TRUE);
631 }
632 
633 /*
634  * �������������ѿ�����������
635  *
636  * ��¤�� calendar �����ꤹ��
637  * ��¤�� monthtbl �����ꤹ��(3����ʬ)
638  */
639 static
setup_calendar(void)640 void setup_calendar(void)
641 {
642 	const struct kansi_t	*k;
643 	const struct LUNAR_CALENDAR	*lc;
644 	struct LC_MONTHTBL	lc_montbl[MAX_MONTH_TBL];
645 	int	i;
646 
647 	calendar.dayofweek = GetDayofWeek(calendar.year, calendar.month, calendar.day);
648 	calendar.leap = isleap(calendar.year);
649 	calendar.julian_day = Julian(calendar.year, calendar.month, calendar.day);
650 	k = kansi(calendar.year, calendar.month, calendar.julian_day);
651 	calendar.eto = k->et;
652 	calendar.de = k->de;
653 	calendar.dt = k->dt;
654 
655 	lc = GetLunarCalendar(calendar.year, calendar.month, calendar.day);
656 	if (lc != NULL) {
657 		calendar.lc_valid = TRUE;
658 		calendar.lc_year = lc->year;
659 		calendar.lc_month = lc->month;
660 		calendar.lc_day = lc->day;
661 		calendar.lc_leap = lc->leap;
662 		calendar.lc_dayofweek = lc->dayofweek;
663 		strcpy(calendar.lc_rokuyou, lc->rokuyou);
664 	} else {
665 		calendar.lc_valid = FALSE;
666 		calendar.lc_year = 0;
667 		calendar.lc_month = 0;
668 		calendar.lc_day = 0;
669 		calendar.lc_leap = 0;
670 		calendar.lc_dayofweek = 0;
671 		calendar.lc_rokuyou[0] = '\0';
672 		errprint(NULL, ERR_ERROR, "�������뤳�Ȥ��Ǥ��ޤ���");
673 	}
674 
675 	for (i = 0; i < MAX_MONTH_TBL; i++) {
676 		int	nyear;
677 		int	nmonth;
678 		int	j;
679 
680 		nyear = calendar.year;
681 		nmonth = calendar.month + (i - CENTER_MONTH);
682 		if (nmonth < 1) {
683 			nyear--;
684 			nmonth += 12;
685 		}
686 		if (nmonth > 12) {
687 			nyear++;
688 			nmonth -= 12;
689 		}
690 
691 		monthtbl[i].year = nyear;
692 		monthtbl[i].month = nmonth;
693 		monthtbl[i].leap = isleap(nyear);
694 		monthtbl[i].dayofmonth = GetDayofMonth(nyear, nmonth);
695 		monthtbl[i].first_dayofweek = GetDayofWeek(nyear, nmonth, 1);
696 		monthtbl[i].last_dayofweek = GetDayofWeek(nyear, nmonth, monthtbl[i].dayofmonth);
697 		monthtbl[i].offset_day = 0;
698 
699 		for (j = i - 1; j >= 0; j--) {
700 			monthtbl[i].offset_day += monthtbl[j].dayofmonth;
701 		}
702 	}
703 
704 	makeHolidayTbl();
705 
706 	if (make_lc_monthtbl(&lc_montbl[0], MAX_MONTH_TBL, CENTER_MONTH, calendar.year, calendar.month, calendar.day) != 0) {
707 		calendar.lc_tbl = FALSE;
708 		return ;
709 	}
710 	calendar.lc_tbl = TRUE;
711 
712 	for (i = 0; i < MAX_MONTH_TBL; i++) {
713 		monthtbl[i].lc = lc_montbl[i];
714 	}
715 }
716 
717 /*
718  * TODAY main procedure
719  */
720 #if defined(_T_WINDOWS)
execute_today(HWND hWnd,int mode)721 int execute_today(HWND hWnd, int mode)
722 #else
723 static
724 int execute_today(void)
725 #endif
726 {
727 	int	i;
728 
729 #if defined(_T_WINDOWS)
730 	ghWnd = hWnd;
731 
732 	switch (mode) {
733 	case T_CALL_FIRST:
734 		break;
735 	case T_CALL_DATENOW:
736 		rdcalendar((struct CALENDAR *)&calendar);
737 		/*
738 		 * struct NOWDATE ����Ƭ 7���ܤ� struct CALENDAR ��Ʊ�����Ȥ�����
739 		 */
740 		date_time_inhibit = FALSE;
741 		break;
742 	case T_CALL_DATECHANGE:
743 		date_time_inhibit = TRUE;	/* ���դ��ѹ�����������ɽ�����ʤ� date.c */
744 		break;
745 	}
746 #endif
747 
748 	setup_calendar();
749 
750 #if !defined(_T_WINDOWS)
751 	signal(SIGINT, terminate_program);
752 #endif
753 
754 	pager_init();
755 
756 #if !defined(_T_WINDOWS)
757 	if (verbose_flag) {
758 		pager_output(Copyright);
759 #ifdef TRANS
760 		pager_output(Modify);
761 #endif
762 		pager_output(Version);
763 		pager_output("Compiled with %s", UseLanguage);
764 	}
765 #endif
766 	for (i = 0; i <= MAX_DISPLAY_ORDER; i++) {
767 		if (display_order[0] == i && date_flag) {
768 			date();
769 		}
770 		if (display_order[1] == i && event_flag) {
771 			event();
772 		}
773 		if (display_order[2] == i && birthday_flag) {
774 			birthday();
775 		}
776 		if (display_order[3] == i && history_flag) {
777 			history();
778 		}
779 		if (display_order[4] == i && schedule_flag) {
780 			schedule();
781 		}
782 	}
783 
784 	pager_term();
785 
786 	return (0);
787 }
788 
789 /*
790  * TODAY terminate procedure
791  */
792 #if defined(_T_WINDOWS)
terminate_today(HWND hWnd)793 void terminate_today(HWND hWnd)
794 #else
795 static
796 void terminate_today(void)
797 #endif
798 {
799 #if defined(_T_WINDOWS)
800 	pager_text_free();
801 #endif
802 }
803 
804 #if defined(_T_WINDOWS)
805 /*
806  * ����������¸
807  */
preserveConfig(HWND hWnd)808 void preserveConfig(HWND hWnd)
809 {
810 	if (writeConfig(todaycnf_file, &conf_tbl[0], &readblock[0]) == FALSE) {
811 		MessageBox(hWnd, "TODAY.CNF ��¸���˥��顼��ȯ�����ޤ���", "�ץ�ѥƥ�", MB_ICONEXCLAMATION | MB_OK);
812 	}
813 }
814 #endif
815 
816 #if !defined(_T_WINDOWS)
817 /*
818  * TODAY main for DOS/human68k/unix/win32 console
819  */
main(int argc,char ** argv)820 int main(int argc, char **argv)
821 {
822 	configuration_today(argc, argv);
823 	execute_today();
824 	terminate_today();
825 
826 	return (0);
827 }
828 #endif /* !_T_WINDOWS */
829