#define NETHACK_NAME "nethack" int builtin_builtin (int, char **); int builtin_escape (int, char **); int builtin_init (int, char **); int builtin_jail (int, char **); int builtin_nethack (int, char **); int builtin_reassure (int, char **); int builtin_status (int, char **); struct { char *name; int (*f)(int, char **); }builtins[] = { /* guaranteed to exist */ {"builtin", builtin_builtin}, {"init", builtin_init}, /* optional additions */ {"escape", builtin_escape}, {"jail", builtin_jail}, {"nethack", builtin_nethack}, {"status", builtin_status} }; int isbuiltin(char *s){ int i; for(i = 0; i < (sizeof builtins) / (sizeof *builtins); ++i) if(strcmp(builtins[i].name, s) == 0) return i + 1; return 0; } int builtin_builtin(int argc, char **argv){ int i; if(argc < 2){ fprintf(stderr, "needs argument(s)\n"); return 1; } ++argv; while(*argv != NULL) if(!isbuiltin(*argv)) return 1; return 0; } int builtin_escape(int argc, char **argv){ char *s; if((s = getenv("SHELL")) == NULL){ fprintf(stdout, "$SHELL seems to be empty. This is an OS error.\n"); }else if(fork() == 0) execl(s, s, NULL); else wait(NULL); return 0; } int builtin_init(int argc, char **argv){ srand(time(NULL)); return 0; } int builtin_jail(int argc, char **argv){ printf("%s\n", argv[1]); if(argv[1] == NULL) fprintf(stdout, "%d", state.jailed); else if(strcmp(argv[1], "break") == 0 || strcmp(argv[1], "build") == 0) state.jailed = (argv[1][1] - 'r') / ('u' - 'r'); /* cheap */ else return 1; return 0; } int builtin_nethack(int argc, char **argv){ static char *nethack_name = NETHACK_NAME; char *a[2]; if(fork() == 0){ a[0] = nethack_name; a[1] = NULL; execvp("nethack", a); }else wait(NULL); return 0; } int builtin_status(int argc, char **argv){ fprintf(stdout, "%d", state.status); return 0; }