Here is my set of patches updated for angband-3.0.0, as promised. The patches mostly have the same names as they did before. Please note, from filename_max.dif: I suggest you apply this patch quickly or not at all: Because it changes the sizes of a lot of arrays, it can be a bitch to verify it after there have been a lot of changes to the source. These patches are new since last time: days New bugfix: Off-by-one bug with days[] makefiles New bugfix: Makefile.* fixes. help-seek New feature: Use fseek() in show_file(). These are updated old patches: 66-uchar-inkey Bugfix: Treat 8bit keyboard input correctly when char is signed 67-uchar Bugfix: more `unsigned char' fixes. 93-fix-strnicmp Bugfix: my_strnicmp() in main-ros.c is quite buggy. 98-uchar-changefmt Possible bugfix: More 8-bit char patches. Need inspection. flowctrl Bugfix: Turn off flow control for main-.c gcu-win Bugfix: Synchronize WINDOWS in main-gcu with main-cap group Bugfix: Buggy --with-setgid permissions. help-avail Bug: In '?' to a tagged topic, other helpfiles are unreachable strncat Bugfix: Buffer overrun if some filenames are too long. strncpy Bugfix: strncpy() does not always \0-terminate the string. filename_max Cleanup/Bugfix: Replace pathname sizes with FILENAME_MAX. 64-shift-unsigned Portability: Change (integer << n) to (unsigned integer << n) L64 Portability: Eliminate L64. Use ANSI C's instead. charset Portability: Make angband mostly charset-indepentent. conf-unused Cleanup/Portability: Remove unused symbols from configure. sizeof-color Cleanup: 16/256 -> BASIC_COLORS/MAX_COLORS for colormaps sizeof-fgets Cleanup: *fgets(,,NUMBER) -> ,,sizeof(buffer) in main-ros.c sizeof-path Cleanup: Replace pathname sizes with sizeof. sizeof-tempfile Cleanup: Remove magic numbers in my_fopen_temp() pathnames. sizeof-various Cleanup: Various trivial sizeof patches. s-lang Trivial: Change "SLang" to "S-Lang". vowel Comment: Y is not a `vowel' in is_a_vowel(). config-modules Feature: Implement ./configure --enable-. fulldump Feature: Full dump command 'F' for character/endgame dump. help-better Feature: Help in more places. Help is also made more tagged. help-case Feature: Let show_file() indicate case sensitivity toggle. lost-art Feature: Tell the user when he has lost an artifact forever. Makefile.std Feature: Module/feature-driven Makefile.std. my_fgets Feature: Handle lines that do not end with \n, and long lines. opt_none Feature: Introduce constant OPT_NONE. userdir-delay Feature: Delay mkdir(~/.angband/) until it is needed. -- Hallvard B. Furuseth Comments copied from the top of each file: ====== 64-shift-unsigned.dif ====== Portability: Change (integer << n) to (unsigned integer << n). [Obsoletes easyread-292.tar.gz:ansi.dif.] To shift +1 into the sign bit of a signed integer causes undefined behavior. (So does any other arithmetic operation which overflows into the sign bit of a signed integer.) Usually it either acts as expected or signals an error. E.g. operations like (1L << 31) when 'long' is 32 bits wide. This patch: - changes (long_constant << foo) to ((u32b) constant << foo). All cases affect code where the result is assigned to or AND/ORed with a variable of type u32b. (I could have used 1UL instead, but this is faster on hosts where 'long' is wider than 'u32b'.) - changes '1 << foo' to '1U << foo'. In all cases, the result meets an unsigned ('byte' or 'u16b') variable. - changes the BOOK*() macros in x-spell.c so that BOOK*(-1) does not get a compiler warning about shifting by a negative amount. (This only happens in branches that are not taken, but some compilers complain anyway.) Accordingly, this patch should have no effect on hosts/compilers where it is safe to shift +1 into the sign bit - except it's an optimization on hosts where 'long' is a larger type than 'u32b'. (I'm sure there are other overflow problems in the code, but these were so easy to spot.) ====== 66-uchar-inkey.dif ====== Bugfix: Treat 8bit keyboard input correctly when char is signed. ** THIS PATCH IS NEEDED BY help-better.dif ** The source code generally assumes that character data is 7-bit. It will fail in a number of ways for 8-bit character data on hosts where 'char' is signed (and thus 8-bit characters negative). The most common error is to call the ctype.h functions with 'char' arguments. These functions expect an argument in the range of 'unsigned char' (or EOF), thus 'char' data must be cast to unsigned char before they are passed to ctype.h functions. This patch fixes the simplest cases: Keyboard input (from inkey(), get_com() and get_string() which is passed to ctype.h functions. ====== 67-uchar.dif ====== Bugfix: more `unsigned char' fixes. See 66-uchar-inkey.dif for explanation. This one fixes various fairly obvious details, each change is independent of the others. ====== 93-fix-strnicmp.dif ====== Bugfix: my_strnicmp() in main-ros.c is quite buggy. Fixes: * cast tolower's arguments to unsigned (since tolower expects that, see 66-uchar-inkey.dif for explanation), * return 0 if the n-length substrings are equal, * return 0 if the strings are equal and shorter than n, * negate the return value: return negative if arg1, not arg2, is smaller. ====== 98-uchar-changefmt.dif ====== Possible bugfix: More 8-bit char patches. Need inspection. See 66-uchar-inkey.dif for explanation. This set of patches needs a quick inspection: On hosts where 'char' is signed, these patches may change how 8-bit characters are parsed/written in things like program arguments and save/pref/info files. The change is *to* the behaviour on hosts where 'char' is unsigned, though, so it is correct, but I imagine some of them might be incompatible with the old behaviour. I also changed (!isalpha(c) && !isdigit(c)) to the equivalent (!isalnum(c)) while I was at it. Note: dehex() treats characters g-z as hexadecimal. Maybe it should use isxdigit() instead of isalpha(). OTOH, the return value is not checked for errors, so maybe it only matters for already buggy files. I wonder: Some places you use 'ch < 32' to test for control chars, while one place in files.c uses iscntrl(). Should one of them be changed to the other? They treat DEL (127) differently, it is a control character. Note that both variants need to cast the character to (byte). ====== L64.dif ====== Portability: Eliminate L64. Use ANSI C's instead. The patches to *.h do the job. The final patch to z-util.c can be omitted, it's just an add-on which checks that the integer types are as desired. ====== charset.dif ====== Portability: Make angband mostly charset-indepentent. - Remove an h-system.h comment about VMS charsets, since VMS apparently uses an ASCII superset now. See the VMS character set DEC-MCS in rfc1345, and this article: . Subject: Re: VMS character set > What kind of character set(s) does VMS use? Mostly "DEC multinational", which is a subset of ISO 8859-1 (ISO Latin-1), IIRC. (...) - Introduce UN_KTRL() to match KTRL(), and use it in ascii_to_text(). No actual change in the computations, it's just written clearer now. That takes care of the charset-dependencies I can see, except - A2I() & co, - expecting control chars to be 0-31 & 127, normal chars 32-126. ====== conf-unused.dif ====== Cleanup/Portability: Remove unused symbols from configure. ** THIS PATCH IS NEEDED BY config-modules.dif ** The following symbols are set by configure but never used: * STDC_HEADERS from the Autoconf macro AC_HEADER_STDC. The ANSI headers are used unconditionally e.g. in h-system.h. * Some of the HAVE_*_H from AC_CHECK_HEADERS. All of the HAVE_*_H symbols are unused now. I have removed some and used others. * TM_IN_SYS_TIME from AC_STRUCT_TM. * gcc -traditional. It doesn't work since the source uses prototypes. * If AC_FUNC_MEMCMP hits, it only adds memcmp.o to $LIBOBJS which is not used, and Angband has no matching memcmp.c source file anyway. memcmp() is used in z-virt.h. * RETSIGTYPE from AC_TYPE_SIGNAL. files.c's signal handlers return void. * HAVE_STRFTIME. strftime() is used unconditionally in files.c, Lua and main-ros.c. * HAVE_VPRINTF/HAVE_DOPRNT from AC_FUNC_VPRINTF. main-ros.c uses vsprintf() unconditionally, otherwise the functions are not used. * Most HAVE_s from AC_CHECK_FUNCS. They are used unconditionally (e.g. strtol()) or #if . * Also, HAS_STRICMP from Makefile.lcc is unused. So: The 1st patch removes these, except some header tests, and inserts new header tests for netdb.h, sys/param.h and sys/timeb.h. The h-config.h patch removes an obsolete comment about string*.h. (USG is still used to decide if sys/params.h should be #included, so the comment is right except that the the example string*.h is wrong.) Then the h-system.h patch adds C code to use the remaining header tests instead of symbols like SOLARIS. If you don't want the h-system.h patch (yet), you can instead delete the entire AC_CHECK_HEADERS() and AC_HEADER_TIME statements from configure.in. Finally, another configure.in patch removes AC_TYPE_SIZE_T and AC_C_CONST, since (a) ANSI C has size_t & const and (b) Lua uses them without autoconf.h. I put that in an optional patch since I don't know where you are going with portability. ====== config-modules.dif ====== Feature: Implement ./configure --enable-. ** THIS PATCH DEPENDS ON conf-unused.dif ** ** For some reason, this breaks size_t detection in autoconf 2.13, ** ** so apply the const/size_t patch in conf-unused.dif first. ** --enable- will attempt to compile into Angband. If libraries or include files for are missing, it is disabled despite --enable-. Also, --disable-x11 --disable-xaw --disable-xpj implies --without-x. Note: I've put all the --enable options inside `if !cygwin', since that is how X11 is done. I don't know cygwin, so I don't know if this is the right thing for the other modules too. If you tell me that some --enables should be outside `if !cygwin', I'll make a new patch. Note: These changes could use some re-indentation of old code, but then the patch would be much bigger. Tell me if you prefer that anyway. Or maybe I should submit a separate whitespace patch, to re-indent code and reformat comments all over Angband? ====== days.dif ====== New bugfix: Off-by-one bug with days[] days[*] is 29 bytes long, but is strcpyed from buf which is (29 bytes + one \0) long. ====== filename_max.dif ====== Bugfix/Cleanup: Replace pathname sizes with FILENAME_MAX. ** THIS PATCH IS NEEDED BY userdir-delay.dif AND fulldump.dif ** [This patch is the largest part of the old sizeof-path.dif.] I suggest you apply this patch quickly or not at all: Because it changes the sizes of a lot of arrays, it can be a bitch to verify it after there have been a lot of changes to the source. To apply this patch, a) `diff -N' your source tree against angband-3.0.0, b) apply the patch, c) check if any *new* instances of `1024' or `1023' found by the diff should now be `FILENAME_MAX' or `FILENAME_MAX-1'. ** The first hunk of the main-ros.c patch must be applied if any ** ** of this patch is applied. Otherwise the parts of this patch ** ** can be applied or not file by file. ** This patch replaces 1024 by FILENAME_MAX, or in some cases: MAX(FILENAME_MAX, ) where a variable has dual use or (in main-ros.c:translate_name()) where there is no telling which relevant "max path size" constant is largest. It also plugs a buffer overrun in main-emx.c by using strncat() instead of strcat(). path[] in files.c:show_file() gets size sizeof(filename) because filename[] is copied into path[]. A lot of sizes in the 'main-*.c's are *not* changed to FILENAME_MAX, because their variables are used as arguments to functions I don't know. I left that to the authors of the individual files. Bugfixes: - Changes 256 and 1024 for the same buffer size to FILENAME_MAX in main-dos.c:play_song(). - Increases pathname size in main-ros.c:translate_name() to match pathnames used elsewhere in Angband. - Plugs a buffer overrun in main-emx.c. ====== flowctrl.dif ====== Bugfix: Turn off flow control for main-.c. ^S halted the terminal instead of saving the game. This may be needed in main-lsl.c and for USE_TCHARS in main-.c too; I could not test these. It is not needed for main-sla.c. (But the non-X11 Unix modules can't be much used anyway, when such a bug could remain undiscovered for so long time.) BTW, maybe the way to turn off flow control for USE_TCHARS is to set t_startc and t_stopc to (char)-1 instead of the values used in main-*.c? ====== fulldump.dif ====== Feature: Full dump command 'F' for character/endgame dump. ** THIS PATCH APPLIES ON TOP OF filename_max.dif ** If filename_max.dif has not been applied, hunk #3 of files.c applies with fuzz. That's OK, though. Add an 'F' command in the character dump screen, which dumps all known abilities of each item instead of just the random abilities. That way it's easier to use a character dump to pick the items to wear; you don't have to remember e.g. that Westernesse gives See Invisible. Let 'F' in the endgame character dump do the same. (Previously both 'f' and 'F' just dumped random abilities.) With this, identify_random_gen() is no longer used - except it is declared in Lua, so I didn't delete it in case someone uses it from Lua. [This is an update of easyread-292.tar.gz:fulldump.dif] Patch: Add the 'F' command to character dump -- cmd4.c hunk 1-2: Update the help message. cmd4.c hunk 3-4: When 'F' is pressed, give TRUE to file_character(,full). Make 'F' in endgame dump do the same -- files.c hunk 7-8 (last 2 hunks). Implement the previously unused `full' argument to file_character() -- files.c hunk 1-6: Set `mode' from `full'. Replace identify_random_gen(x), which merely does identify_fully_aux2(x,OBJECT_FLAGS_RANDOM), with identify_fully_aux2(x,mode). defines.h, object1.c, externs.h, l-object.pkg: Make identify_fully_aux2() and modes of object_flags_aux() global. ====== gcu-win.dif ====== Bugfix: Synchronize WINDOWS in main-gcu with main-cap. Angband 2.9.3 added '|| defined(WINDOWS)' in this #if in main-cap.c, but not in the matching #if in main-gcu.c. I expect that's a bug. ====== group.dif ====== Bugfix: Buggy --with-setgid permissions. Installation --with-setgid can install the wrong file and directory permissions. I append a suggested fix. To reproduce: # Directory /tmp/lib does not (yet) exist. ./configure --with-setgid=games --bindir=/tmp/bin --with-libpath=/tmp/lib umask 077 make -s all install The umask during installation controls the permissions of many files and directories. So with a high umask, only the owner can play. I fixed it with a chmod in mkinstalldirs and after creating files. Please inspect these; I'm not quite sure which umask you expected. I think the mkinstalldirs chmod is correct though, since it creates directories that are not owned by Angband. Taking away chmod 7xx also prevents files like scores.raw from getting execute permission. (If you need execute, +rwX is better anyway.) It's worse if you install as non-root, which untrustful users really should be allowed to do. I.e. replace install' above with: # User `games' has primary group `users' and is member of group `games'. # (The point is to use --with-setgid=.) su games umask 077 make install Now installation fails for 2 reasons: * `chown -R root.games ...' is not allowed for non-root users. I changed it to do `chgrp -R games ...'. * `chmod -R 070' fails for non-root users if it does not traverse the directory depth-first. E.g. on Linux. After it took away permissions from the current user on the top dir, it can't traverse it:-( Anyway, I don't see why you need it anymore, with setgid instead of setuid. Allow scores unless the owner is playing? :-) So I changed the chmod to ug+rw,o-rwx. Finally, I added o-r to the chmod for the angband executable, so it's world executable but not world readable/debuggable. I think that's correct security-wise, but perhaps not what you want. ====== help-avail.dif ====== Bug: In '?' to a tagged topic, other helpfiles are unreachable. ** THIS PATCH IS NEEDED BY help-seek.dif ** [A bit simplified since last time. Originally from help-292beta.diff.gz.] To reproduce: Enter "User Interface Options". Push '?' to get help for some option. Push '?' again and you are taken *out* of help; there is no path to help.hlp. Well, you could use '%' (Goto File), but that's clumsy. This patch to show_file() makes another '?' take you to help.hlp in that case. It also makes '?' enter Help from infodumps like Known Uniques (recognized by != NULL). Note: If you don't like static variables, tell me to make help_level an extra parameter to show_file() and drop old_help_level. Note: Since you've said you don't like this patch, I can think of 4 other solutions. I think they are inferiour, but I'll do either if you ask me to: 1. Add a new parameter to show_file(). The cleanest way, but requires changes outside files.c in other Angband variants. 2. Use the parameter for this purpose. Also requires changes in other variants, *but no compiler error will tell them so*! Aarggh. 3. As you suggested last time, let '?' from non-help.hlp always go "into" help.hlp. Unfortunately, this means that if your current '?' path is birth.txt#classes -> help.hlp -> general.txt, there is no simple path *back* to birth.txt#classes; you have to go to help.hlp and then birth.txt and then page down to Classes. With the patch below, all you need to get there is to push '??'. 4. A really ugly hack: Let '?' from non-help.hlp go "into" help.hlp if there is a #tag, and out from the current file otherwise. I.e. treat the tag as the new parameter in solution (1). Then, let do_cmd_help_target() [see help-better.dif] add an empty #tag to non-help.hlp calls that have no #tag, and let show_file() notice the empty tag but otherwise treat it as no tag. ====== help-better.dif ====== Feature: Help in more places. Help is also made more tagged. ** THIS PATCH RECOMMENDS help-avail.dif ** ** THIS PATCH APPLIES ON TOP OF 66-uchar-inkey.dif ** If 66-uchar-inkey.dif has not been applied, hunks #6-7 of cmd4.c apply with fuzz. That's OK, though. This patch makes Angband accept the '?' key in more places, and make more of them take the user directly to the relevant file or section instead of to help.hlp. Because of the latter, help-avail.dif or some simplified version of it should be applied in conjunction with this patch. The files.c and externs.h patches add do_cmd_help_target(), a generalized do_cmd_help(). The rest add more calls to help, and more help targets to the help files. [This is an update of part of help-292beta.diff.gz.] ====== help-case.dif ====== Feature: Let show_file() indicate case sensitivity toggle. Previously it showed no indication that anything had happened when you toggled case sensitivity. ====== help-seek.dif ====== New feature: Use fseek() in show_file(). ** THIS PATCH APPLIES ON TOP OF help-avail.dif ** When one paged backwards in show_file(), it would close the file, reopen it and reread the initial portion. This patch uses fseek() instead. It notes the position of every 50th line up to 10000 lines. With longer files it seeks to just before line#10000 and reads on from there. (These numbers can be changed by changing enum Seek_step and the length of seek_offsets[], but they should be sufficient for most purposes. The longest Vanilla Angband file I know of, mon-info.spo, has 7000 lines.) Note: Consider removing the remaining comment about a temporary pre-padded file. ====== lost-art.dif ====== Feature: Tell the user when he has lost an artifact forever. This patch makes the config.h option NOTIFY_LOST_ARTIFACTS tell the user when he has left a level and lost an artifact forever. The logic of the tests when !defined(NOTIFY_LOST_ARTIFACTS) is unchanged. Note: I'm not quite sure whether 'if (p_ptr->playing)' is the correct test for whether the game is being played; I don't know the flags that well. It seems to work. Note: Maybe this should be a gameplay user option, but I don't know how to add user options. I'll make a new patch if you tell me how. ====== Makefile.std ====== Feature: Module/feature-driven Makefile.std. (Fixed some bugs since the original version.) Here is a rewrite of Makefile.std which lets you pick (uncomment) what you want to compile, module by module instead of just a few selected compile commands for some sepecific host/module combinations. It compiles Angband with the same options as the original Makefile.std, with two exceptions: - The variation below is removed, since it looked buggy. It linked Xaw libraries, but had -D"USE_X11" instead of -D"USE_XAW". Its ncurses part (not shown here) is kept in a separate option, though. ## ## Variation -- compile for Linux ## ## Allows the use of Angband in the console using ncurses, ## as well as under X11. ## CFLAGS = -I/usr/X11R6/include ... -D"USE_X11" ... LIBS = -L/usr/X11R6/lib -lXaw -lXext -lSM -lICE -lXmu -lXt -lX11 ... - XPJ support is added. ====== makefiles.dif ====== New bugfix: Makefile.* fixes. Synchronize some Makefiles with Makefile.std: - Most Makefiles missed x-spell.o. (I did not add it to Makefile., since they do not have script.o either.) - Makefile.ami missed use-obj.o. - Makefile. had wrong or missing dependencies (assuming Makefile.std is correct). Though I still suggest you delete Makefile.gtk and Makefile.lsl; both are handled by Makefile.std. ====== my_fgets.dif ====== Feature: Handle lines that do not end with \n, and long lines. This patch fixes two buglets: * my_fgets() does not "see" the last line of a file if that line does not end with newline. * my_fgets() cannot read lines longer than 1024 characters. (BTW, with this patch you can change it to use a smaller buffer, if you wish.) ====== opt_none.dif ====== Feature: Introduce constant OPT_NONE. Make an OPT_NONE constant for the magic constant option_page[][] == 255. ====== s-lang.dif ====== Trivial: Change "SLang" to "S-Lang". I missed these in main-sla.dif. ====== sizeof-color.dif ====== Cleanup: 16/256 -> BASIC_COLORS/MAX_COLORS for colormaps This patch gets rid of a bunch of magic constants. It: - Replaces 16 and 256 with BASIC_COLORS and MAX_COLORS many places, - #defines a few similar constants - typically as 16 or 32 - in files where I couldn't prove that the 16 is the "same" 16 as BASIC_COLORS, and not just a local colorcount which happens to equal BASIC_COLORS, E.g. NUM_PENS NUM_PUBPENS in main-ami.c. - Introduces a few N_ELEMENTS() calls where none of the above seemed proper. - Replaces (attr & 0x0F) with (attr % BASIC_COLORS). I checked that the "attr"s are nonnegative. - Expresses 8 color pairs as BASIC_COLORS/2 in main-gcu.c. - In main-ami.c, p in PEN(p) calls is always either a small constant or (expr & 0x0F), so I moved the '& 0x0F' into the #definition of PEN() and forced the operation to be unsigned. Removes the #definition of GPEN(); it is not used. - Expresses COLOR_OFFSET 240 as (256 - BASIC_COLORS) in main-dos.c and main-lsl.c. I suspect the 256 is MAX_COLORS but couldn't prove it. There are a number of 16s and 256es which serve the same function and seem to "accidentally" have the same value as BASIC_COLORS and MAX_COLORS. I left them as separate constants. I'll make a separate patch which does set them to BASIC_COLORS and MAX_COLORS if you like. Examples: NUM_PENS in main-ami.c, and the 256 mentioned above main-dos.c and main-lsl.c. ====== sizeof-fgets.dif ====== Cleanup: *fgets(,,NUMBER) -> ,,sizeof(buffer) in main-ros.c This patch does not change the compiled code, it only gets rid of magic constants. Tell me if you prefer me to #define these constants instead - after all a future change in buffer sizes here would affect the max accepted lengths of lines in input files. ====== sizeof-path.dif ====== Cleanup: Replace pathname sizes with sizeof. [Most of the old sizelf-path.dif has been moved to filename_max.dif.] This patch replaces magic numbers in pathname sizes in some of the cases where FILENAME_MAX is not appropriate. For savefile[] I use sizeof(savefile) instead of FILENAME_MAX because a change in savefile's size would explode all over some of the main-* files. And maybe over variants' private code, for all I know. ====== sizeof-tempfile.dif ====== Cleanup: Remove magic numbers in my_fopen_temp() pathnames. This patch replaces some of 295-alpha-patches.tar.gz:sizeof-path.dif. The size of my_fopen_temp() buffers couldn't be replaced with FILENAME_MAX, since FILENAME_MAX might in theory be smaller than MAX(L_tmpnam, 14). FILENAME_MAX is a _recommended_ size, not a guaranteed max size. ====== sizeof-various.dif ====== Cleanup: Various trivial sizeof patches. A little of the previous version of this patch was applied in 296alpha; I've removed those hunks as well as one buggy patch. ====== strncat.dif ====== Bugfix: Buffer overrun if some filenames are too long. Use *buf = '\0'; strncat(buf,...) instead of strcpy(buf,...) to prevent buffer overruns if some filenames are too long. An alternative would be the slower strncpy(buf,...); buf[sizeof(buf)-1] = '\0'; which zero-fills the entire final part of the buffer. ====== strncpy.dif ====== Bugfix: strncpy() does not always \0-terminate the string. Use string[0] = '\0'; strncat(buf, ..., sizeof(buf)-1) instead. (The alternative is the slower strncpy(buf, ..., sizeof(buf)); string[maxlen-1] = '\0'; which \0-fills the end of the array.) ====== userdir-delay.dif ====== Feature: Delay mkdir(~/.angband/) until it is needed. ** THIS PATCH APPLIES ON TOP OF filename_max.dif ** If you are not going to apply filename_max.dif, replace FILENAME_MAX in this patch file with 1024. I always find it irritating when programs create useless junk in $HOME. This patch delays mkdir(~/.angband/) until that directory is needed. Rewritten as described in my mail about that patch: - Change create_user_dir() to create_user_dir_when_needed(file), which creates ANGBAND_USER_DIR if starts with that directory and we do not have privileges (which would mean is elsewhere). Call it from my_fopen() & co. - Add a global bool have_permissions = TRUE; to files.c, reset/set it in safe_setuid_(), and test it before ~/.angband/ is created. If we have permissions, the file we are about to write should not be in ANGBAND_USER_DIR. - Also keep track of whether or not ANGBAND_USER_DIR has been created from PRIVATE_USER_PATH at all. ====== vowel.dif ====== Comment: Y is not a `vowel' in is_a_vowel().