1 /*
2    XMascot Ver 2.6
3    Copyright(c) 1996,1997 Go Watanabe     go@cclub.tutcc.tut.ac.jp
4                           Tsuyoshi IIda   iida@cclub.tutcc.tut.ac.jp
5 */
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include "xmascot.h"
12 
13 /* ����ե����� */
14 #define RCFILE ".xmascotrc"
15 
16 extern Widget   top;
17 
18 #define LINEBUF 1024
19 
20 const char     *reserve1[] = {
21 	"dummy_no_data",
22 	"inter_timer",
23 	"houry_alarm",
24 	"half_alarm",
25 };
26 
27 const char     *reserve2[] = {
28 	"timer_action",
29 	"inter_action",
30 	"houry_action",
31 	"half_action",
32 };
33 
34 static char    *token_p;
35 static char     buf[LINEBUF + 1];
36 
37 void
set_token(char * p)38 set_token(char *p)
39 {
40 	token_p = p;
41 }
42 
43 char            token_buf[LINEBUF + 1];
44 int             token_dat;
45 
46 int
get_token(void)47 get_token(void)
48 {
49 	char            ch;
50 
51 	while ((ch = *token_p++) == ' ' || ch == '\t' || ch == '\n');
52 
53 	if (ch == '#' || ch == '\0')
54 		return NODAT;
55 
56 	if (ch == '"') {
57 		char           *p = token_buf;
58 		for (;;) {
59 			ch = *token_p++;
60 			if (ch == '"')
61 				break;
62 			else if (ch == '\\') {
63 				ch = *token_p++;
64 			}
65 			if (ch == '\n' || '\0')
66 				return NODAT;
67 			*p++ = ch;
68 		}
69 		*p = '\0';
70 		return STRING;
71 	} else if (isalnum(ch) || ch == '_' || ch == '.') {
72 		int             i;
73 		char           *p = token_buf;
74 		*p++ = ch;
75 		while (isalnum((ch = *token_p)) || ch == '_' || ch == '.') {
76 			*p++ = ch;
77 			token_p++;
78 		}
79 		*p = '\0';
80 		for (i = 0; i < ALARM_NUM; i++) {
81 			if (!strncmp("alarm", token_buf, 5) && token_buf[5] - '0' == i) {
82 				token_dat = i;
83 				return RESERVE;
84 			}
85 			if (!strncmp("action", token_buf, 6) && token_buf[6] - '0' == i) {
86 				token_dat = ALARM_ALLNUM + i;
87 				return RESERVE;
88 			}
89 		}
90 		for (i = 0; i < 4; i++) {
91 			if (!strcmp(reserve1[i], token_buf)) {
92 				token_dat = ALARM_NUM + i;
93 				return RESERVE;
94 			}
95 		}
96 		for (i = 0; i < 4; i++) {
97 			if (!strcmp(reserve2[i], token_buf)) {
98 				token_dat = ALARM_ALLNUM + ALARM_NUM + i;
99 				return RESERVE;
100 			}
101 		}
102 #ifdef BIFF
103 		if (!strcmp("biff_action", token_buf)) {
104 			token_dat = ALARM_ALLNUM + ALARM_NUM + 4;
105 			return RESERVE;
106 		}
107 #endif
108 		return ID;
109 	} else {
110 		token_dat = ch;
111 		return SYMBOL;
112 	}
113 }
114 
115 int
get_token2(void)116 get_token2(void)
117 {
118 	char            ch;
119 
120 	while ((ch = *token_p++) == ' ' || ch == '\t' || ch == '\n');
121 
122 	if (ch == '\0')
123 		return NODAT;
124 
125 	if (ch == '"') {
126 		char           *p = token_buf;
127 		for (;;) {
128 			ch = *token_p++;
129 			if (ch == '"')
130 				break;
131 			else if (ch == '\\') {
132 				ch = *token_p++;
133 			}
134 			if (ch == '\n' || '\0')
135 				return NODAT;
136 			*p++ = ch;
137 		}
138 		*p = '\0';
139 		return STRING;
140 	} else {
141 		char           *p = token_buf;
142 		*p++ = ch;
143 		while (!((ch = *token_p) == ' ' || ch == '\t' || ch == '\n' || ch == '\0')) {
144 			*p++ = ch;
145 			token_p++;
146 		}
147 		*p = '\0';
148 		return ID;
149 	}
150 }
151 
152 extern Alarm    alarm_dat[];
153 extern AppData  adat;
154 #ifdef BIFF
155 extern String   biff_action;
156 #endif
157 
158 void
get_rcfile(void)159 get_rcfile(void)
160 {
161 	FILE           *fp;
162 	char           *p, *path;
163 	int             i, num, hour;
164 
165 	for (i = 0; i < ALARM_ALLNUM; i++) {
166 		alarm_dat[i].sw =
167 			alarm_dat[i].hour =
168 			alarm_dat[i].min = 0;
169 		alarm_dat[i].action = XtNewString(adat.def_act);
170 		alarm_dat[i].id = -1;
171 	}
172 #ifdef BIFF
173 	biff_action = XtNewString(adat.biff_action);
174 #endif
175 	p = getenv("HOME");
176 	path = XtMalloc(strlen(p) + strlen(RCFILE) + 1 + 1);
177 	strcpy(path, p);
178 	strcat(path, "/");
179 	strcat(path, RCFILE);
180 	if ((fp = fopen(path, "r")) != NULL) {
181 		while (fgets(buf, LINEBUF, fp) != NULL) {
182 			set_token(buf);
183 			if (get_token() == RESERVE) {
184 #ifdef BIFF
185 				if (token_dat == ALARM_ALLNUM + ALARM_NUM + 4) {
186 					if (get_token() == STRING)
187 						set_new_string(&biff_action, token_buf);
188 				} else
189 #endif
190 				if (token_dat < ALARM_ALLNUM) {
191 					num = token_dat;
192 					if (get_token() == ID) {
193 						alarm_dat[num].sw = (strcmp(token_buf, "on")) ? 0 : 1;
194 					}
195 					if (get_token() == ID) {
196 						hour = atoi(token_buf);
197 						if (get_token() == SYMBOL && token_dat == ':')
198 							if (get_token() == ID) {
199 								alarm_dat[num].hour = hour;
200 								alarm_dat[num].min = atoi(token_buf);
201 							}
202 					}
203 				} else {
204 					num = token_dat - ALARM_ALLNUM;
205 					if (get_token() == STRING)
206 						set_new_string(&alarm_dat[num].action, token_buf);
207 				}
208 			}
209 		}
210 		fclose(fp);
211 	}
212 	XtFree(path);
213 	msg_out("Read .xmascotrc DONE.\n");
214 }
215 
216 static void
put_rc_string(FILE * fp,String str)217 put_rc_string(FILE * fp, String str)
218 {
219 	char           *p = str;
220 
221 	fputc('\"', fp);
222 	while (*p != '\0') {
223 		if (*p == '\"') {
224 			fputc('\\', fp);
225 			fputc('\"', fp);
226 		} else
227 			fputc(*p, fp);
228 		p++;
229 	}
230 	fprintf(fp, "\"\n");
231 }
232 
233 void
put_rcfile(void)234 put_rcfile(void)
235 {
236 	FILE           *fp;
237 	char           *p, *path;
238 	int             i, n;
239 
240 	p = getenv("HOME");
241 	path = XtMalloc(strlen(p) + strlen(RCFILE) + 1 + 1);
242 	strcpy(path, p);
243 	strcat(path, "/");
244 	strcat(path, RCFILE);
245 	if ((fp = fopen(path, "w")) != NULL) {
246 		for (i = 0; i < ALARM_NUM; i++) {
247 			fprintf(fp, "alarm%d %s %02d:%02d\n", i, (alarm_dat[i].sw) ? "on" : "off",
248 				alarm_dat[i].hour, alarm_dat[i].min);
249 			if (alarm_dat[i].action != NULL) {
250 				fprintf(fp, "action%d ", i);
251 				put_rc_string(fp, alarm_dat[i].action);
252 			}
253 		}
254 		for (i = 0; i < 4; i++) {
255 			n = ALARM_NUM + i;
256 			if (i == 1) {	/* interval */
257 				fprintf(fp, "%s %s %02d:%02d\n", reserve1[i],
258 					(alarm_dat[n].sw) ? "on" : "off",
259 					alarm_dat[n].hour, alarm_dat[n].min);
260 			} else if (i != 0) {
261 				fprintf(fp, "%s %s 00:00\n", reserve1[i],
262 					(alarm_dat[n].sw) ? "on" : "off");
263 			}
264 			if (alarm_dat[n].action != NULL) {
265 				fprintf(fp, "%s ", reserve2[i]);
266 				put_rc_string(fp, alarm_dat[n].action);
267 			}
268 		}
269 #ifdef BIFF
270 		/* for biff */
271 		if (biff_action != NULL) {
272 			fprintf(fp, "biff_action ");
273 			put_rc_string(fp, biff_action);
274 		}
275 #endif
276 		fclose(fp);
277 	} else
278 		err_out("warning: Can't write rcfile.");
279 	XtFree(path);
280 }
281 
282 /* ���������ζ�ư */
283 void
action_parse(char * action)284 action_parse(char *action)
285 {
286 	String          ptr[10];
287 	int             num, t;
288 	char           *act = NULL;
289 
290 	if (action == NULL)
291 		return;
292 	set_token(action);
293 	t = get_token();
294 
295 	for (;;) {
296 		if (t == NODAT)
297 			break;
298 		else if (t == ID) {
299 			num = 0;
300 			if (act != NULL)
301 				XtFree(act);
302 			act = XtNewString(token_buf);
303 			t = get_token();
304 			if (t == SYMBOL) {
305 				if (token_dat == '(') {
306 					t = get_token();
307 					for (; num < 10;) {
308 						if (t == NODAT)
309 							break;
310 						if (t == STRING || t == ID || t == RESERVE) {
311 							ptr[num++] = XtNewString(token_buf);
312 							t = get_token();
313 						} else if (t == SYMBOL && token_dat == ')') {
314 							t = get_token();
315 							break;
316 						} else
317 							t = get_token();
318 					}
319 					XtCallActionProc(top, act, NULL, ptr, num);
320 				} else
321 					XtCallActionProc(top, act, NULL, NULL, 0);
322 			} else
323 				XtCallActionProc(top, act, NULL, NULL, 0);
324 		} else
325 			t = get_token();
326 	}
327 	if (act != NULL)
328 		XtFree(act);
329 }
330