1 /* $NetBSD: init.c,v 1.14 2007/12/15 19:44:43 perry Exp $ */ 2 3 /* 4 * Copyright (c) 1988, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Timothy C. Stoehr. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include <sys/cdefs.h> 36 #ifndef lint 37 #if 0 38 static char sccsid[] = "@(#)init.c 8.1 (Berkeley) 5/31/93"; 39 #else 40 __RCSID("$NetBSD: init.c,v 1.14 2007/12/15 19:44:43 perry Exp $"); 41 #endif 42 #endif /* not lint */ 43 44 /* 45 * init.c 46 * 47 * This source herein may be modified and/or distributed by anybody who 48 * so desires, with the following restrictions: 49 * 1.) No portion of this notice shall be removed. 50 * 2.) Credit shall not be taken for the creation of this source. 51 * 3.) This code is not to be traded, sold, or used for personal 52 * gain or profit. 53 * 54 */ 55 56 #include <stdlib.h> 57 #include <fcntl.h> 58 59 #include "rogue.h" 60 61 char login_name[MAX_OPT_LEN]; 62 char *nick_name = (char *) 0; 63 char *rest_file = 0; 64 boolean cant_int = 0; 65 boolean did_int = 0; 66 boolean score_only; 67 boolean init_curses = 0; 68 boolean save_is_interactive = 1; 69 boolean ask_quit = 1; 70 boolean no_skull = 0; 71 boolean passgo = 0; 72 const char *error_file = "rogue.esave"; 73 const char *byebye_string = "Okay, bye bye!"; 74 gid_t gid, egid; 75 76 int 77 init(argc, argv) 78 int argc; 79 char *argv[]; 80 { 81 const char *pn; 82 int seed; 83 int fd; 84 85 gid = getgid(); 86 egid = getegid(); 87 setegid(gid); 88 /* Check for dirty tricks with closed fds 0, 1, 2 */ 89 fd = open("/dev/null", O_RDONLY); 90 if (fd < 3) 91 exit(1); 92 close(fd); 93 94 seed = 0; 95 pn = md_gln(); 96 if ((!pn) || (strlen(pn) >= MAX_OPT_LEN)) { 97 clean_up("Hey! Who are you?"); 98 } 99 (void) strcpy(login_name, pn); 100 101 do_args(argc, argv); 102 do_opts(); 103 104 if (!score_only && !rest_file) { 105 printf("Hello %s, just a moment while I dig the dungeon...", 106 nick_name); 107 fflush(stdout); 108 } 109 110 initscr(); 111 if ((LINES < DROWS) || (COLS < DCOLS)) { 112 clean_up("must be played on 24 x 80 screen"); 113 } 114 start_window(); 115 init_curses = 1; 116 117 md_heed_signals(); 118 119 if (score_only) { 120 put_scores((object *) 0, 0); 121 } 122 seed = md_gseed(); 123 (void) srrandom(seed); 124 if (rest_file) { 125 restore(rest_file); 126 return(1); 127 } 128 mix_colors(); 129 get_wand_and_ring_materials(); 130 make_scroll_titles(); 131 132 level_objects.next_object = (object *) 0; 133 level_monsters.next_monster = (object *) 0; 134 player_init(); 135 ring_stats(0); 136 return(0); 137 } 138 139 void 140 player_init() 141 { 142 object *obj; 143 144 rogue.pack.next_object = (object *) 0; 145 146 obj = alloc_object(); 147 get_food(obj, 1); 148 (void) add_to_pack(obj, &rogue.pack, 1); 149 150 obj = alloc_object(); /* initial armor */ 151 obj->what_is = ARMOR; 152 obj->which_kind = RINGMAIL; 153 obj->class = RINGMAIL+2; 154 obj->is_protected = 0; 155 obj->d_enchant = 1; 156 (void) add_to_pack(obj, &rogue.pack, 1); 157 do_wear(obj); 158 159 obj = alloc_object(); /* initial weapons */ 160 obj->what_is = WEAPON; 161 obj->which_kind = MACE; 162 obj->damage = "2d3"; 163 obj->hit_enchant = obj->d_enchant = 1; 164 obj->identified = 1; 165 (void) add_to_pack(obj, &rogue.pack, 1); 166 do_wield(obj); 167 168 obj = alloc_object(); 169 obj->what_is = WEAPON; 170 obj->which_kind = BOW; 171 obj->damage = "1d2"; 172 obj->hit_enchant = 1; 173 obj->d_enchant = 0; 174 obj->identified = 1; 175 (void) add_to_pack(obj, &rogue.pack, 1); 176 177 obj = alloc_object(); 178 obj->what_is = WEAPON; 179 obj->which_kind = ARROW; 180 obj->quantity = get_rand(25, 35); 181 obj->damage = "1d2"; 182 obj->hit_enchant = 0; 183 obj->d_enchant = 0; 184 obj->identified = 1; 185 (void) add_to_pack(obj, &rogue.pack, 1); 186 } 187 188 void 189 clean_up(estr) 190 const char *estr; 191 { 192 if (save_is_interactive) { 193 if (init_curses) { 194 move(DROWS-1, 0); 195 refresh(); 196 stop_window(); 197 } 198 printf("\n%s\n", estr); 199 } 200 md_exit(0); 201 } 202 203 void 204 start_window() 205 { 206 cbreak(); 207 noecho(); 208 #ifndef BAD_NONL 209 nonl(); 210 #endif 211 } 212 213 void 214 stop_window() 215 { 216 endwin(); 217 } 218 219 void 220 byebye(dummy) 221 int dummy __unused; 222 { 223 md_ignore_signals(); 224 if (ask_quit) { 225 quit(1); 226 } else { 227 clean_up(byebye_string); 228 } 229 md_heed_signals(); 230 } 231 232 void 233 onintr(dummy) 234 int dummy __unused; 235 { 236 md_ignore_signals(); 237 if (cant_int) { 238 did_int = 1; 239 } else { 240 check_message(); 241 message("interrupt", 1); 242 } 243 md_heed_signals(); 244 } 245 246 void 247 error_save(dummy) 248 int dummy __unused; 249 { 250 save_is_interactive = 0; 251 save_into_file(error_file); 252 clean_up(""); 253 } 254 255 void 256 do_args(argc, argv) 257 int argc; 258 char *argv[]; 259 { 260 short i, j; 261 262 for (i = 1; i < argc; i++) { 263 if (argv[i][0] == '-') { 264 for (j = 1; argv[i][j]; j++) { 265 switch(argv[i][j]) { 266 case 's': 267 score_only = 1; 268 break; 269 } 270 } 271 } else { 272 rest_file = argv[i]; 273 } 274 } 275 } 276 277 void 278 do_opts() 279 { 280 char *eptr; 281 282 if ((eptr = md_getenv("ROGUEOPTS")) != NULL) { 283 for (;;) { 284 while ((*eptr) == ' ') { 285 eptr++; 286 } 287 if (!(*eptr)) { 288 break; 289 } 290 if (!strncmp(eptr, "fruit=", 6)) { 291 eptr += 6; 292 env_get_value(&fruit, eptr, 1); 293 } else if (!strncmp(eptr, "file=", 5)) { 294 eptr += 5; 295 env_get_value(&save_file, eptr, 0); 296 } else if (!strncmp(eptr, "jump", 4)) { 297 jump = 1; 298 } else if (!strncmp(eptr, "name=", 5)) { 299 eptr += 5; 300 env_get_value(&nick_name, eptr, 0); 301 } else if (!strncmp(eptr, "noaskquit", 9)) { 302 ask_quit = 0; 303 } else if (!strncmp(eptr, "noskull", 5) || 304 !strncmp(eptr,"notomb", 6)) { 305 no_skull = 1; 306 } else if (!strncmp(eptr, "passgo", 5)) { 307 passgo = 1; 308 } 309 while ((*eptr) && (*eptr != ',')) { 310 eptr++; 311 } 312 if (!(*(eptr++))) { 313 break; 314 } 315 } 316 } 317 /* If some strings have not been set through ROGUEOPTS, assign defaults 318 * to them so that the options editor has data to work with. 319 */ 320 init_str(&nick_name, login_name); 321 init_str(&save_file, "rogue.save"); 322 init_str(&fruit, "slime-mold"); 323 } 324 325 void 326 env_get_value(s, e, add_blank) 327 char **s, *e; 328 boolean add_blank; 329 { 330 short i = 0; 331 const char *t; 332 333 t = e; 334 335 while ((*e) && (*e != ',')) { 336 if (*e == ':') { 337 *e = ';'; /* ':' reserved for score file purposes */ 338 } 339 e++; 340 if (++i >= MAX_OPT_LEN) { 341 break; 342 } 343 } 344 *s = md_malloc(MAX_OPT_LEN + 2); 345 if (*s == NULL) 346 clean_up("out of memory"); 347 (void) strncpy(*s, t, i); 348 if (add_blank) { 349 (*s)[i++] = ' '; 350 } 351 (*s)[i] = '\0'; 352 } 353 354 void 355 init_str(str, dflt) 356 char **str; 357 const char *dflt; 358 { 359 if (!(*str)) { 360 *str = md_malloc(MAX_OPT_LEN + 2); 361 if (*str == NULL) 362 clean_up("out of memory"); 363 (void) strcpy(*str, dflt); 364 } 365 } 366