From 6aa48afdd57d03314fdf4be6c9da911c32277c84 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Fri, 8 Jan 2010 20:28:34 +0100 Subject: Import tome-2.3.5. --- src/files.c | 7219 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 7219 insertions(+) create mode 100644 src/files.c (limited to 'src/files.c') diff --git a/src/files.c b/src/files.c new file mode 100644 index 00000000..8c934c8c --- /dev/null +++ b/src/files.c @@ -0,0 +1,7219 @@ +/* File: files.c */ + +/* Purpose: code dealing with files (and death) */ + +/* + * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke + * + * This software may be copied and distributed for educational, research, and + * not for profit purposes provided that this copyright and statement are + * included in all such copies. + */ + +#include "angband.h" + + +static bool setuid_grabbed = TRUE; + + +/* + * You may or may not want to use the following "#undef". + */ +/* #undef _POSIX_SAVED_IDS */ + + +/* + * Hack -- drop permissions + */ +void safe_setuid_drop(void) +{ + if (setuid_grabbed) + { + setuid_grabbed = FALSE; +#ifdef SET_UID + +# ifdef SAFE_SETUID + +# ifdef SAFE_SETUID_POSIX + + if (setuid(getuid()) != 0) + { + quit("setuid(): cannot set permissions correctly!"); + } + if (setgid(getgid()) != 0) + { + quit("setgid(): cannot set permissions correctly!"); + } + +# else + + if (setreuid(geteuid(), getuid()) != 0) + { + quit("setreuid(): cannot set permissions correctly!"); + } + if (setregid(getegid(), getgid()) != 0) + { + quit("setregid(): cannot set permissions correctly!"); + } + +# endif + +# endif + +#endif + } + +} + + +/* + * Hack -- grab permissions + */ +void safe_setuid_grab(void) +{ + if (!setuid_grabbed) + { + setuid_grabbed = TRUE; +#ifdef SET_UID + +# ifdef SAFE_SETUID + +# ifdef SAFE_SETUID_POSIX + + if (setuid(player_euid) != 0) + { + quit("setuid(): cannot set permissions correctly!"); + } + if (setgid(player_egid) != 0) + { + quit("setgid(): cannot set permissions correctly!"); + } + +# else + + if (setreuid(geteuid(), getuid()) != 0) + { + quit("setreuid(): cannot set permissions correctly!"); + } + if (setregid(getegid(), getgid()) != 0) + { + quit("setregid(): cannot set permissions correctly!"); + } + +# endif /* SAFE_SETUID_POSIX */ + +# endif /* SAFE_SETUID */ + +#endif /* SET_UID */ + } + +} + + +/* + * Extract the first few "tokens" from a buffer + * + * This function uses "colon" and "slash" and delim arg as the delimeter characters. + * + * We never extract more than "num" tokens. The "last" token may include + * "delimeter" characters, allowing the buffer to include a "string" token. + * + * We save pointers to the tokens in "tokens", and return the number found. + * + * Hack -- Attempt to handle the 'c' character formalism + * + * Hack -- An empty buffer, or a final delimeter, yields an "empty" token. + * + * Hack -- We will always extract at least one token + */ +s16b tokenize(char *buf, s16b num, char **tokens, char delim1, char delim2) +{ + int i = 0; + + char *s = buf; + + + /* Process */ + while (i < num - 1) + { + char *t; + + /* Scan the string */ + for (t = s; *t; t++) + { + /* Found a delimiter */ + if ((*t == delim1) || (*t == delim2)) break; + + /* Handle single quotes */ + if (*t == '\'') + { + /* Advance */ + t++; + + /* Handle backslash */ + if (*t == '\\') t++; + + /* Require a character */ + if (!*t) break; + + /* Advance */ + t++; + + /* Hack -- Require a close quote */ + if (*t != '\'') *t = '\''; + } + + /* Handle back-slash */ + if (*t == '\\') t++; + } + + /* Nothing left */ + if (!*t) break; + + /* Nuke and advance */ + *t++ = '\0'; + + /* Save the token */ + tokens[i++] = s; + + /* Advance */ + s = t; + } + + /* Save the token */ + tokens[i++] = s; + + /* Number found */ + return (i); +} + + + +/* + * Parse a sub-file of the "extra info" (format shown below) + * + * Each "action" line has an "action symbol" in the first column, + * followed by a colon, followed by some command specific info, + * usually in the form of "tokens" separated by colons or slashes. + * + * Blank lines, lines starting with white space, and lines starting + * with pound signs ("#") are ignored (as comments). + * + * Note the use of "tokenize()" to allow the use of both colons and + * slashes as delimeters, while still allowing final tokens which + * may contain any characters including "delimiters". + * + * Note the use of "strtol()" to allow all "integers" to be encoded + * in decimal, hexidecimal, or octal form. + * + * Note that "monster zero" is used for the "player" attr/char, "object + * zero" will be used for the "stack" attr/char, and "feature zero" is + * used for the "nothing" attr/char. + * + * Parse another file recursively, see below for details + * %: + * + * Specify the attr/char values for "monsters" by race index + * R::: + * + * Specify the attr/char values for "objects" by kind index + * K::: + * + * Specify the attr/char values for "features" by feature index + * F::: + * + * Specify the attr/char values for "stores" by store index + * B::: + * + * Specify the attr/char values for unaware "objects" by kind tval + * U::: + * + * Specify the attr/char values for inventory "objects" by kind tval + * E::: + * + * Define a macro action, given an encoded macro action + * A: + * + * Create a normal macro, given an encoded macro trigger + * P: + * + * Create a command macro, given an encoded macro trigger + * C: + * + * Create a keyset mapping + * S::: + * + * Turn an option off, given its name + * X: + * + * Turn an option on, given its name + * Y: + * + * Specify visual information, given an index, and some data + * V::::: + * + * Specify squelch settings + * Q:: + */ +errr process_pref_file_aux(char *buf) +{ + int i, j, n1, n2; + + char *zz[16]; + + + /* Skip "empty" lines */ + if (!buf[0]) return (0); + + /* Skip "blank" lines */ + if (isspace(buf[0])) return (0); + + /* Skip comments */ + if (buf[0] == '#') return (0); + + /* Require "?:*" format */ + if (buf[1] != ':') return (1); + + + /* Process "%:" */ + if (buf[0] == '%') + { + /* Attempt to Process the given file */ + return (process_pref_file(buf + 2)); + } + + + /* Process "R::/" -- attr/char for monster races */ + if (buf[0] == 'R') + { + if (tokenize(buf + 2, 3, zz, ':', '/') == 3) + { + monster_race *r_ptr; + i = (huge)strtol(zz[0], NULL, 0); + n1 = strtol(zz[1], NULL, 0); + n2 = strtol(zz[2], NULL, 0); + if (i >= max_r_idx) return (1); + r_ptr = &r_info[i]; + if (n1) r_ptr->x_attr = n1; + if (n2) + { + r_ptr->x_char = n2; + } + return (0); + } + } + + + /* Process "G:::/" -- attr/char for overlay graphics */ + if (buf[0] == 'G') + { + /* Process "G:M::/" -- attr/char for ego monsters */ + if (buf[2] == 'M') + { + if (tokenize(buf + 4, 3, zz, ':', '/') == 3) + { + monster_ego *re_ptr; + i = (huge)strtol(zz[0], NULL, 0); + n1 = strtol(zz[1], NULL, 0); + n2 = strtol(zz[2], NULL, 0); + if (i >= max_re_idx) return (1); + re_ptr = &re_info[i]; + if (n1) re_ptr->g_attr = n1; + if (n2) + { + re_ptr->g_char = n2; + } + return (0); + } + } + + /* Process "G:P::/" -- attr/char for race modifiers */ + if (buf[2] == 'P') + { + if (tokenize(buf + 4, 3, zz, ':', '/') == 3) + { + player_race_mod *rmp_ptr; + i = (huge)strtol(zz[0], NULL, 0); + n1 = strtol(zz[1], NULL, 0); + n2 = strtol(zz[2], NULL, 0); + if (i >= max_rmp_idx) return (1); + rmp_ptr = &race_mod_info[i]; + if (n1) rmp_ptr->g_attr = n1; + if (n2) + { + rmp_ptr->g_char = n2; + } + return (0); + } + } + + /* Process "G:T::/" -- attr/char for traps */ + if (buf[2] == 'T') + { + if (tokenize(buf + 4, 3, zz, ':', '/') == 3) + { + trap_type *t_ptr; + i = (huge)strtol(zz[0], NULL, 0); + n1 = strtol(zz[1], NULL, 0); + n2 = strtol(zz[2], NULL, 0); + if (i >= max_t_idx) return (1); + t_ptr = &t_info[i]; + if (n1) t_ptr->g_attr = n1; + if (n2) + { + t_ptr->g_char = n2; + } + return (0); + } + } + } + + + /* Process "K::/" -- attr/char for object kinds */ + else if (buf[0] == 'K') + { + if (tokenize(buf + 2, 3, zz, ':', '/') == 3) + { + object_kind *k_ptr; + i = (huge)strtol(zz[0], NULL, 0); + n1 = strtol(zz[1], NULL, 0); + n2 = strtol(zz[2], NULL, 0); + if (i >= max_k_idx) return (1); + k_ptr = &k_info[i]; + if (n1) k_ptr->x_attr = n1; + if (n2) + { + k_ptr->x_char = n2; + } + return (0); + } + } + + + /* Process "F::/" -- attr/char for terrain features */ + else if (buf[0] == 'F') + { + if (tokenize(buf + 2, 3, zz, ':', '/') == 3) + { + feature_type *f_ptr; + i = (huge)strtol(zz[0], NULL, 0); + n1 = strtol(zz[1], NULL, 0); + n2 = strtol(zz[2], NULL, 0); + if (i >= max_f_idx) return (1); + f_ptr = &f_info[i]; + if (n1) f_ptr->x_attr = n1; + if (n2) + { + f_ptr->x_char = n2; + } + return (0); + } + } + + /* Process "B::/" -- attr/char for stores */ + else if (buf[0] == 'B') + { + if (tokenize(buf + 2, 3, zz, ':', '/') == 3) + { + store_info_type *st_ptr; + i = (huge)strtol(zz[0], NULL, 0); + n1 = strtol(zz[1], NULL, 0); + n2 = strtol(zz[2], NULL, 0); + if (i >= max_st_idx) return (1); + st_ptr = &st_info[i]; + if (n1) st_ptr->x_attr = n1; + if (n2) st_ptr->x_char = n2; + return (0); + } + } + + /* Process "S::/" -- attr/char for special things */ + else if (buf[0] == 'S') + { + if (tokenize(buf + 2, 3, zz, ':', '/') == 3) + { + j = (byte)strtol(zz[0], NULL, 0); + n1 = strtol(zz[1], NULL, 0); + n2 = strtol(zz[2], NULL, 0); + misc_to_attr[j] = n1; + misc_to_char[j] = n2; + return (0); + } + } + + /* Process "U::/" -- attr/char for unaware items */ + else if (buf[0] == 'U') + { + if (tokenize(buf + 2, 3, zz, ':', '/') == 3) + { + j = (huge)strtol(zz[0], NULL, 0); + n1 = strtol(zz[1], NULL, 0); + n2 = strtol(zz[2], NULL, 0); + for (i = 1; i < max_k_idx; i++) + { + object_kind *k_ptr = &k_info[i]; + if (k_ptr->tval == j) + { + if (n1) k_ptr->d_attr = n1; + if (n2) k_ptr->d_char = n2; + } + } + return (0); + } + } + + + /* Process "E::" -- attribute for inventory objects */ + else if (buf[0] == 'E') + { + if (tokenize(buf + 2, 2, zz, ':', '/') == 2) + { + j = (byte)strtol(zz[0], NULL, 0) % 128; + n1 = strtol(zz[1], NULL, 0); + if (n1) tval_to_attr[j] = n1; + return (0); + } + } + + + /* Process "A:" -- save an "action" for later */ + else if (buf[0] == 'A') + { + text_to_ascii(macro__buf, buf + 2); + return (0); + } + + /* Process "P:" -- normal macro */ + else if (buf[0] == 'P') + { + char tmp[1024]; + text_to_ascii(tmp, buf + 2); + macro_add(tmp, macro__buf); + return (0); + } + + /* Process "L::: -- extended command macro */ + else if (buf[0] == 'L') + { + switch (tokenize(buf + 2, 3, zz, ':', 0)) + { + case 3: + cli_add(zz[0], zz[1], zz[2]); + return 0; + case 2: + cli_add(zz[0], zz[1], 0); + return 0; + default: + return 1; + } + } + + /* Process "C:" -- create keymap */ + else if (buf[0] == 'C') + { + int mode; + + char tmp[1024]; + + if (tokenize(buf + 2, 2, zz, ':', '/') != 2) return (1); + + mode = strtol(zz[0], NULL, 0); + if ((mode < 0) || (mode >= KEYMAP_MODES)) return (1); + + text_to_ascii(tmp, zz[1]); + if (!tmp[0] || tmp[1]) return (1); + i = (byte)(tmp[0]); + + string_free(keymap_act[mode][i]); + + keymap_act[mode][i] = string_make(macro__buf); + + return (0); + } + + + /* Process "V:::::" -- visual info */ + else if (buf[0] == 'V') + { + if (tokenize(buf + 2, 5, zz, ':', '/') == 5) + { + i = (byte)strtol(zz[0], NULL, 0); + angband_color_table[i][0] = (byte)strtol(zz[1], NULL, 0); + angband_color_table[i][1] = (byte)strtol(zz[2], NULL, 0); + angband_color_table[i][2] = (byte)strtol(zz[3], NULL, 0); + angband_color_table[i][3] = (byte)strtol(zz[4], NULL, 0); + return (0); + } + } + /* set macro trigger names and a template */ + /* Process "T:::" */ + /* Process "T: