Annotation of dgamelaunch-openbsd/dgl-common.c, Revision 1.2
1.1 rubenllo 1: /* Functions common to both dgamelaunch itself and dgl-wall. */
2:
3: #include "dgamelaunch.h"
4: #include "ttyrec.h"
5: #include <sys/stat.h>
6: #include <sys/types.h>
7: #include <sys/wait.h>
8: #include <dirent.h>
9: #include <stdio.h>
10: #include <fcntl.h>
11: #include <string.h>
12: #include <stdlib.h>
13: #include <signal.h>
14: #include <unistd.h>
15: #include <pwd.h>
16: #include <grp.h>
17: #include <curses.h>
18:
19: extern FILE* yyin;
20: extern int yyparse ();
21: extern void (*g_chain_winch)(int);
22:
23: /* Data structures */
24: struct dg_config **myconfig = NULL;
25: struct dg_config defconfig = {
26: /* game_path = */ "/bin/nethack",
27: /* game_name = */ "NetHack",
28: /* game_id = */ NULL,
29: /* shortname = */ "NH",
30: /* rcfile = */ NULL, /*"/dgl-default-rcfile",*/
31: /* ttyrecdir =*/ "%ruserdata/%n/ttyrec/",
32: /* spool = */ "/var/mail/",
33: /* inprogressdir = */ "%rinprogress/",
34: /* num_args = */ 0,
35: /* bin_args = */ NULL,
36: /* rc_fmt = */ "%rrcfiles/%n.nethackrc", /* [dglroot]rcfiles/[username].nethackrc */
37: /* cmdqueue = */ NULL,
38: /* postcmdqueue = */ NULL,
39: /* max_idle_time = */ 0,
40: /* extra_info_file = */ NULL,
41: /* encoding */ 0
42: };
43:
44: char* config = NULL;
45: int silent = 0;
46: int loggedin = 0;
47: char *chosen_name;
48: int num_games = 0;
49:
50: int shm_n_games = 200;
51:
52: int dgl_local_COLS = -1, dgl_local_LINES = -1;
53: int curses_resize = 0;
54:
55: int selected_game = 0;
56: int return_from_submenu = 0;
57:
58: mode_t default_fmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
59:
60: struct dg_globalconfig globalconfig;
61:
62: void
63: sigwinch_func(int sig)
64: {
65: signal(SIGWINCH, sigwinch_func);
66: curses_resize = 1;
67: g_chain_winch(sig);
68: }
69:
70: void
71: term_resize_check()
72: {
73: if ((COLS == dgl_local_COLS) && (LINES == dgl_local_LINES) && !curses_resize) return;
74:
75: signal(SIGWINCH, SIG_IGN);
76: endwin();
77: initcurses();
78: dgl_local_COLS = COLS;
79: dgl_local_LINES = LINES;
80: curses_resize = 0;
81: signal(SIGWINCH, sigwinch_func);
82: }
83:
84: int
85: check_retard(int reset)
86: {
87: static int retardation = 0; /* counter for retarded clients & flooding */
88: if (reset) retardation = 0;
89: else retardation++;
90: return ((retardation > 20) ? 1 : 0);
91: }
92:
93:
94: struct dg_menu *
95: dgl_find_menu(char *menuname)
96: {
97: struct dg_menulist *tmp = globalconfig.menulist;
98:
99: while (tmp) {
100: if (!strcmp(tmp->menuname, menuname)) return tmp->menu;
101: tmp = tmp->next;
102: }
103: return NULL;
104: }
105:
106: /*
107: * replace following codes with variables:
108: * %u == shed_uid (number)
109: * %n == user name (string; gotten from 'me', or from 'plrname' if 'me' is null)
110: * %r == chroot (string) (aka "dglroot" config var)
111: * %g == game name
112: * %s == short game name
113: * %t == ttyrec file (full path&name) of the last game played.
114: */
115: char *
116: dgl_format_str(int game, struct dg_user *me, char *str, char *plrname)
117: {
118: static char buf[1024];
119: char *f, *p, *end;
120: int ispercent = 0;
121: int isbackslash = 0;
122:
123: if (!str) return NULL;
124:
125: f = str;
126: p = buf;
127: end = buf + sizeof(buf) - 10;
128:
129: while (*f) {
130: if (ispercent) {
131: switch (*f) {
132: case 'u':
133: snprintf (p, end + 1 - p, "%d", globalconfig.shed_uid);
134: while (*p != '\0')
135: p++;
136: break;
137: case 'N':
138: if (me) *p = me->username[0];
139: else if (plrname) *p = plrname[0];
140: else return NULL;
141: p++;
142: *p = '\0';
143: break;
144: case 'n':
145: if (me) snprintf (p, end + 1 - p, "%s", me->username);
146: else if (plrname) snprintf(p, end + 1 - p, "%s", plrname);
147: else return NULL;
148: while (*p != '\0')
149: p++;
150: break;
151: case 'g':
152: if (game >= 0 && game < num_games && myconfig[game]) snprintf (p, end + 1 - p, "%s", myconfig[game]->game_name);
153: else return NULL;
154: while (*p != '\0')
155: p++;
156: break;
157: case 's':
158: if (game >= 0 && game < num_games && myconfig[game]) snprintf (p, end + 1 - p, "%s", myconfig[game]->shortname);
159: else return NULL;
160: while (*p != '\0')
161: p++;
162: break;
163: case 'r':
164: snprintf (p, end + 1 - p, "%s", globalconfig.dglroot);
165: while (*p != '\0')
166: p++;
167: break;
168: case 't':
169: snprintf (p, end + 1 - p, "%s", last_ttyrec);
170: while (*p != '\0')
171: p++;
172: break;
173: default:
174: *p = *f;
175: if (p < end)
176: p++;
177: }
178: ispercent = 0;
179: } else if (isbackslash) {
180: switch (*f) {
181: case 'a': *p = '\007'; break;
182: case 'b': *p = '\010'; break;
183: case 't': *p = '\011'; break;
184: case 'n': *p = '\012'; break;
185: case 'v': *p = '\013'; break;
186: case 'f': *p = '\014'; break;
187: case 'r': *p = '\015'; break;
188: case 'e': *p = '\033'; break;
189: default: *p = *f;
190: }
191: if (p < end)
192: p++;
193: isbackslash = 0;
194: } else {
195: if (*f == '%') {
196: ispercent = 1;
197: } else if (*f == '\\') {
198: isbackslash = 1;
199: } else {
200: *p = *f;
201: if (p < end)
202: p++;
203: }
204: }
205: f++;
206: }
207: *p = '\0';
208:
209: return buf;
210: }
211:
212: int
213: dgl_exec_cmdqueue(struct dg_cmdpart *queue, int game, struct dg_user *me)
214: {
215: int i;
216: struct dg_cmdpart *tmp = queue;
217: char *p1;
218: char *p2;
219: int played = 0;
220:
221: if (!queue) return 1;
222:
223: p1 = (char *)malloc(1024);
224: p2 = (char *)malloc(1024);
225:
226: if (!p1 || !p2) return 1;
227:
228: return_from_submenu = 0;
229:
230: while (tmp && !return_from_submenu) {
231: if (tmp->param1) strcpy(p1, dgl_format_str(game, me, tmp->param1, NULL));
232: if (tmp->param2) strcpy(p2, dgl_format_str(game, me, tmp->param2, NULL));
233:
234: switch (tmp->cmd) {
235: default: break;
236: case DGLCMD_RAWPRINT:
237: if (p1) fprintf(stdout, "%s", p1);
238: break;
239: case DGLCMD_MKDIR:
240: if (p1 && (access(p1, F_OK) != 0)) mkdir(p1, 0755);
241: break;
242: case DGLCMD_UNLINK:
243: if (p1 && (access(p1, F_OK) == 0)) unlink(p1);
244: break;
245: case DGLCMD_CHDIR:
246: if (p1) {
247: if (chdir(p1) == -1) {
248: debug_write("chdir-command failed");
249: graceful_exit(123);
250: }
251: }
252: break;
253: case DGLCMD_IF_NX_CP:
254: if (p1 && p2) {
255: FILE *tmpfile;
256: tmpfile = fopen(p2, "r");
257: if (tmpfile) {
258: fclose(tmpfile);
259: break;
260: }
261: }
262: /* else fall through to cp */
263: case DGLCMD_CP:
264: if (p1 && p2) {
265: FILE *cannedf, *newfile;
266: char buf[1024];
267: size_t bytes;
268: /* FIXME: use nethack-themed error messages here, as per write_canned_rcfile() */
269: if (!(cannedf = fopen (p1, "r"))) break;
270: if (!(newfile = fopen (p2, "w"))) break;
271: while ((bytes = fread (buf, 1, 1024, cannedf)) > 0) {
272: if (fwrite (buf, 1, bytes, newfile) != bytes) {
273: if (ferror (newfile)) {
274: fclose (cannedf);
275: fclose (newfile);
276: break;
277: }
278: }
279: }
280: fclose (cannedf);
281: fclose (newfile);
282: chmod (p2, default_fmode);
283: }
284: break;
285: case DGLCMD_EXEC:
286: if (p1 && p2) {
287: pid_t child;
288: char *myargv[3];
289:
290: myargv[0] = p1;
291: myargv[1] = p2;
292: myargv[2] = 0;
293:
294: clear();
295: refresh();
296: endwin();
297: idle_alarm_set_enabled(0);
298: child = fork();
299: if (child == -1) {
300: perror("fork");
301: debug_write("exec-command fork failed");
302: graceful_exit(114);
303: } else if (child == 0) {
304: execvp(p1, myargv);
305: exit(0);
306: } else
307: waitpid(child, NULL, 0);
308: idle_alarm_set_enabled(1);
309: initcurses();
310: check_retard(1);
311: }
312: break;
313: case DGLCMD_SETENV:
314: if (p1 && p2) mysetenv(p1, p2, 1);
315: break;
316: case DGLCMD_CHPASSWD:
317: if (loggedin) changepw(1);
318: break;
319: case DGLCMD_CHMAIL:
320: if (loggedin) change_email();
321: break;
322: case DGLCMD_WATCH_MENU:
323: inprogressmenu(-1);
324: break;
325: case DGLCMD_LOGIN:
326: if (!loggedin) loginprompt(0);
327: if (loggedin) runmenuloop(dgl_find_menu(get_mainmenu_name()));
328: break;
329: case DGLCMD_REGISTER:
330: if (!loggedin && globalconfig.allow_registration) newuser();
331: break;
332: case DGLCMD_QUIT:
333: debug_write("command: quit");
334: graceful_exit(0);
335: /* break; */
336: case DGLCMD_SUBMENU:
337: if (p1)
338: runmenuloop(dgl_find_menu(p1));
339: break;
340: case DGLCMD_RETURN:
341: return_from_submenu = 1;
342: break;
343: case DGLCMD_PLAY_IF_EXIST:
344: if (!(loggedin && me && p1 && p2)) break;
345: {
346: FILE *tmpfile;
347: tmpfile = fopen(p2, "r");
348: if (tmpfile) {
349: fclose(tmpfile);
350: } else break;
351: }
352: /* else fall through to playgame */
353: case DGLCMD_PLAYGAME:
354: if (loggedin && me && p1 && !played) {
355: int userchoice, i;
356: char *tmpstr;
357: for (userchoice = 0; userchoice < num_games; userchoice++) {
358: if (!strcmp(myconfig[userchoice]->game_id, p1) || !strcmp(myconfig[userchoice]->game_name, p1) || !strcmp(myconfig[userchoice]->shortname, p1)) {
359: if (purge_stale_locks(userchoice)) {
360: if (myconfig[userchoice]->rcfile) {
361: if (access (dgl_format_str(userchoice, me, myconfig[userchoice]->rc_fmt, NULL), R_OK) == -1)
362: write_canned_rcfile (userchoice, dgl_format_str(userchoice, me, myconfig[userchoice]->rc_fmt, NULL));
363: }
364:
365: setproctitle("%s [playing %s]", me->username, myconfig[userchoice]->shortname);
366:
367: clear();
368: refresh();
369: endwin ();
370:
371: /* first run the generic "do these when a game is started" commands */
372: dgl_exec_cmdqueue(globalconfig.cmdqueue[DGLTIME_GAMESTART], userchoice, me);
373: /* then run the game-specific commands */
374: dgl_exec_cmdqueue(myconfig[userchoice]->cmdqueue, userchoice, me);
375:
376: /* fix the variables in the arguments */
377: for (i = 0; i < myconfig[userchoice]->num_args; i++) {
378: tmpstr = strdup(dgl_format_str(userchoice, me, myconfig[userchoice]->bin_args[i], NULL));
379: free(myconfig[userchoice]->bin_args[i]);
380: myconfig[userchoice]->bin_args[i] = tmpstr;
381: }
382:
383: signal(SIGWINCH, SIG_DFL);
384: signal(SIGINT, SIG_DFL);
385: signal(SIGQUIT, SIG_DFL);
386: signal(SIGTERM, SIG_DFL);
387: idle_alarm_set_enabled(0);
388: /* launch program */
389: ttyrec_main (userchoice, me->username,
390: dgl_format_str(userchoice, me, myconfig[userchoice]->ttyrecdir, NULL),
391: gen_ttyrec_filename());
392: idle_alarm_set_enabled(1);
393: played = 1;
394: /* lastly, run the generic "do these when a game is left" commands */
395: signal (SIGHUP, catch_sighup);
396: signal (SIGINT, catch_sighup);
397: signal (SIGQUIT, catch_sighup);
398: signal (SIGTERM, catch_sighup);
399: signal(SIGWINCH, sigwinch_func);
400:
401: dgl_exec_cmdqueue(myconfig[userchoice]->postcmdqueue, userchoice, me);
402:
403: dgl_exec_cmdqueue(globalconfig.cmdqueue[DGLTIME_GAMEEND], userchoice, me);
404:
405: setproctitle ("%s", me->username);
406: initcurses ();
407: check_retard(1); /* reset retard counter */
408: }
409: break;
410: }
411: }
412: }
413: break;
414: }
415: tmp = tmp->next;
416: }
417:
418: free(p1);
419: free(p2);
420:
421: return 0;
422: }
423:
424:
425:
426: static int
427: sort_game_username(const void *g1, const void *g2)
428: {
429: const struct dg_game *game1 = *(const struct dg_game **)g1;
430: const struct dg_game *game2 = *(const struct dg_game **)g2;
431: return strcasecmp(game1->name, game2->name);
432: }
433:
434: time_t sort_ctime;
435:
436: static int
437: sort_game_idletime(const void *g1, const void *g2)
438: {
439: const struct dg_game *game1 = *(const struct dg_game **)g1;
440: const struct dg_game *game2 = *(const struct dg_game **)g2;
441: if ((sort_ctime - game1->idle_time < 5) && (sort_ctime - game2->idle_time < 5))
442: return strcasecmp(game1->name, game2->name);
443: if (game2->idle_time != game1->idle_time)
444: return difftime(game2->idle_time, game1->idle_time);
445: else
446: return strcasecmp(game1->name, game2->name);
447: }
448:
449: static int
450: sort_game_extrainfo(const void *g1, const void *g2)
451: {
452: const int extra_weight1 =
453: (*(const struct dg_game **) g1)->extra_info_weight;
454: const int extra_weight2 =
455: (*(const struct dg_game **) g2)->extra_info_weight;
456: return dglsign(extra_weight2 - extra_weight1);
457: }
458:
459: static int
460: sort_game_gamenum(const void *g1, const void *g2)
461: {
462: const struct dg_game *game1 = *(const struct dg_game **)g1;
463: const struct dg_game *game2 = *(const struct dg_game **)g2;
464: if (game2->gamenum != game1->gamenum)
465: return dglsign(game2->gamenum - game1->gamenum);
466: else
467: return strcasecmp(game1->name, game2->name);
468: }
469:
470: static int
471: sort_game_windowsize(const void *g1, const void *g2)
472: {
473: const struct dg_game *game1 = *(const struct dg_game **)g1;
474: const struct dg_game *game2 = *(const struct dg_game **)g2;
475: if (game2->ws_col != game1->ws_col)
476: return dglsign(game1->ws_col - game2->ws_col);
477: if (game2->ws_row != game1->ws_row)
478: return dglsign(game1->ws_row - game2->ws_row);
479: return strcasecmp(game1->name, game2->name);
480: }
481:
482: static int
483: sort_game_starttime(const void *g1, const void *g2)
484: {
485: const struct dg_game *game1 = *(const struct dg_game **)g1;
486: const struct dg_game *game2 = *(const struct dg_game **)g2;
487: int i = strcmp(game1->date, game2->date);
488: if (!i)
489: i = strcmp(game1->time, game2->time);
490: if (!i)
491: return strcasecmp(game1->name, game2->name);
492: return i;
493: }
494:
495: static int
496: sort_game_watchers(const void *g1, const void *g2)
497: {
498: const struct dg_game *game1 = *(const struct dg_game **)g1;
499: const struct dg_game *game2 = *(const struct dg_game **)g2;
500: int i = dglsign(game2->nwatchers - game1->nwatchers);
501: if (!i && (sort_ctime - game1->idle_time < 5) && (sort_ctime - game2->idle_time < 5))
502: return strcasecmp(game1->name, game2->name);
503: if (!i)
504: i = dglsign(game2->idle_time - game1->idle_time);
505: if (!i)
506: return strcasecmp(game1->name, game2->name);
507: return i;
508: }
509:
510: struct dg_game **
511: sort_games (struct dg_game **games, int len, dg_sortmode sortmode)
512: {
513: switch (sortmode) {
514: case SORTMODE_USERNAME: qsort(games, len, sizeof(struct dg_game *), sort_game_username); break;
515: case SORTMODE_GAMENUM: qsort(games, len, sizeof(struct dg_game *), sort_game_gamenum); break;
516: case SORTMODE_WINDOWSIZE: qsort(games, len, sizeof(struct dg_game *), sort_game_windowsize); break;
517: case SORTMODE_IDLETIME:
518: (void) time(&sort_ctime);
519: qsort(games, len, sizeof(struct dg_game *), sort_game_idletime);
520: break;
521: case SORTMODE_DURATION:
522: case SORTMODE_STARTTIME: qsort(games, len, sizeof(struct dg_game *), sort_game_starttime); break;
523:
524: case SORTMODE_EXTRA_INFO:
525: qsort(games, len, sizeof(struct dg_game *),
526: sort_game_extrainfo);
527: break;
528:
529: #ifdef USE_SHMEM
530: case SORTMODE_WATCHERS:
531: (void) time(&sort_ctime);
532: qsort(games, len, sizeof(struct dg_game *), sort_game_watchers);
533: break;
534: #endif
535: default: ;
536: }
537: return games;
538: }
539:
540: #ifdef USE_DEBUGFILE
541: void
542: debug_write(char *str)
543: {
544: FILE *fp;
545: fp = fopen("/dgldebug.log", "a");
546: if (!fp) return;
547: fprintf(fp, "%s\n", str);
548: fclose(fp);
549:
550: }
551: #endif /* USE_DEBUGFILE */
552:
553: void
554: free_populated_games(struct dg_game **games, int len)
555: {
556: int i;
557: if (!games || (len < 1)) return;
558:
559: for (i = 0; i < len; i++) {
560: if (games[i]->ttyrec_fn) free(games[i]->ttyrec_fn);
561: if (games[i]->name) free(games[i]->name);
562: if (games[i]->date) free(games[i]->date);
563: if (games[i]->time) free(games[i]->time);
564: if (games[i]->extra_info) free(games[i]->extra_info);
565: free(games[i]);
566: }
567: free(games);
568: }
569:
570: static
571: void
572: game_read_extra_info(struct dg_game *game, const char *extra_info_file)
573: {
574: FILE *ei = NULL;
575: char *sep = NULL;
576: char buffer[120];
577: int buflen;
578:
579: if (game->extra_info) {
580: free(game->extra_info);
581: game->extra_info = NULL;
582: }
583: game->extra_info_weight = 0;
584:
585: if (!extra_info_file)
586: return;
587:
588: if (!(ei = fopen(extra_info_file, "r")))
589: return;
590: *buffer = 0;
591: fgets(buffer, sizeof buffer, ei);
592: fclose(ei);
593:
594: buflen = strlen(buffer);
595: if (buflen && buffer[buflen - 1] == '\n')
596: buffer[buflen - 1] = 0;
597:
598: /* The extra info file format is <sort-weight>|<info> */
599: sep = strchr(buffer, '|');
600: game->extra_info = strdup(sep? sep + 1 : buffer);
601:
602: if (sep) {
603: *sep = 0;
604: game->extra_info_weight = atoi(buffer);
605: }
606: }
607:
608: struct dg_game **
609: populate_games (int xgame, int *l, struct dg_user *me)
610: {
611: int fd, len, n, pid;
612: DIR *pdir;
613: struct dirent *pdirent;
614: struct stat pstat;
615: char fullname[130], ttyrecname[130], pidws[80], playername[DGL_PLAYERNAMELEN+1];
616: char *replacestr, *dir, *p;
617: struct dg_game **games = NULL;
618: struct flock fl = { 0 };
619:
620: int game;
621:
622: fl.l_type = F_WRLCK;
623: fl.l_whence = SEEK_SET;
624: fl.l_start = 0;
625: fl.l_len = 0;
626:
627: len = 0;
628:
629: for (game = ((xgame < 0) ? 0 : xgame); game < ((xgame <= 0) ? num_games : (xgame+1)); game++) {
630:
631: dir = strdup(dgl_format_str(game, me, myconfig[game]->inprogressdir, NULL));
632: if (!dir) continue;
633:
634: if (!(pdir = opendir (dir))) {
635: debug_write("cannot open inprogress-dir");
636: graceful_exit (140);
637: }
638:
639: while ((pdirent = readdir (pdir)))
640: {
641: char *inprog = NULL;
642: if (!strcmp (pdirent->d_name, ".") || !strcmp (pdirent->d_name, ".."))
643: continue;
644:
645: inprog = dgl_format_str(game, me, myconfig[game]->inprogressdir, NULL);
646:
647: if (!inprog) continue;
648:
649: snprintf (fullname, 130, "%s%s", inprog, pdirent->d_name);
650:
651: fd = 0;
652: /* O_RDWR here should be O_RDONLY, but we need to test for
653: * an exclusive lock */
654: fd = open (fullname, O_RDWR);
655: if (fd >= 0 && (fcntl (fd, F_SETLK, &fl) == -1))
656: {
657: char *ttrecdir = NULL;
658: strncpy(playername, pdirent->d_name, DGL_PLAYERNAMELEN);
659: playername[DGL_PLAYERNAMELEN] = '\0';
660: if ((replacestr = strchr(playername, ':')))
661: *replacestr = '\0';
662:
663: replacestr = strchr(pdirent->d_name, ':');
664: if (!replacestr) {
665: debug_write("inprogress-filename does not have ':'");
666: graceful_exit(145);
667: }
668: replacestr++;
669:
670: ttrecdir = dgl_format_str(game, me, myconfig[game]->ttyrecdir, playername);
671: if (!ttrecdir) continue;
672: snprintf (ttyrecname, 130, "%s%s", ttrecdir, replacestr);
673:
674: if (!stat (ttyrecname, &pstat))
675: {
676: /* now it's a valid game for sure */
677: games = realloc (games, sizeof (struct dg_game) * (len + 1));
678: games[len] = malloc (sizeof (struct dg_game));
679: games[len]->ttyrec_fn = strdup (ttyrecname);
680:
681: if (!(replacestr = strchr (pdirent->d_name, ':'))) {
682: debug_write("inprogress-filename does not have ':', pt. 2");
683: graceful_exit (146);
684: } else
685: *replacestr = '\0';
686:
687: games[len]->name = malloc (strlen (pdirent->d_name) + 1);
688: strlcpy (games[len]->name, pdirent->d_name,
689: strlen (pdirent->d_name) + 1);
690:
691: games[len]->date = malloc (11);
692: strlcpy (games[len]->date, replacestr + 1, 11);
693:
694: games[len]->time = malloc (9);
695: strlcpy (games[len]->time, replacestr + 12, 9);
696:
697: games[len]->idle_time = pstat.st_mtime;
698:
699: games[len]->gamenum = game;
700: games[len]->is_in_shm = 0;
701: games[len]->nwatchers = 0;
702: games[len]->shm_idx = -1;
703:
704: n = read(fd, pidws, sizeof(pidws) - 1);
705: if (n > 0)
706: {
707: pidws[n] = '\0';
708: p = pidws;
709: }
710: else
711: p = "";
712: pid = atoi(p);
713: while (*p != '\0' && *p != '\n')
714: p++;
715: if (*p != '\0')
716: p++;
717: games[len]->ws_row = atoi(p);
718: while (*p != '\0' && *p != '\n')
719: p++;
720: if (*p != '\0')
721: p++;
722: games[len]->ws_col = atoi(p);
723:
724: if (games[len]->ws_row < 4 || games[len]->ws_col < 4) {
725: games[len]->ws_row = 24;
726: games[len]->ws_col = 80;
727: }
728:
729: games[len]->extra_info = NULL;
730: games[len]->extra_info_weight = 0;
731: if (myconfig[game]->extra_info_file) {
732: char *extra_info_file =
733: dgl_format_str(game, NULL,
734: myconfig[game]->extra_info_file,
735: games[len]->name);
736: game_read_extra_info(games[len], extra_info_file);
737: }
738:
739: len++;
740: }
741: }
742: else
743: {
744: /* clean dead ones */
745: unlink (fullname);
746: }
747: close (fd);
748:
749: fl.l_type = F_WRLCK;
750: }
751:
752: closedir (pdir);
753: }
754: *l = len;
755: return games;
756: }
757:
758: void
759: graceful_exit (int status)
760: {
761: /*FILE *fp;
762: if (status != 1)
763: {
764: fp = fopen ("/crash.log", "a");
765: char buf[100];
766: sprintf (buf, "graceful_exit called with status %d", status);
767: fputs (buf, fp);
768: }
769: This doesn't work. Ever.
770: */
771: endwin();
772: exit (status);
773: }
774:
775: void
776: create_config ()
777: {
778: FILE *config_file = NULL;
779: int tmp;
780:
781: if (!globalconfig.allow_registration) globalconfig.allow_registration = 1;
782: globalconfig.menulist = NULL;
783: globalconfig.banner_var_list = NULL;
784: globalconfig.locale = NULL;
785: globalconfig.defterm = NULL;
786:
787: globalconfig.shed_uid = (uid_t)-1;
788: globalconfig.shed_gid = (gid_t)-1;
789:
790: globalconfig.sortmode = SORTMODE_USERNAME;
791: globalconfig.utf8esc = 0;
792: globalconfig.flowctrl = -1; /* undefined, don't touch it */
793:
794: if (config)
795: {
796: if ((config_file = fopen(config, "r")) != NULL)
797: {
798: yyin = config_file;
799: yyparse();
800: fclose(config_file);
801: free (config);
802: }
803: else
804: {
805: fprintf(stderr, "ERROR: can't find or open %s for reading\n", config);
806: debug_write("cannot read config file");
807: graceful_exit(104);
808: return;
809: }
810: }
811: else
812: {
813: #ifdef DEFCONFIG
814: config = DEFCONFIG;
815: if ((config_file = fopen(DEFCONFIG, "r")) != NULL)
816: {
817: yyin = config_file;
818: yyparse();
819: fclose(config_file);
820: } else {
821: fprintf(stderr, "ERROR: can't find or open %s for reading\n", config);
822: debug_write("cannot read default config file");
823: graceful_exit(105);
824: return;
825: }
826: #else
827: num_games = 0;
828: myconfig = calloc(1, sizeof(myconfig[0]));
829: myconfig[0] = &defconfig;
830: return;
831: #endif
832: }
833:
834: if (!myconfig) /* a parse error occurred */
835: {
836: fprintf(stderr, "ERROR: configuration parsing failed\n");
837: debug_write("config file parsing failed");
838: graceful_exit(113);
839: }
840:
841: if (!globalconfig.chroot) globalconfig.chroot = "/var/lib/dgamelaunch/";
842:
843: if (globalconfig.max == 0) globalconfig.max = 64000;
844: if (globalconfig.max_newnick_len == 0) globalconfig.max_newnick_len = DGL_PLAYERNAMELEN;
845: if (!globalconfig.dglroot) globalconfig.dglroot = "/dgldir/";
846: if (!globalconfig.banner) globalconfig.banner = "/dgl-banner";
847:
848: #ifndef USE_SQLITE3
1.2 ! rubenllo 849: if (!globalconfig.passwd) globalconfig.passwd = "/dgldir/dgl-login";
1.1 rubenllo 850: #else
851: if (!globalconfig.passwd) globalconfig.passwd = USE_SQLITE_DB;
852: #endif
1.2 ! rubenllo 853: if (!globalconfig.lockfile) globalconfig.lockfile = "/dgldir/dgl-lock";
1.1 rubenllo 854: if (!globalconfig.shed_user && globalconfig.shed_uid == (uid_t)-1)
855: {
856: struct passwd *pw;
857: if ((pw = getpwnam("games")))
858: globalconfig.shed_uid = pw->pw_uid;
859: else
860: globalconfig.shed_uid = 5; /* games uid in debian */
861: }
862:
863: if (!globalconfig.shed_group && globalconfig.shed_gid == (gid_t)-1)
864: {
865: struct group *gr;
866: if ((gr = getgrnam("games")))
867: globalconfig.shed_gid = gr->gr_gid;
868: else
869: globalconfig.shed_gid = 60; /* games gid in debian */
870: }
871:
872: }
CVSweb