THIS PATCH FIXES A SECURITY BUG INTRODUCED IN 1.7.7p17 - IF YOU USE 1.7.7p17, PLEASE UPGRADE! This is patch18 to PennMUSH 1.7.7. After applying this patch, you will have version 1.7.7p18 To apply this patch, save it to a file in your top-level MUSH directory, and do the following: patch -p1 < 1.7.7-patch18 make install If you use GNU patch 2.2, you probably want the above to be 'patch -b -p1', not just 'patch -p1'. Unix (or cygwin) users need not worry about failed hunks in src/switchinc.c, hdrs/switches.h, hdrs/cmds.h, or hdrs/funs.h. These files are automatically rebuilt on compile. On the off chance they appear not to be, simply rm them and re-run make. Then @shutdown and restart your MUSH. - Alan/Javelin In this patch: Major Changes: * The flag handling code has been additionally abstracted to allow, in a future patchlevel, @powers to be handled in the same way that flags are now. Minor Changes: * Wrap the OS-dependant code for making sure the mush always has a free file descriptor available for use in a pair of functions. [SW] Fixes: * Linted some ssl-related warnings. Reported by Cheetah@M*U*S*H. * Compile failed in timer.c unless USE_MAILER was defined. Reported by Sunny@M*U*S*H. * Bug allowing players to view internal and mortal_dark attributes introduced in p17 has been fixed. [TAP] Prereq: 1.7.7p17 *** 1_7_7.551/Patchlevel Mon, 11 Aug 2003 16:14:42 -0500 dunemush (pennmush/5_Patchlevel 1.17.1.11.1.19 600) --- 1_7_7.557(w)/Patchlevel Tue, 19 Aug 2003 17:49:34 -0500 dunemush (pennmush/5_Patchlevel 1.17.1.11.1.20 600) *************** *** 1,2 **** Do not edit this file. It is maintained by the official PennMUSH patches. ! This is PennMUSH 1.7.7p17 --- 1,2 ---- Do not edit this file. It is maintained by the official PennMUSH patches. ! This is PennMUSH 1.7.7p18 *** 1_7_7.551/CHANGES.177 Sun, 17 Aug 2003 08:30:54 -0500 dunemush (pennmush/g/23_CHANGES 1.48.1.128 600) --- 1_7_7.557(w)/CHANGES.177 Tue, 19 Aug 2003 17:49:55 -0500 dunemush (pennmush/g/23_CHANGES 1.48.1.133 600) *************** *** 18,23 **** --- 18,40 ---- ========================================================================== + Version 1.7.7 patchlevel 18 August 19, 2003 + + Major Changes: + * The flag handling code has been additionally abstracted to + allow, in a future patchlevel, @powers to be handled in the + same way that flags are now. + Minor Changes: + * Wrap the OS-dependant code for making sure the mush always has a free + file descriptor available for use in a pair of functions. [SW] + Fixes: + * Linted some ssl-related warnings. Reported by Cheetah@M*U*S*H. + * Compile failed in timer.c unless USE_MAILER was defined. + Reported by Sunny@M*U*S*H. + * Bug allowing players to view internal and mortal_dark attributes + introduced in p17 has been fixed. [TAP] + + Version 1.7.7 patchlevel 17 August 11, 2003 Major changes: *** 1_7_7.551/src/wiz.c Thu, 17 Jul 2003 16:30:15 -0500 dunemush (pennmush/b/23_wiz.c 1.44.1.1.1.1.1.2.1.7.1.1.1.1.1.1.1.1.1.1.1.8.1.2.2.2.1.2.1.1.1.1.1.1.1.2.1.1.1.2.2.14 660) --- 1_7_7.557(w)/src/wiz.c Tue, 19 Aug 2003 23:36:08 -0500 dunemush (pennmush/b/23_wiz.c 1.44.1.1.1.1.1.2.1.7.1.1.1.1.1.1.1.1.1.1.1.8.1.2.2.2.1.2.1.1.1.1.1.1.1.2.1.1.1.2.2.16 660) *************** *** 64,70 **** #ifdef I_SYS_FILE #include #endif - extern int reserved; #endif static int tport_dest_ok(dbref player, dbref victim, dbref dest); --- 64,69 ---- *************** *** 990,996 **** notify(player, object_header(player, thing)); notify_format(player, T("Flags value: %s"), ! bits_to_string(Flags(thing), GOD, NOTHING)); notify_format(player, T("Powers value: 0x%08x"), Powers(thing)); notify_format(player, "Next: %d", Next(thing)); --- 989,995 ---- notify(player, object_header(player, thing)); notify_format(player, T("Flags value: %s"), ! bits_to_string("FLAG", Flags(thing), GOD, NOTHING)); notify_format(player, T("Powers value: 0x%08x"), Powers(thing)); notify_format(player, "Next: %d", Next(thing)); *************** *** 1626,1633 **** for (n = low; n <= high; n++) { if ((restrict_owner == ANY_OWNER || Owner(n) == restrict_owner) && (restrict_type == NOTYPE || Typeof(n) == restrict_type) ! && ((sclass == S_FLAG) ? flaglist_check(player, n, restriction, 1) ! : flaglist_check_long(player, n, restriction, 1))) { if (nresults >= result_size) { dbref *newresults; result_size *= 2; --- 1625,1633 ---- for (n = low; n <= high; n++) { if ((restrict_owner == ANY_OWNER || Owner(n) == restrict_owner) && (restrict_type == NOTYPE || Typeof(n) == restrict_type) ! && ((sclass == S_FLAG) ? ! flaglist_check("FLAG", player, n, restriction, 1) ! : flaglist_check_long("FLAG", player, n, restriction, 1))) { if (nresults >= result_size) { dbref *newresults; result_size *= 2; *************** *** 1812,1820 **** case 2: if (!site || !*site) { /* List bad names */ ! #ifndef WIN32 ! close(reserved); ! #endif #ifdef macintosh if ((fp = fopen(NAMES_FILE, "rb")) == NULL) { #else --- 1812,1818 ---- case 2: if (!site || !*site) { /* List bad names */ ! release_fd(); #ifdef macintosh if ((fp = fopen(NAMES_FILE, "rb")) == NULL) { #else *************** *** 1829,1843 **** } fclose(fp); } ! #ifndef WIN32 ! reserved = open("/dev/null", O_RDWR); ! #endif return; } if (site[0] == '!') { /* Delete a name */ ! #ifndef WIN32 ! close(reserved); ! #endif #ifdef macintosh if ((fp = fopen(NAMES_FILE, "rb")) != NULL) { if ((fptmp = fopen("tmp.tmp", "wb")) == NULL) { --- 1827,1837 ---- } fclose(fp); } ! reserve_fd(); return; } if (site[0] == '!') { /* Delete a name */ ! release_fd(); #ifdef macintosh if ((fp = fopen(NAMES_FILE, "rb")) != NULL) { if ((fptmp = fopen("tmp.tmp", "wb")) == NULL) { *************** *** 1870,1884 **** } } else notify(player, T("Unable to delete name.")); ! #ifndef WIN32 ! reserved = open("/dev/null", O_RDWR); ! #endif ! return; } /* Add a name */ ! #ifndef WIN32 ! close(reserved); ! #endif #ifdef macintosh if ((fp = fopen(NAMES_FILE, "ab")) != NULL) { #else --- 1864,1873 ---- } } else notify(player, T("Unable to delete name.")); ! reserve_fd(); } /* Add a name */ ! release_fd(); #ifdef macintosh if ((fp = fopen(NAMES_FILE, "ab")) != NULL) { #else *************** *** 1892,1900 **** } else { notify(player, T("Error writing to file.")); } ! #ifndef WIN32 ! reserved = open("/dev/null", O_RDWR); ! #endif break; } } --- 1881,1887 ---- } else { notify(player, T("Error writing to file.")); } ! reserve_fd(); break; } } *** 1_7_7.551/src/timer.c Sun, 17 Aug 2003 08:30:54 -0500 dunemush (pennmush/b/29_timer.c 1.29.1.7.1.11 660) --- 1_7_7.557(w)/src/timer.c Tue, 19 Aug 2003 23:36:07 -0500 dunemush (pennmush/b/29_timer.c 1.29.1.7.1.12 660) *************** *** 123,129 **** --- 123,131 ---- int actual; ATTR *aptr; lock_list *lptr; + #ifdef USE_MAILER MAIL *mp; + #endif if (db_top == 0) return; *************** *** 137,147 **** --- 139,151 ---- for (lptr = Locks(end_obj); lptr; lptr = L_NEXT(lptr)) if (L_KEY(lptr) != NULL_CHUNK_REFERENCE) actual++; + #ifdef USE_MAILER if (IsPlayer(end_obj)) { for (mp = find_exact_starting_point(end_obj); mp; mp = mp->next) if (mp->msgid != NULL_CHUNK_REFERENCE) actual++; } + #endif end_obj = (end_obj + 1) % db_top; } while (actual < amount && end_obj != start_obj); *************** *** 175,180 **** --- 179,185 ---- refs[actual] = &(lptr->key); actual++; } + #ifdef USE_MAILER if (IsPlayer(start_obj)) { for (mp = find_exact_starting_point(start_obj); mp; mp = mp->next) if (mp->msgid != NULL_CHUNK_REFERENCE) { *************** *** 182,187 **** --- 187,193 ---- actual++; } } + #endif start_obj = (start_obj + 1) % db_top; } while (start_obj != end_obj); *** 1_7_7.551/src/player.c Mon, 23 Jun 2003 16:03:37 -0500 dunemush (pennmush/b/47_player.c 1.15.1.1.1.1.1.4.1.6.1.1.1.2 660) --- 1_7_7.557(w)/src/player.c Tue, 19 Aug 2003 23:36:03 -0500 dunemush (pennmush/b/47_player.c 1.15.1.1.1.1.1.4.1.6.1.1.1.4 660) *************** *** 46,53 **** #include "extmail.h" #include "confmagic.h" - extern int reserved; - dbref email_register_player (const char *name, const char *email, const char *host, const char *ip); static dbref make_player --- 46,51 ---- *************** *** 317,325 **** * 1) We'll use sendmail -t, so we don't pass user-given values to a shell. */ ! #ifndef WIN32 ! close(reserved); ! #endif if ((fp = #ifdef __LCC__ (FILE *) --- 315,321 ---- * 1) We'll use sendmail -t, so we don't pass user-given values to a shell. */ ! release_fd(); if ((fp = #ifdef __LCC__ (FILE *) *************** *** 328,336 **** do_log(LT_CONN, 0, 0, T("Failed registration of %s by %s: unable to open sendmail"), name, email); ! #ifndef WIN32 ! reserved = open("/dev/null", O_RDWR); ! #endif return NOTHING; } fprintf(fp, T("Subject: [%s] Registration of %s\n"), MUDNAME, name); --- 324,330 ---- do_log(LT_CONN, 0, 0, T("Failed registration of %s by %s: unable to open sendmail"), name, email); ! reserve_fd(); return NOTHING; } fprintf(fp, T("Subject: [%s] Registration of %s\n"), MUDNAME, name); *************** *** 347,355 **** fprintf(fp, "\tconnect %s %s\n", name, passwd); fprintf(fp, "\n"); pclose(fp); ! #ifndef WIN32 ! reserved = open("/dev/null", O_RDWR); ! #endif /* Ok, all's well, make a player */ player = make_player(name, passwd, host, ip); (void) atr_add(player, "REGISTERED_EMAIL", email, GOD, NOTHING); --- 341,347 ---- fprintf(fp, "\tconnect %s %s\n", name, passwd); fprintf(fp, "\n"); pclose(fp); ! reserve_fd(); /* Ok, all's well, make a player */ player = make_player(name, passwd, host, ip); (void) atr_add(player, "REGISTERED_EMAIL", email, GOD, NOTHING); *************** *** 385,392 **** Owner(player) = player; Parent(player) = NOTHING; Type(player) = TYPE_PLAYER; ! flags = string_to_bits(options.player_flags); ! copy_flag_bitmask(Flags(player), flags); destroy_flag_bitmask(flags); if (Suspect_Site(host, player) || Suspect_Site(ip, player)) set_flag_internal(player, "SUSPECT"); --- 377,384 ---- Owner(player) = player; Parent(player) = NOTHING; Type(player) = TYPE_PLAYER; ! flags = string_to_bits("FLAG", options.player_flags); ! copy_flag_bitmask("FLAG", Flags(player), flags); destroy_flag_bitmask(flags); if (Suspect_Site(host, player) || Suspect_Site(ip, player)) set_flag_internal(player, "SUSPECT"); *** 1_7_7.551/src/game.c Mon, 11 Aug 2003 15:42:46 -0500 dunemush (pennmush/c/10_game.c 1.50.1.8.1.1.1.1.2.1.1.1.2.1.1.4.1.1.1.1.1.1.1.1.1.1.2.1.1.2.1.1.1.1.1.1.1.2.1.1.1.2.1.1.1.1.1.1.1.1.1.5.1.3.1.2.1.2.1.1.1.1.1.1.1.1.1.10 660) --- 1_7_7.557(w)/src/game.c Tue, 19 Aug 2003 23:36:02 -0500 dunemush (pennmush/c/10_game.c 1.50.1.8.1.1.1.1.2.1.1.1.2.1.1.4.1.1.1.1.1.1.1.1.1.1.2.1.1.2.1.1.1.1.1.1.1.2.1.1.1.2.1.1.1.1.1.1.1.1.1.5.1.3.1.2.1.2.1.1.1.1.1.1.1.1.1.12 660) *************** *** 101,107 **** time_t last_dump_time = 0; /**< Time of last successful db save */ int reboot_count = 0; /**< Number of reboots so far */ static int epoch = 0; ! int reserved; /**< Reserved file descriptor */ int depth = 0; /**< excessive recursion prevention */ extern dbref cplr; extern char ccom[]; --- 101,107 ---- time_t last_dump_time = 0; /**< Time of last successful db save */ int reboot_count = 0; /**< Number of reboots so far */ static int epoch = 0; ! static int reserved; /**< Reserved file descriptor */ int depth = 0; /**< excessive recursion prevention */ extern dbref cplr; extern char ccom[]; *************** *** 154,159 **** --- 154,177 ---- Pid_t forked_dump_pid = -1; + /** Open /dev/null to reserve a file descriptor that can be reused later. */ + void + reserve_fd(void) + { + #ifndef WIN32 + reserved = open("/dev/null", O_RDWR); + #endif + } + + /** Release the reserved file descriptor for other use. */ + void + release_fd(void) + { + #ifndef WIN32 + close(reserved); + #endif + } + /** User command to dump the database. * \verbatim * This implements the @dump command. *************** *** 576,591 **** } if (nofork || (!nofork && child == 0)) { /* in the child */ ! #ifndef WIN32 ! close(reserved); /* get that file descriptor back */ ! #endif status = dump_database_internal(); if (!nofork) { _exit(status); /* !!! */ } else { ! #ifndef WIN32 ! reserved = open("/dev/null", O_RDWR); ! #endif if (DUMP_NOFORK_COMPLETE && *DUMP_NOFORK_COMPLETE) flag_broadcast(0, 0, "%s", DUMP_NOFORK_COMPLETE); } --- 594,605 ---- } if (nofork || (!nofork && child == 0)) { /* in the child */ ! release_fd(); status = dump_database_internal(); if (!nofork) { _exit(status); /* !!! */ } else { ! reserve_fd(); if (DUMP_NOFORK_COMPLETE && *DUMP_NOFORK_COMPLETE) flag_broadcast(0, 0, "%s", DUMP_NOFORK_COMPLETE); } *************** *** 681,687 **** (int) getpid(), show_time(start_time, 0)); /* initialize all the hash and prefix tables */ ! init_flag_table(); init_func_hashtab(); init_math_hashtab(); init_tag_hashtab(); --- 695,702 ---- (int) getpid(), show_time(start_time, 0)); /* initialize all the hash and prefix tables */ ! init_flagspaces(); ! init_flag_table("FLAG"); init_func_hashtab(); init_math_hashtab(); init_tag_hashtab(); *** 1_7_7.551/src/fundb.c Mon, 11 Aug 2003 14:04:21 -0500 dunemush (pennmush/c/17_fundb.c 1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.7.1.3.1.3.1.3.1.2.1.2.1.3.2.1.2.1.2.1.1.1.1.4.1.1.1.1.1.1.1.1.1.1.1.3.1.1.2.2.2.1.1.1.1.1.1.16 660) --- 1_7_7.557(w)/src/fundb.c Tue, 19 Aug 2003 23:36:02 -0500 dunemush (pennmush/c/17_fundb.c 1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.7.1.3.1.3.1.3.1.2.1.2.1.3.2.1.2.1.2.1.1.1.1.4.1.1.1.1.1.1.1.1.1.1.1.3.1.1.2.2.2.1.1.1.1.1.1.17 660) *************** *** 419,425 **** char *p; ATTR *a; if (nargs == 0) { ! safe_str(list_all_flags(NULL, executor, 0x1), buff, bp); return; } if ((p = strchr(args[0], '/'))) --- 419,425 ---- char *p; ATTR *a; if (nargs == 0) { ! safe_str(list_all_flags("FLAG", NULL, executor, 0x1), buff, bp); return; } if ((p = strchr(args[0], '/'))) *************** *** 450,456 **** char *p; ATTR *a; if (nargs == 0) { ! safe_str(list_all_flags(NULL, executor, 0x2), buff, bp); return; } if ((p = strchr(args[0], '/'))) --- 450,456 ---- char *p; ATTR *a; if (nargs == 0) { ! safe_str(list_all_flags("FLAG", NULL, executor, 0x2), buff, bp); return; } if ((p = strchr(args[0], '/'))) *************** *** 470,476 **** safe_str(privs_to_string(attr_privs, AL_FLAGS(a)), buff, bp); } else { /* Object flags, visible to all */ ! safe_str(bits_to_string(Flags(thing), executor, thing), buff, bp); } } --- 470,476 ---- safe_str(privs_to_string(attr_privs, AL_FLAGS(a)), buff, bp); } else { /* Object flags, visible to all */ ! safe_str(bits_to_string("FLAG", Flags(thing), executor, thing), buff, bp); } } *************** *** 1026,1053 **** FUNCTION(fun_orflags) { dbref it = match_thing(executor, args[0]); ! safe_boolean(flaglist_check(executor, it, args[1], 0), buff, bp); } /* ARGSUSED */ FUNCTION(fun_andflags) { dbref it = match_thing(executor, args[0]); ! safe_boolean(flaglist_check(executor, it, args[1], 1), buff, bp); } /* ARGSUSED */ FUNCTION(fun_orlflags) { dbref it = match_thing(executor, args[0]); ! safe_boolean(flaglist_check_long(executor, it, args[1], 0), buff, bp); } /* ARGSUSED */ FUNCTION(fun_andlflags) { dbref it = match_thing(executor, args[0]); ! safe_boolean(flaglist_check_long(executor, it, args[1], 1), buff, bp); } static lock_type --- 1026,1053 ---- FUNCTION(fun_orflags) { dbref it = match_thing(executor, args[0]); ! safe_boolean(flaglist_check("FLAG", executor, it, args[1], 0), buff, bp); } /* ARGSUSED */ FUNCTION(fun_andflags) { dbref it = match_thing(executor, args[0]); ! safe_boolean(flaglist_check("FLAG", executor, it, args[1], 1), buff, bp); } /* ARGSUSED */ FUNCTION(fun_orlflags) { dbref it = match_thing(executor, args[0]); ! safe_boolean(flaglist_check_long("FLAG", executor, it, args[1], 0), buff, bp); } /* ARGSUSED */ FUNCTION(fun_andlflags) { dbref it = match_thing(executor, args[0]); ! safe_boolean(flaglist_check_long("FLAG", executor, it, args[1], 1), buff, bp); } static lock_type *** 1_7_7.551/src/flags.c Thu, 17 Jul 2003 15:25:22 -0500 dunemush (pennmush/c/20_flags.c 1.1.1.1.1.1.1.1.1.1.1.1.1.6.1.2.1.1.1.1.1.2.2.2.2.1.2.1.1.3.1.2.1.1.1.1.1.1.1.1.1.3.1.9.1.2.2.1.1.2.1.52 660) --- 1_7_7.557(w)/src/flags.c Tue, 19 Aug 2003 23:36:02 -0500 dunemush (pennmush/c/20_flags.c 1.1.1.1.1.1.1.1.1.1.1.1.1.6.1.2.1.1.1.1.1.2.2.2.2.1.2.1.1.3.1.2.1.1.1.1.1.1.1.1.1.3.1.9.1.2.2.1.1.2.1.53 660) *************** *** 35,40 **** --- 35,41 ---- #include "parse.h" #include "match.h" #include "ptab.h" + #include "htab.h" #include "privtab.h" #include "game.h" #include "flags.h" *************** *** 46,73 **** static int can_set_flag(dbref player, dbref thing, FLAG *flagp, int negate); ! static FLAG *letter_to_flagptr(char c, int type); ! static void flag_add(const char *name, FLAG *f); static int has_flag(dbref thing, FLAG *f); void decompile_flags(dbref player, dbref thing, const char *name); void decompile_powers(dbref player, dbref thing, const char *name); static FLAG *flag_read(FILE * in); static void flag_write(FILE * out, FLAG *f, const char *name); static FLAG *clone_flag(FLAG *f); static FLAG *new_flag(void); static void flag_add_additional(void); ! static char *list_aliases(FLAG *given); static void realloc_object_flag_bitmasks(int numbytes); PTAB ptab_flag; /**< Table of flags by name, inc. aliases */ ! FLAG **flags = NULL; /**< A variable-length array of pointers, ! * to canonical flags, indexed by bit ! * position. Aliases not inclued. */ ! static int flagbits = 0; /* The current length of the flags array */ extern PTAB ptab_command; /* Uses flag bitmasks */ /** This is the old default flag table. We still use it when we have to * convert old dbs, but once you have a converted db, it's the flag --- 47,74 ---- static int can_set_flag(dbref player, dbref thing, FLAG *flagp, int negate); ! static FLAG *letter_to_flagptr(FLAGSPACE * n, char c, int type); ! static void flag_add(FLAGSPACE * n, const char *name, FLAG *f); static int has_flag(dbref thing, FLAG *f); void decompile_flags(dbref player, dbref thing, const char *name); void decompile_powers(dbref player, dbref thing, const char *name); static FLAG *flag_read(FILE * in); static void flag_write(FILE * out, FLAG *f, const char *name); + static FLAG *flag_hash_lookup(FLAGSPACE * n, const char *name, int type); static FLAG *clone_flag(FLAG *f); static FLAG *new_flag(void); static void flag_add_additional(void); ! static char *list_aliases(FLAGSPACE * n, FLAG *given); static void realloc_object_flag_bitmasks(int numbytes); + static FLAG *match_flag_ns(FLAGSPACE * n, const char *name); PTAB ptab_flag; /**< Table of flags by name, inc. aliases */ ! HASHTAB htab_flagspaces; /**< Hash of flagspaces */ extern PTAB ptab_command; /* Uses flag bitmasks */ + #define Flagspace_Lookup(n,ns) if (!(n = (FLAGSPACE *)hashfind(ns,&htab_flagspaces))) panic("Unable to locate flagspace"); /** This is the old default flag table. We still use it when we have to * convert old dbs, but once you have a converted db, it's the flag *************** *** 283,289 **** FLAG * match_flag(const char *name) { ! return (FLAG *) ptab_find(&ptab_flag, name); } /** Given a flag name and mask of types, return a pointer to a flag struct. --- 284,301 ---- FLAG * match_flag(const char *name) { ! return (FLAG *) match_flag_ns(hashfind("FLAG", &htab_flagspaces), name); ! } ! ! /** Convenience function to return a pointer to a flag struct ! * given the name. ! * \param name name of flag to find. ! * \return poiner to flag structure, or NULL. ! */ ! static FLAG * ! match_flag_ns(FLAGSPACE * n, const char *name) ! { ! return (FLAG *) ptab_find(n->tab, name); } /** Given a flag name and mask of types, return a pointer to a flag struct. *************** *** 291,306 **** * right type. If that fails, it tries to match flag characters if the * name is a single character. If all else fails, it tries to match * against an object type name. * \param name name of flag to find. * \param type mask of desired flag object types. * \return pointer to flag structure, or NULL. */ ! FLAG * ! flag_hash_lookup(const char *name, int type) { FLAG *f; ! f = match_flag(name); if (f && !(f->perms & F_DISABLED)) { if (f->type & type) return f; --- 303,319 ---- * right type. If that fails, it tries to match flag characters if the * name is a single character. If all else fails, it tries to match * against an object type name. + * \param n pointer to flagspace to search. * \param name name of flag to find. * \param type mask of desired flag object types. * \return pointer to flag structure, or NULL. */ ! static FLAG * ! flag_hash_lookup(FLAGSPACE * n, const char *name, int type) { FLAG *f; ! f = match_flag_ns(n, name); if (f && !(f->perms & F_DISABLED)) { if (f->type & type) return f; *************** *** 309,322 **** /* If the name is a single character, search the flag characters */ if (name && *name && !*(name + 1)) { ! if ((f = letter_to_flagptr(*name, type))) return f; } /* provided for backwards compatibility: type flag checking */ ! for (f = type_table; f->name != NULL; f++) ! if (string_prefix(name, f->name)) ! return f; return NULL; } --- 322,338 ---- /* If the name is a single character, search the flag characters */ if (name && *name && !*(name + 1)) { ! if ((f = letter_to_flagptr(n, *name, type))) return f; } /* provided for backwards compatibility: type flag checking */ ! if (n->flag_table == flag_table) { ! for (f = type_table; f->name != NULL; f++) ! if (string_prefix(name, f->name)) ! return f; ! } ! return NULL; } *************** *** 335,348 **** /* Deallocate all flag-related memory */ static void ! clear_all_flags(void) { ! ptab_free(&ptab_flag); /* Finally, the flags array */ ! if (flags) ! free(flags); ! flags = NULL; ! flagbits = 0; } static FLAG * --- 351,364 ---- /* Deallocate all flag-related memory */ static void ! clear_all_flags(FLAGSPACE * n) { ! ptab_free(n->tab); /* Finally, the flags array */ ! if (n->flags) ! free(n->flags); ! n->flags = NULL; ! n->flagbits = 0; } static FLAG * *************** *** 365,383 **** * f->bitpos is used. */ static void ! flag_add(const char *name, FLAG *f) { /* If this flag has no bitpos assigned, assign it the next one. * We could improve this algorithm to use the next available * slot after deletions, too, but this will do for now. */ if (f->bitpos < 0) ! f->bitpos = flagbits; /* Insert the flag in the ptab by the given name (maybe an alias) */ ! ptab_start_inserts(&ptab_flag); ! ptab_insert(&ptab_flag, name, f); ! ptab_end_inserts(&ptab_flag); /* Is this a canonical flag (as opposed to an alias?) * If it's an alias, we're done. --- 381,399 ---- * f->bitpos is used. */ static void ! flag_add(FLAGSPACE * n, const char *name, FLAG *f) { /* If this flag has no bitpos assigned, assign it the next one. * We could improve this algorithm to use the next available * slot after deletions, too, but this will do for now. */ if (f->bitpos < 0) ! f->bitpos = n->flagbits; /* Insert the flag in the ptab by the given name (maybe an alias) */ ! ptab_start_inserts(n->tab); ! ptab_insert(n->tab, name, f); ! ptab_end_inserts(n->tab); /* Is this a canonical flag (as opposed to an alias?) * If it's an alias, we're done. *************** *** 386,420 **** * (An alias would have a previously used bitpos that's already * indexing a flag in the flags array) */ ! if ((f->bitpos >= flagbits) || (flags[f->bitpos] == NULL)) { /* It's a canonical flag */ int i; ! if (f->bitpos >= flagbits) { /* Oops, we need a bigger array */ ! if (flagbits == 0) ! flags = (FLAG **) malloc(sizeof(FLAG *)); else { ! flags = (FLAG **) realloc(flags, (f->bitpos + 1) * sizeof(FLAG *)); ! if (!flags) panic("Unable to reallocate flags array!\n"); } /* Make sure the new space is full of NULLs */ ! for (i = flagbits; i <= f->bitpos; i++) ! flags[i] = NULL; } /* Put the canonical flag in the flags array */ ! flags[f->bitpos] = f; ! flagbits = f->bitpos + 1; ! if (flagbits % 8 == 1) { /* We've crossed over a byte boundary, so we need to realloc * all the flags on all our objects to get them an additional * byte. */ ! realloc_object_flag_bitmasks((flagbits + 7) / 8); } } } static void realloc_object_flag_bitmasks(int numbytes) { --- 402,440 ---- * (An alias would have a previously used bitpos that's already * indexing a flag in the flags array) */ ! if ((f->bitpos >= n->flagbits) || (n->flags[f->bitpos] == NULL)) { /* It's a canonical flag */ int i; ! if (f->bitpos >= n->flagbits) { /* Oops, we need a bigger array */ ! if (n->flagbits == 0) ! n->flags = (FLAG **) malloc(sizeof(FLAG *)); else { ! n->flags = ! (FLAG **) realloc(n->flags, (f->bitpos + 1) * sizeof(FLAG *)); ! if (!n->flags) panic("Unable to reallocate flags array!\n"); } /* Make sure the new space is full of NULLs */ ! for (i = n->flagbits; i <= f->bitpos; i++) ! n->flags[i] = NULL; } /* Put the canonical flag in the flags array */ ! n->flags[f->bitpos] = f; ! n->flagbits = f->bitpos + 1; ! if (n->flagbits % 8 == 1) { /* We've crossed over a byte boundary, so we need to realloc * all the flags on all our objects to get them an additional * byte. */ ! realloc_object_flag_bitmasks((n->flagbits + 7) / 8); } } } + /* Eventually, this need to compute numbytes itself from the + * total bytes required for flags + powers + */ static void realloc_object_flag_bitmasks(int numbytes) { *************** *** 504,521 **** * \param in file pointer to read from. */ void ! flag_read_all(FILE * in) { FLAG *f; char alias[BUFFER_LEN]; /* If we are reading flags from the db, they are definitive. */ ! clear_all_flags(); while ((f = flag_read(in))) { ! flag_add(f->name, f); } /* Assumes we'll always have at least one alias */ while ((f = flag_alias_read(in, alias))) { ! flag_add(alias, f); } flag_add_additional(); } --- 524,547 ---- * \param in file pointer to read from. */ void ! flag_read_all(FILE * in, const char *ns) { FLAG *f; + FLAGSPACE *n; char alias[BUFFER_LEN]; + + if (!(n = (FLAGSPACE *) hashfind(ns, &htab_flagspaces))) { + do_rawlog(LT_ERR, T("FLAG READ: Unable to locate flagspace %s."), ns); + return; + } /* If we are reading flags from the db, they are definitive. */ ! clear_all_flags(n); while ((f = flag_read(in))) { ! flag_add(n, f->name, f); } /* Assumes we'll always have at least one alias */ while ((f = flag_alias_read(in, alias))) { ! flag_add(n, alias, f); } flag_add_additional(); } *************** *** 547,599 **** * \param out file pointer to write to. */ void ! flag_write_all(FILE * out) { int i; FLAG *f; char flagname[BUFFER_LEN]; /* Write out canonical flags first */ ! for (i = 0; i < flagbits; i++) { ! if (flags[i]) ! flag_write(out, flags[i], flags[i]->name); } putstring(out, "FLAG ALIASES"); /* Now write out aliases. An alias is a flag in the ptab whose * name isn't the same as the name of the canonical flag in its * bit position */ ! f = ptab_firstentry_new(&ptab_flag, flagname); while (f) { ! if (strcmp(flags[f->bitpos]->name, flagname)) { /* This is an alias! */ flag_alias_write(out, f, flagname); } ! f = ptab_nextentry_new(&ptab_flag, flagname); } putstring(out, "END OF FLAGS"); } ! /** Initialize the flag table with defaults. * This function loads the standard flags as a baseline * (and for dbs that haven't yet converted). */ void ! init_flag_table(void) { FLAG *f, *cf; FLAG_ALIAS *a; ! ptab_init(&ptab_flag); /* do regular flags first */ ! for (f = flag_table; f->name; f++) { cf = clone_flag(f); cf->bitpos = -1; ! flag_add(cf->name, cf); } /* now add in the aliases */ ! for (a = flag_alias_tab; a->alias; a++) { ! if ((f = match_flag(a->realname))) ! flag_add(a->alias, f); else do_rawlog(LT_ERR, T("FLAG INIT: flag alias %s matches no known flag."), a->alias); --- 573,656 ---- * \param out file pointer to write to. */ void ! flag_write_all(FILE * out, const char *ns) { int i; FLAG *f; + FLAGSPACE *n; char flagname[BUFFER_LEN]; + + if (!(n = (FLAGSPACE *) hashfind(ns, &htab_flagspaces))) { + do_rawlog(LT_ERR, T("FLAG WRITE: Unable to locate flagspace %s."), ns); + return; + } /* Write out canonical flags first */ ! for (i = 0; i < n->flagbits; i++) { ! if (n->flags[i]) ! flag_write(out, n->flags[i], n->flags[i]->name); } putstring(out, "FLAG ALIASES"); /* Now write out aliases. An alias is a flag in the ptab whose * name isn't the same as the name of the canonical flag in its * bit position */ ! f = ptab_firstentry_new(n->tab, flagname); while (f) { ! if (strcmp(n->flags[f->bitpos]->name, flagname)) { /* This is an alias! */ flag_alias_write(out, f, flagname); } ! f = ptab_nextentry_new(n->tab, flagname); } putstring(out, "END OF FLAGS"); } + /** Initialize the flagspaces. + */ + void + init_flagspaces(void) + { + FLAGSPACE *flags; + + hashinit(&htab_flagspaces, 4, sizeof(FLAGSPACE)); + flags = (FLAGSPACE *) mush_malloc(sizeof(FLAGSPACE), "flagspace"); + flags->tab = &ptab_flag; + flags->flagbits = 0; + flags->flags = NULL; + flags->flag_table = flag_table; + flags->flag_alias_table = flag_alias_tab; + hashadd("FLAG", (void *) flags, &htab_flagspaces); + } + ! /** Initialize a flag table with defaults. * This function loads the standard flags as a baseline * (and for dbs that haven't yet converted). + * \param ns name of flagspace to initialize. */ void ! init_flag_table(const char *ns) { FLAG *f, *cf; FLAG_ALIAS *a; ! FLAGSPACE *n; ! ! if (!(n = (FLAGSPACE *) hashfind(ns, &htab_flagspaces))) { ! do_rawlog(LT_ERR, T("FLAG INIT: Unable to locate flagspace %s."), ns); ! return; ! } ! ! ptab_init(n->tab); /* do regular flags first */ ! for (f = n->flag_table; f->name; f++) { cf = clone_flag(f); cf->bitpos = -1; ! flag_add(n, cf->name, cf); } /* now add in the aliases */ ! for (a = n->flag_alias_table; a->alias; a++) { ! if ((f = match_flag_ns(n, a->realname))) ! flag_add(n, a->alias, f); else do_rawlog(LT_ERR, T("FLAG INIT: flag alias %s matches no known flag."), a->alias); *************** *** 657,663 **** flags_from_old_flags(long old_flags, long old_toggles, int type) { FLAG *f, *newf; ! object_flag_type bitmask = new_flag_bitmask(); for (f = flag_table; f->name; f++) { if (f->type == NOTYPE) { if (f->bitpos & old_flags) { --- 714,721 ---- flags_from_old_flags(long old_flags, long old_toggles, int type) { FLAG *f, *newf; ! object_flag_type bitmask = new_flag_bitmask("FLAG"); ! for (f = flag_table; f->name; f++) { if (f->type == NOTYPE) { if (f->bitpos & old_flags) { *************** *** 685,696 **** /* Given a single character, return the matching flag definition */ static FLAG * ! letter_to_flagptr(char c, int type) { FLAG *f; int i; ! for (i = 0; i < flagbits; i++) ! if ((f = flags[i])) { /* Doh! Kludge-city. We'll ignore the CHOWN_OK flag on players, because * it's more useful to check 'C' as COLOR. Argle. */ --- 743,754 ---- /* Given a single character, return the matching flag definition */ static FLAG * ! letter_to_flagptr(FLAGSPACE * n, char c, int type) { FLAG *f; int i; ! for (i = 0; i < n->flagbits; i++) ! if ((f = n->flags[i])) { /* Doh! Kludge-city. We'll ignore the CHOWN_OK flag on players, because * it's more useful to check 'C' as COLOR. Argle. */ *************** *** 712,718 **** /** Locate a specific bit within a byte given a bit position */ #define FlagBit(x) (7 - (x % 8)) /** How many bytes do we need for a flag bitmask? */ ! #define FlagBytes ((size_t)((flagbits + 7) / 8)) /** Allocate a new flag bitmask. * This function allocates a new flag bitmask of sufficient length --- 770,777 ---- /** Locate a specific bit within a byte given a bit position */ #define FlagBit(x) (7 - (x % 8)) /** How many bytes do we need for a flag bitmask? */ ! #define FlagBytes(n) ((size_t)((n->flagbits + 7) / 8)) ! /** Allocate a new flag bitmask. * This function allocates a new flag bitmask of sufficient length *************** *** 721,733 **** * \return a newly allocated zeroed flag bitmask. */ object_flag_type ! new_flag_bitmask(void) { object_flag_type bitmask; ! bitmask = (object_flag_type) mush_malloc(FlagBytes, "flag_bitmask"); if (!bitmask) panic("Unable to allocate memory for flag bitmask"); ! memset(bitmask, 0, FlagBytes); return bitmask; } --- 780,794 ---- * \return a newly allocated zeroed flag bitmask. */ object_flag_type ! new_flag_bitmask(const char *ns) { object_flag_type bitmask; ! FLAGSPACE *n; ! Flagspace_Lookup(n, ns); ! bitmask = (object_flag_type) mush_malloc(FlagBytes(n), "flag_bitmask"); if (!bitmask) panic("Unable to allocate memory for flag bitmask"); ! memset(bitmask, 0, FlagBytes(n)); return bitmask; } *************** *** 739,751 **** * \return a newly allocated clone of the given bitmask. */ object_flag_type ! clone_flag_bitmask(object_flag_type given) { object_flag_type bitmask; ! bitmask = (object_flag_type) mush_malloc(FlagBytes, "flag_bitmask"); if (!bitmask) panic("Unable to allocate memory for flag bitmask"); ! memcpy(bitmask, given, FlagBytes); return bitmask; } --- 800,814 ---- * \return a newly allocated clone of the given bitmask. */ object_flag_type ! clone_flag_bitmask(const char *ns, object_flag_type given) { object_flag_type bitmask; ! FLAGSPACE *n; ! Flagspace_Lookup(n, ns); ! bitmask = (object_flag_type) mush_malloc(FlagBytes(n), "flag_bitmask"); if (!bitmask) panic("Unable to allocate memory for flag bitmask"); ! memcpy(bitmask, given, FlagBytes(n)); return bitmask; } *************** *** 756,764 **** */ /* Copy a given bitmask to an already-allocated destination bitmask */ void ! copy_flag_bitmask(object_flag_type dest, object_flag_type given) { ! memcpy((void *) dest, (void *) given, FlagBytes); } /** Deallocate a flag bitmask. --- 819,829 ---- */ /* Copy a given bitmask to an already-allocated destination bitmask */ void ! copy_flag_bitmask(const char *ns, object_flag_type dest, object_flag_type given) { ! FLAGSPACE *n; ! Flagspace_Lookup(n, ns); ! memcpy((void *) dest, (void *) given, FlagBytes(n)); } /** Deallocate a flag bitmask. *************** *** 834,844 **** * \retval 0 at least one bit in bitmask is not set in source. */ int ! has_all_bits(object_flag_type source, object_flag_type bitmask) { unsigned int i; int ok = 1; ! for (i = 0; i < FlagBytes; i++) ok &= ((*(bitmask + i) & *(source + i)) == *(bitmask + i)); return ok; } --- 899,911 ---- * \retval 0 at least one bit in bitmask is not set in source. */ int ! has_all_bits(const char *ns, object_flag_type source, object_flag_type bitmask) { unsigned int i; int ok = 1; ! FLAGSPACE *n; ! Flagspace_Lookup(n, ns); ! for (i = 0; i < FlagBytes(n); i++) ok &= ((*(bitmask + i) & *(source + i)) == *(bitmask + i)); return ok; } *************** *** 849,859 **** * \retval 0 at least one bit in bitmask is 1. */ int ! null_flagmask(object_flag_type source) { unsigned int i; int bad = 0; ! for (i = 0; i < FlagBytes; i++) bad |= *(source + i); return (!bad); } --- 916,928 ---- * \retval 0 at least one bit in bitmask is 1. */ int ! null_flagmask(const char *ns, object_flag_type source) { unsigned int i; int bad = 0; ! FLAGSPACE *n; ! Flagspace_Lookup(n, ns); ! for (i = 0; i < FlagBytes(n); i++) bad |= *(source + i); return (!bad); } *************** *** 867,877 **** * \retval 0 no bits in bitmask are set in source. */ int ! has_any_bits(object_flag_type source, object_flag_type bitmask) { unsigned int i; int ok = 0; ! for (i = 0; i < FlagBytes; i++) ok |= (*(bitmask + i) & *(source + i)); return ok; } --- 936,948 ---- * \retval 0 no bits in bitmask are set in source. */ int ! has_any_bits(const char *ns, object_flag_type source, object_flag_type bitmask) { unsigned int i; int ok = 0; ! FLAGSPACE *n; ! Flagspace_Lookup(n, ns); ! for (i = 0; i < FlagBytes(n); i++) ok |= (*(bitmask + i) & *(source + i)); return ok; } *************** *** 884,899 **** * \return string representation of bitmask (list of flags). */ const char * ! bits_to_string(object_flag_type bitmask, dbref privs, dbref thing) { FLAG *f; int i; int first = 1; static char buf[BUFFER_LEN]; char *bp; bp = buf; ! for (i = 0; i < flagbits; i++) { ! if ((f = flags[i])) { if (has_bit(bitmask, f->bitpos) && (!GoodObject(thing) || Can_See_Flag(privs, thing, f))) { if (!first) --- 955,974 ---- * \return string representation of bitmask (list of flags). */ const char * ! bits_to_string(const char *ns, object_flag_type bitmask, dbref privs, ! dbref thing) { FLAG *f; + FLAGSPACE *n; int i; int first = 1; static char buf[BUFFER_LEN]; char *bp; + + Flagspace_Lookup(n, ns); bp = buf; ! for (i = 0; i < n->flagbits; i++) { ! if ((f = n->flags[i])) { if (has_bit(bitmask, f->bitpos) && (!GoodObject(thing) || Can_See_Flag(privs, thing, f))) { if (!first) *************** *** 914,932 **** * \return a newly allocated flag bitmask. */ object_flag_type ! string_to_bits(const char *str) { object_flag_type bitmask; char *copy, *s, *sp; FLAG *f; ! bitmask = new_flag_bitmask(); if (!str) return bitmask; /* We're done, then */ copy = strdup(str); s = trim_space_sep(copy, ' '); while (s) { sp = split_token(&s, ' '); ! if (!(f = match_flag(sp))) /* Now what do we do? Ignore it? */ continue; set_flag_bitmask(bitmask, f->bitpos); --- 989,1013 ---- * \return a newly allocated flag bitmask. */ object_flag_type ! string_to_bits(const char *ns, const char *str) { object_flag_type bitmask; char *copy, *s, *sp; FLAG *f; ! FLAGSPACE *n; ! ! bitmask = new_flag_bitmask(ns); ! if (!(n = (FLAGSPACE *) hashfind(ns, &htab_flagspaces))) { ! do_rawlog(LT_ERR, T("FLAG: Unable to locate flagspace %s."), ns); ! return bitmask; ! } if (!str) return bitmask; /* We're done, then */ copy = strdup(str); s = trim_space_sep(copy, ' '); while (s) { sp = split_token(&s, ' '); ! if (!(f = match_flag_ns(n, sp))) /* Now what do we do? Ignore it? */ continue; set_flag_bitmask(bitmask, f->bitpos); *************** *** 954,960 **** has_flag_by_name(dbref thing, const char *flag, int type) { FLAG *f; ! f = flag_hash_lookup(flag, type); if (!f) return 0; return has_flag(thing, f); --- 1035,1043 ---- has_flag_by_name(dbref thing, const char *flag, int type) { FLAG *f; ! FLAGSPACE *n; ! n = hashfind("FLAG", &htab_flagspaces); ! f = flag_hash_lookup(n, flag, type); if (!f) return 0; return has_flag(thing, f); *************** *** 1053,1058 **** --- 1136,1144 ---- char *p; FLAG *f; int i; + FLAGSPACE *n; + + Flagspace_Lookup(n, "FLAG"); p = buf; switch (Typeof(thing)) { case TYPE_GARBAGE: *************** *** 1071,1078 **** *p++ = 'P'; break; } ! for (i = 0; i < flagbits; i++) { ! if ((f = flags[i])) { if (has_flag(thing, f) && Can_See_Flag(player, thing, f)) *p++ = f->letter; } --- 1157,1164 ---- *p++ = 'P'; break; } ! for (i = 0; i < n->flagbits; i++) { ! if ((f = n->flags[i])) { if (has_flag(thing, f) && Can_See_Flag(player, thing, f)) *p++ = f->letter; } *************** *** 1095,1101 **** safe_str(T("Type: "), buf, &bp); safe_str(privs_to_string(type_privs, Typeof(thing)), buf, &bp); safe_str(T(" Flags: "), buf, &bp); ! safe_str(bits_to_string(Flags(thing), player, thing), buf, &bp); *bp = '\0'; return buf; } --- 1181,1187 ---- safe_str(T("Type: "), buf, &bp); safe_str(privs_to_string(type_privs, Typeof(thing)), buf, &bp); safe_str(T(" Flags: "), buf, &bp); ! safe_str(bits_to_string("FLAG", Flags(thing), player, thing), buf, &bp); *bp = '\0'; return buf; } *************** *** 1112,1119 **** { FLAG *f; int i; ! for (i = 0; i < flagbits; i++) ! if ((f = flags[i])) { if (has_flag(thing, f) && Can_See_Flag(player, thing, f)) notify_format(player, "@set %s = %s", name, f->name); } --- 1198,1207 ---- { FLAG *f; int i; ! FLAGSPACE *n; ! Flagspace_Lookup(n, "FLAG"); ! for (i = 0; i < n->flagbits; i++) ! if ((f = n->flags[i])) { if (has_flag(thing, f) && Can_See_Flag(player, thing, f)) notify_format(player, "@set %s = %s", name, f->name); } *************** *** 1128,1140 **** * \param negate if 1, clear the flag, if 0, set the flag. */ void ! twiddle_flag_internal(dbref thing, const char *flag, int negate) { FLAG *f; if (IsGarbage(thing)) return; ! if ((f = flag_hash_lookup(flag, Typeof(thing)))) ! twiddle_flag(thing, f, negate); } --- 1216,1232 ---- * \param negate if 1, clear the flag, if 0, set the flag. */ void ! twiddle_flag_internal(const char *ns, dbref thing, const char *flag, int negate) { FLAG *f; + FLAGSPACE *n; if (IsGarbage(thing)) return; ! n = (FLAGSPACE *) hashfind(ns, &htab_flagspaces); ! if ((f = flag_hash_lookup(n, flag, Typeof(thing)))) { ! if (n->flag_table == flag_table) ! twiddle_flag(thing, f, negate); ! } } *************** *** 1157,1163 **** FLAG *f; char tbuf1[BUFFER_LEN]; char *tp; ! if ((f = flag_hash_lookup(flag, Typeof(thing))) == NULL) { notify(player, T("I don't recognize that flag.")); return; } --- 1249,1258 ---- FLAG *f; char tbuf1[BUFFER_LEN]; char *tp; ! FLAGSPACE *n; ! ! n = (FLAGSPACE *) hashfind("FLAG", &htab_flagspaces); ! if ((f = flag_hash_lookup(n, flag, Typeof(thing))) == NULL) { notify(player, T("I don't recognize that flag.")); return; } *************** *** 1314,1328 **** * \retval 0 object has no (or not all) flags. */ int ! flaglist_check(dbref player, dbref it, const char *fstr, int type) { char *s; FLAG *fp; int negate, temp; int ret = type; negate = temp = 0; if (!GoodObject(it)) return 0; for (s = (char *) fstr; *s; s++) { /* Check for a negation sign. If we find it, we note it and * increment the pointer to the next character. --- 1409,1430 ---- * \retval 0 object has no (or not all) flags. */ int ! flaglist_check(const char *ns, dbref player, dbref it, const char *fstr, ! int type) { char *s; FLAG *fp; int negate, temp; int ret = type; + FLAGSPACE *n; + negate = temp = 0; if (!GoodObject(it)) return 0; + if (!(n = (FLAGSPACE *) hashfind(ns, &htab_flagspaces))) { + do_rawlog(LT_ERR, T("FLAG: Unable to locate flagspace %s"), ns); + return 0; + } for (s = (char *) fstr; *s; s++) { /* Check for a negation sign. If we find it, we note it and * increment the pointer to the next character. *************** *** 1339,1345 **** * Fail the check. */ return (type == 1) ? 0 : ret; /* Find the flag. */ ! if ((fp = letter_to_flagptr(*s, Typeof(it))) == NULL) { /* Maybe *s is a type specifier (P, T, E, R). These aren't really * flags, but we grandfather them in to preserve old code */ --- 1441,1447 ---- * Fail the check. */ return (type == 1) ? 0 : ret; /* Find the flag. */ ! if ((fp = letter_to_flagptr(n, *s, Typeof(it))) == NULL) { /* Maybe *s is a type specifier (P, T, E, R). These aren't really * flags, but we grandfather them in to preserve old code */ *************** *** 1396,1410 **** * \retval 0 object has no (or not all) flags. */ int ! flaglist_check_long(dbref player, dbref it, const char *fstr, int type) { char *s, *copy, *sp; FLAG *fp; int negate, temp; int ret = type; negate = temp = 0; if (!GoodObject(it)) return 0; copy = strdup(fstr); sp = trim_space_sep(copy, ' '); while (sp) { --- 1498,1518 ---- * \retval 0 object has no (or not all) flags. */ int ! flaglist_check_long(const char *ns, dbref player, dbref it, const char *fstr, ! int type) { char *s, *copy, *sp; FLAG *fp; int negate, temp; int ret = type; + FLAGSPACE *n; negate = temp = 0; if (!GoodObject(it)) return 0; + if (!(n = (FLAGSPACE *) hashfind(ns, &htab_flagspaces))) { + do_rawlog(LT_ERR, T("FLAG: Unable to locate flagspace %s"), ns); + return 0; + } copy = strdup(fstr); sp = trim_space_sep(copy, ' '); while (sp) { *************** *** 1424,1430 **** * Fail the check. */ return (type == 1) ? 0 : ret; /* Find the flag. */ ! if (!(fp = flag_hash_lookup(s, Typeof(it)))) { /* Either we got a '!' that wasn't followed by a letter, or * we couldn't find that flag. For AND, since we've failed * a check, we can return false. Otherwise we just go on. --- 1532,1538 ---- * Fail the check. */ return (type == 1) ? 0 : ret; /* Find the flag. */ ! if (!(fp = flag_hash_lookup(n, s, Typeof(it)))) { /* Either we got a '!' that wasn't followed by a letter, or * we couldn't find that flag. For AND, since we've failed * a check, we can return false. Otherwise we just go on. *************** *** 1480,1486 **** { /* Does thing have the flag named name && can privs see it? */ FLAG *f; ! if ((f = flag_hash_lookup(name, Typeof(thing))) == NULL) return 0; return has_flag(thing, f) && Can_See_Flag(privs, thing, f); } --- 1588,1596 ---- { /* Does thing have the flag named name && can privs see it? */ FLAG *f; ! FLAGSPACE *n; ! n = hashfind("FLAG", &htab_flagspaces); ! if ((f = flag_hash_lookup(n, name, Typeof(thing))) == NULL) return 0; return has_flag(thing, f) && Can_See_Flag(privs, thing, f); } *************** *** 1504,1512 **** --- 1614,1624 ---- int perms, int negate_perms) { FLAG *f; + FLAGSPACE *n; /* Don't double-add */ if (match_flag(name)) return; + n = hashfind("FLAG", &htab_flagspaces); f = new_flag(); f->name = strdup(strupper(name)); f->letter = letter; *************** *** 1514,1520 **** f->perms = perms; f->negate_perms = negate_perms; f->bitpos = -1; ! flag_add(f->name, f); } --- 1626,1632 ---- f->perms = perms; f->negate_perms = negate_perms; f->bitpos = -1; ! flag_add(n, f->name, f); } *************** *** 1533,1539 **** void do_list_flags(dbref player, const char *arg, int lc) { ! char *b = list_all_flags(arg, player, 0x3); notify_format(player, T("Flags: %s"), lc ? strlower(b) : b); } --- 1645,1651 ---- void do_list_flags(dbref player, const char *arg, int lc) { ! char *b = list_all_flags("FLAG", arg, player, 0x3); notify_format(player, T("Flags: %s"), lc ? strlower(b) : b); } *************** *** 1545,1564 **** * \param name name of the flag to describe. */ void ! do_flag_info(dbref player, const char *name) { FLAG *f; /* Find the flag */ ! f = flag_hash_lookup(name, NOTYPE); if (!f && God(player)) ! f = match_flag(name); if (!f) { notify(player, T("No such flag.")); return; } notify_format(player, T("Flag name: %s"), f->name); notify_format(player, T("Flag char: %c"), f->letter); ! notify_format(player, " Aliases: %s", list_aliases(f)); notify_format(player, " Type(s): %s", privs_to_string(type_privs, f->type)); notify_format(player, " Perms: %s", privs_to_string(flag_privs, f->perms)); notify_format(player, "ResetPrms: %s", --- 1657,1683 ---- * \param name name of the flag to describe. */ void ! do_flag_info(const char *ns, dbref player, const char *name) { FLAG *f; + FLAGSPACE *n; + /* Find the flagspace */ + if (!(n = (FLAGSPACE *) hashfind(ns, &htab_flagspaces))) { + do_rawlog(LT_ERR, T("FLAG: Unable to locate flagspace %s"), ns); + return; + } + /* Find the flag */ ! f = flag_hash_lookup(n, name, NOTYPE); if (!f && God(player)) ! f = match_flag_ns(n, name); if (!f) { notify(player, T("No such flag.")); return; } notify_format(player, T("Flag name: %s"), f->name); notify_format(player, T("Flag char: %c"), f->letter); ! notify_format(player, " Aliases: %s", list_aliases(n, f)); notify_format(player, " Type(s): %s", privs_to_string(type_privs, f->type)); notify_format(player, " Perms: %s", privs_to_string(flag_privs, f->perms)); notify_format(player, "ResetPrms: %s", *************** *** 1581,1592 **** do_flag_restrict(dbref player, const char *name, char *args_right[]) { FLAG *f; int perms, negate_perms; if (!God(player)) { notify(player, T("You don't have enough magic for that.")); return; } ! if (!(f = flag_hash_lookup(name, NOTYPE))) { notify(player, T("No such flag.")); return; } --- 1700,1714 ---- do_flag_restrict(dbref player, const char *name, char *args_right[]) { FLAG *f; + FLAGSPACE *n; int perms, negate_perms; + if (!God(player)) { notify(player, T("You don't have enough magic for that.")); return; } ! n = hashfind("FLAG", &htab_flagspaces); ! if (!(f = flag_hash_lookup(n, name, NOTYPE))) { notify(player, T("No such flag.")); return; } *************** *** 1645,1650 **** --- 1767,1774 ---- int perms = F_ANY; int negate_perms = F_ANY; FLAG *f; + FLAGSPACE *n; + if (!God(player)) { notify(player, T("You don't have enough magic for that.")); return; *************** *** 1661,1670 **** notify(player, T("Flag names may not contain spaces.")); return; } ! if ((f = flag_hash_lookup(name, NOTYPE))) { ! notify_format(player, T("Name conflicts with the %s flag."), f->name); ! return; ! } /* Do we have a letter? */ if (args_right[1]) { if (strlen(args_right[1]) > 1) { --- 1785,1791 ---- notify(player, T("Flag names may not contain spaces.")); return; } ! Flagspace_Lookup(n, "FLAG"); /* Do we have a letter? */ if (args_right[1]) { if (strlen(args_right[1]) > 1) { *************** *** 1683,1689 **** } /* Is this letter already in use for this type? */ if (*args_right[1]) { ! if ((f = letter_to_flagptr(*args_right[1], type))) { notify_format(player, T("Letter conflicts with the %s flag."), f->name); return; } --- 1804,1810 ---- } /* Is this letter already in use for this type? */ if (*args_right[1]) { ! if ((f = letter_to_flagptr(n, *args_right[1], type))) { notify_format(player, T("Letter conflicts with the %s flag."), f->name); return; } *************** *** 1717,1723 **** add_flag(name, letter, type, perms, negate_perms); /* Did it work? */ if ((f = match_flag(name))) ! do_flag_info(player, name); else notify(player, T("Unknown failure adding flag.")); } --- 1838,1844 ---- add_flag(name, letter, type, perms, negate_perms); /* Did it work? */ if ((f = match_flag(name))) ! do_flag_info("FLAG", player, name); else notify(player, T("Unknown failure adding flag.")); } *************** *** 1734,1739 **** --- 1855,1861 ---- do_flag_alias(dbref player, const char *name, const char *alias) { FLAG *f; + FLAGSPACE *n; if (!God(player)) { notify(player, T("You don't look like God.")); return; *************** *** 1750,1762 **** notify(player, T("Flag aliases may not contain spaces.")); return; } ! f = match_flag(alias); if (f) { notify_format(player, T("That alias already matches the %s flag."), f->name); return; } ! f = match_flag(name); if (!f) { notify(player, T("I don't know that flag.")); return; --- 1872,1885 ---- notify(player, T("Flag aliases may not contain spaces.")); return; } ! n = hashfind("FLAG", &htab_flagspaces); ! f = match_flag_ns(n, alias); if (f) { notify_format(player, T("That alias already matches the %s flag."), f->name); return; } ! f = match_flag_ns(n, name); if (!f) { notify(player, T("I don't know that flag.")); return; *************** *** 1766,1776 **** return; } /* Insert the flag in the ptab by the given alias */ ! ptab_start_inserts(&ptab_flag); ! ptab_insert(&ptab_flag, alias, f); ! ptab_end_inserts(&ptab_flag); ! if ((f = match_flag(alias))) ! do_flag_info(player, alias); else notify(player, T("Unknown failure adding alias.")); } --- 1889,1899 ---- return; } /* Insert the flag in the ptab by the given alias */ ! ptab_start_inserts(n->tab); ! ptab_insert(n->tab, alias, f); ! ptab_end_inserts(n->tab); ! if ((f = match_flag_ns(n, alias))) ! do_flag_info("FLAG", player, alias); else notify(player, T("Unknown failure adding alias.")); } *************** *** 1824,1834 **** char flagname[BUFFER_LEN]; dbref i; int got_one; if (!God(player)) { notify(player, T("You don't look like God.")); return; } ! f = ptab_find_exact(&ptab_flag, name); if (!f) { notify(player, T("I don't know that flag.")); return; --- 1947,1960 ---- char flagname[BUFFER_LEN]; dbref i; int got_one; + FLAGSPACE *n; + if (!God(player)) { notify(player, T("You don't look like God.")); return; } ! n = (FLAGSPACE *) hashfind("FLAG", &htab_flagspaces); ! f = ptab_find_exact(n->tab, name); if (!f) { notify(player, T("I don't know that flag.")); return; *************** *** 1842,1865 **** */ do { got_one = 0; ! tmpf = ptab_firstentry_new(&ptab_flag, flagname); while (tmpf) { if (!strcmp(tmpf->name, f->name) && ! strcmp(flags[f->bitpos]->name, flagname)) { ! ptab_delete(&ptab_flag, flagname); got_one = 1; break; } ! tmpf = ptab_nextentry_new(&ptab_flag, flagname); } } while (got_one); /* Reset the flag on all objects */ for (i = 0; i < db_top; i++) twiddle_flag(i, f, 1); /* Remove the flag's entry in flags */ ! flags[f->bitpos] = NULL; /* Remove the flag from the ptab */ ! ptab_delete(&ptab_flag, f->name); notify_format(player, T("Flag %s deleted."), f->name); /* Free the flag. Don't use mush_free, see new_flag() */ free((Malloc_t) f); --- 1968,1991 ---- */ do { got_one = 0; ! tmpf = ptab_firstentry_new(n->tab, flagname); while (tmpf) { if (!strcmp(tmpf->name, f->name) && ! strcmp(n->flags[f->bitpos]->name, flagname)) { ! ptab_delete(n->tab, flagname); got_one = 1; break; } ! tmpf = ptab_nextentry_new(n->tab, flagname); } } while (got_one); /* Reset the flag on all objects */ for (i = 0; i < db_top; i++) twiddle_flag(i, f, 1); /* Remove the flag's entry in flags */ ! n->flags[f->bitpos] = NULL; /* Remove the flag from the ptab */ ! ptab_delete(n->tab, f->name); notify_format(player, T("Flag %s deleted."), f->name); /* Free the flag. Don't use mush_free, see new_flag() */ free((Malloc_t) f); *************** *** 1897,1903 **** static char * ! list_aliases(FLAG *given) { FLAG *f; static char buf[BUFFER_LEN]; --- 2023,2029 ---- static char * ! list_aliases(FLAGSPACE * n, FLAG *given) { FLAG *f; static char buf[BUFFER_LEN]; *************** *** 1905,1921 **** char flagname[BUFFER_LEN]; int first = 1; bp = buf; ! f = ptab_firstentry_new(&ptab_flag, flagname); while (f) { if (!strcmp(given->name, f->name) && ! strcmp(flags[f->bitpos]->name, flagname)) { /* This is an alias! */ if (!first) safe_chr(' ', buf, &bp); first = 0; safe_str(flagname, buf, &bp); } ! f = ptab_nextentry_new(&ptab_flag, flagname); } *bp = '\0'; return buf; --- 2031,2047 ---- char flagname[BUFFER_LEN]; int first = 1; bp = buf; ! f = ptab_firstentry_new(n->tab, flagname); while (f) { if (!strcmp(given->name, f->name) && ! strcmp(n->flags[f->bitpos]->name, flagname)) { /* This is an alias! */ if (!first) safe_chr(' ', buf, &bp); first = 0; safe_str(flagname, buf, &bp); } ! f = ptab_nextentry_new(n->tab, flagname); } *bp = '\0'; return buf; *************** *** 1928,1934 **** * \param which a bitmask of 0x1 (flag chars) and 0x2 (flag names)u */ char * ! list_all_flags(const char *name, dbref privs, int which) { FLAG *f; char **ptrs; --- 2054,2060 ---- * \param which a bitmask of 0x1 (flag chars) and 0x2 (flag names)u */ char * ! list_all_flags(const char *ns, const char *name, dbref privs, int which) { FLAG *f; char **ptrs; *************** *** 1936,1945 **** static char buf[BUFFER_LEN]; char *bp; int disallowed; disallowed = God(privs) ? F_INTERNAL : (F_INTERNAL | F_DISABLED); ! ptrs = (char **) malloc(flagbits * sizeof(char *)); ! for (i = 0; i < flagbits; i++) { ! if ((f = flags[i]) && !(f->perms & disallowed)) { if (!name || !*name || quick_wild(name, f->name)) ptrs[numptrs++] = (char *) f->name; } --- 2062,2074 ---- static char buf[BUFFER_LEN]; char *bp; int disallowed; + FLAGSPACE *n; + + Flagspace_Lookup(n, ns); disallowed = God(privs) ? F_INTERNAL : (F_INTERNAL | F_DISABLED); ! ptrs = (char **) malloc(n->flagbits * sizeof(char *)); ! for (i = 0; i < n->flagbits; i++) { ! if ((f = n->flags[i]) && !(f->perms & disallowed)) { if (!name || !*name || quick_wild(name, f->name)) ptrs[numptrs++] = (char *) f->name; } *************** *** 1952,1958 **** if (i) safe_chr(' ', buf, &bp); safe_str(ptrs[i], buf, &bp); ! f = match_flag(ptrs[i]); if (f && (f->letter != '\0')) safe_format(buf, &bp, " (%c)", f->letter); break; --- 2081,2087 ---- if (i) safe_chr(' ', buf, &bp); safe_str(ptrs[i], buf, &bp); ! f = match_flag_ns(n, ptrs[i]); if (f && (f->letter != '\0')) safe_format(buf, &bp, " (%c)", f->letter); break; *************** *** 1962,1968 **** safe_str(ptrs[i], buf, &bp); break; case 0x1: ! f = match_flag(ptrs[i]); if (f && (f->letter != '\0')) safe_chr(f->letter, buf, &bp); break; --- 2091,2097 ---- safe_str(ptrs[i], buf, &bp); break; case 0x1: ! f = match_flag_ns(n, ptrs[i]); if (f && (f->letter != '\0')) safe_chr(f->letter, buf, &bp); break; *************** *** 2056,2062 **** if (powers) safe_chr('\n', fbuf, &bp); safe_str("Flags : ", fbuf, &bp); ! safe_str(bits_to_string(flagmask, GOD, NOTHING), fbuf, &bp); } *bp = '\0'; --- 2185,2191 ---- if (powers) safe_chr('\n', fbuf, &bp); safe_str("Flags : ", fbuf, &bp); ! safe_str(bits_to_string("FLAG", flagmask, GOD, NOTHING), fbuf, &bp); } *bp = '\0'; *** 1_7_7.551/src/db.c Thu, 14 Aug 2003 12:02:03 -0500 dunemush (pennmush/c/25_db.c 1.26.1.1.1.1.1.6.1.1.1.3 660) --- 1_7_7.557(w)/src/db.c Tue, 19 Aug 2003 23:36:01 -0500 dunemush (pennmush/c/25_db.c 1.26.1.1.1.1.1.6.1.1.1.4 660) *************** *** 216,222 **** o->zone = NOTHING; o->penn = 0; o->type = TYPE_GARBAGE; ! o->flags = new_flag_bitmask(); o->powers = 0; o->warnings = 0; o->modification_time = o->creation_time = mudtime; --- 216,222 ---- o->zone = NOTHING; o->penn = 0; o->type = TYPE_GARBAGE; ! o->flags = new_flag_bitmask("FLAG"); o->powers = 0; o->warnings = 0; o->modification_time = o->creation_time = mudtime; *************** *** 455,461 **** putref(f, o->zone); putref(f, Pennies(i)); putref(f, Typeof(i)); ! putstring(f, bits_to_string(o->flags, GOD, NOTHING)); putref(f, o->powers); /* Original chat system wrote chat channels to the db here. * That's no longer done, they're written to chatdb --- 455,461 ---- putref(f, o->zone); putref(f, Pennies(i)); putref(f, Typeof(i)); ! putstring(f, bits_to_string("FLAG", o->flags, GOD, NOTHING)); putref(f, o->powers); /* Original chat system wrote chat channels to the db here. * That's no longer done, they're written to chatdb *************** *** 556,562 **** db_write_flags(FILE * f) { OUTPUT(fprintf(f, "+FLAGS LIST\n")); ! flag_write_all(f); } --- 556,562 ---- db_write_flags(FILE * f) { OUTPUT(fprintf(f, "+FLAGS LIST\n")); ! flag_write_all(f, "FLAG"); } *************** *** 1055,1061 **** } } else if (c == 'F') { (void) getstring_noalloc(f); ! flag_read_all(f); } else { do_rawlog(LT_ERR, T("Unrecognized database format!")); return -1; --- 1055,1061 ---- } } else if (c == 'F') { (void) getstring_noalloc(f); ! flag_read_all(f, "FLAG"); } else { do_rawlog(LT_ERR, T("Unrecognized database format!")); return -1; *************** *** 1087,1093 **** s_Pennies(i, getref(f)); if (indb_flags & DBF_NEW_FLAGS) { o->type = getref(f); ! o->flags = string_to_bits(getstring_noalloc(f)); } else { int old_flags, old_toggles; old_flags = getref(f); --- 1087,1093 ---- s_Pennies(i, getref(f)); if (indb_flags & DBF_NEW_FLAGS) { o->type = getref(f); ! o->flags = string_to_bits("FLAG", getstring_noalloc(f)); } else { int old_flags, old_toggles; old_flags = getref(f); *** 1_7_7.551/src/create.c Mon, 12 May 2003 16:54:32 -0500 dunemush (pennmush/c/27_create.c 1.27.1.3.1.1.1.1.1.1.1.2.1.1.1.1.1.22 660) --- 1_7_7.557(w)/src/create.c Tue, 19 Aug 2003 23:36:01 -0500 dunemush (pennmush/c/27_create.c 1.27.1.3.1.1.1.1.1.1.1.2.1.1.1.1.1.23 660) *************** *** 122,128 **** Zone(new_exit) = Zone(player); Source(new_exit) = loc; Type(new_exit) = TYPE_EXIT; ! Flags(new_exit) = string_to_bits(options.exit_flags); /* link it in */ PUSH(new_exit, Exits(loc)); --- 122,128 ---- Zone(new_exit) = Zone(player); Source(new_exit) = loc; Type(new_exit) = TYPE_EXIT; ! Flags(new_exit) = string_to_bits("FLAG", options.exit_flags); /* link it in */ PUSH(new_exit, Exits(loc)); *************** *** 389,395 **** Owner(room) = Owner(player); Zone(room) = Zone(player); Type(room) = TYPE_ROOM; ! Flags(room) = string_to_bits(options.room_flags); notify_format(player, T("%s created with room number %d."), name, room); if (argv[1] && *argv[1]) { --- 389,395 ---- Owner(room) = Owner(player); Zone(room) = Zone(player); Type(room) = TYPE_ROOM; ! Flags(room) = string_to_bits("FLAG", options.room_flags); notify_format(player, T("%s created with room number %d."), name, room); if (argv[1] && *argv[1]) { *************** *** 452,458 **** Zone(thing) = Zone(player); s_Pennies(thing, cost); Type(thing) = TYPE_THING; ! Flags(thing) = string_to_bits(options.thing_flags); /* home is here (if we can link to it) or player's home */ if ((loc = Location(player)) != NOTHING && --- 452,458 ---- Zone(thing) = Zone(player); s_Pennies(thing, cost); Type(thing) = TYPE_THING; ! Flags(thing) = string_to_bits("FLAG", options.thing_flags); /* home is here (if we can link to it) or player's home */ if ((loc = Location(player)) != NOTHING && *************** *** 498,504 **** clone_locks(player, thing, clone); Zone(clone) = Zone(thing); Parent(clone) = Parent(thing); ! Flags(clone) = clone_flag_bitmask(Flags(thing)); if (!preserve) { clear_flag_internal(clone, "WIZARD"); clear_flag_internal(clone, "ROYALTY"); --- 498,504 ---- clone_locks(player, thing, clone); Zone(clone) = Zone(thing); Parent(clone) = Parent(thing); ! Flags(clone) = clone_flag_bitmask("FLAG", Flags(thing)); if (!preserve) { clear_flag_internal(clone, "WIZARD"); clear_flag_internal(clone, "ROYALTY"); *************** *** 621,627 **** clone_locks(player, thing, clone); Zone(clone) = Zone(thing); Parent(clone) = Parent(thing); ! Flags(clone) = clone_flag_bitmask(Flags(thing)); if (!preserve) { clear_flag_internal(clone, "WIZARD"); clear_flag_internal(clone, "ROYALTY"); --- 621,627 ---- clone_locks(player, thing, clone); Zone(clone) = Zone(thing); Parent(clone) = Parent(thing); ! Flags(clone) = clone_flag_bitmask("FLAG", Flags(thing)); if (!preserve) { clear_flag_internal(clone, "WIZARD"); clear_flag_internal(clone, "ROYALTY"); *** 1_7_7.551/src/command.c Mon, 11 Aug 2003 15:42:46 -0500 dunemush (pennmush/c/36_command.c 1.56.1.1.1.1.1.1.1.2.1.1.1.1.1.5.1.2.1.1.1.1.1.2.1.3.1.10.1.1.3.10 660) --- 1_7_7.557(w)/src/command.c Tue, 19 Aug 2003 23:36:01 -0500 dunemush (pennmush/c/36_command.c 1.56.1.1.1.1.1.1.1.2.1.1.1.1.1.5.1.2.1.1.1.1.1.2.1.3.1.10.1.1.3.11 660) *************** *** 450,456 **** switch_mask *sw = switchmask(switchstr); if (flagstr) ! flagmask = string_to_bits(flagstr); ptab_start_inserts(&ptab_command); ptab_insert(&ptab_command, name, make_command(name, type, flagmask, powers, sw, func)); --- 450,456 ---- switch_mask *sw = switchmask(switchstr); if (flagstr) ! flagmask = string_to_bits("FLAG", flagstr); ptab_start_inserts(&ptab_command); ptab_insert(&ptab_command, name, make_command(name, type, flagmask, powers, sw, func)); *************** *** 600,608 **** ptab_start_inserts(&ptab_command); for (cmd = commands; cmd->name; cmd++) { ptab_insert(&ptab_command, cmd->name, ! make_command(cmd->name, cmd->type, string_to_bits(cmd->flagstr), ! cmd->powers, switchmask(cmd->switches), ! cmd->func)); } ptab_end_inserts(&ptab_command); --- 600,608 ---- ptab_start_inserts(&ptab_command); for (cmd = commands; cmd->name; cmd++) { ptab_insert(&ptab_command, cmd->name, ! make_command(cmd->name, cmd->type, ! string_to_bits("FLAG", cmd->flagstr), cmd->powers, ! switchmask(cmd->switches), cmd->func)); } ptab_end_inserts(&ptab_command); *************** *** 1141,1147 **** clear_flag_bitmask(command->flagmask, wiz->bitpos); } else { if (!command->flagmask) ! command->flagmask = new_flag_bitmask(); set_flag_bitmask(command->flagmask, roy->bitpos); set_flag_bitmask(command->flagmask, wiz->bitpos); } --- 1141,1147 ---- clear_flag_bitmask(command->flagmask, wiz->bitpos); } else { if (!command->flagmask) ! command->flagmask = new_flag_bitmask("FLAG"); set_flag_bitmask(command->flagmask, roy->bitpos); set_flag_bitmask(command->flagmask, wiz->bitpos); } *************** *** 1155,1161 **** clear_flag_bitmask(command->flagmask, mask->bitpos); else { if (!command->flagmask) ! command->flagmask = new_flag_bitmask(); set_flag_bitmask(command->flagmask, mask->bitpos); } } else if ((powers = match_power(restriction))) { --- 1155,1161 ---- clear_flag_bitmask(command->flagmask, mask->bitpos); else { if (!command->flagmask) ! command->flagmask = new_flag_bitmask("FLAG"); set_flag_bitmask(command->flagmask, mask->bitpos); } } else if ((powers = match_power(restriction))) { *************** *** 1388,1394 **** * any match, the player is ok to do the command. */ ok = 1; ! check_flags = cmd->flagmask && !null_flagmask(cmd->flagmask); if (!((!cmd->powers && !check_flags) || (cmd->powers && (cmd->powers & Powers(player))) || --- 1388,1394 ---- * any match, the player is ok to do the command. */ ok = 1; ! check_flags = cmd->flagmask && !null_flagmask("FLAG", cmd->flagmask); if (!((!cmd->powers && !check_flags) || (cmd->powers && (cmd->powers & Powers(player))) || *** 1_7_7.551/src/cmds.c Wed, 02 Jul 2003 14:19:13 -0500 dunemush (pennmush/c/37_cmds.c 1.33.1.1.1.2.1.2.2.3.1.1.1.2.1.1.1.3.1.8.1.1.2.2.2.19 660) --- 1_7_7.557(w)/src/cmds.c Tue, 19 Aug 2003 23:36:00 -0500 dunemush (pennmush/c/37_cmds.c 1.33.1.1.1.2.1.2.2.3.1.1.1.2.1.1.1.3.1.8.1.1.2.2.2.20 660) *************** *** 290,296 **** else if (SW_ISSET(sw, SWITCH_ENABLE)) do_flag_enable(player, arg_left); else ! do_flag_info(player, arg_left); } COMMAND (cmd_force) { --- 290,296 ---- else if (SW_ISSET(sw, SWITCH_ENABLE)) do_flag_enable(player, arg_left); else ! do_flag_info("FLAG", player, arg_left); } COMMAND (cmd_force) { *** 1_7_7.551/src/bsd.c Sun, 17 Aug 2003 08:30:54 -0500 dunemush (pennmush/c/38_bsd.c 1.58.1.11.1.2.1.5.1.7.1.14.1.13.1.9.1.4.1.2.1.12.1.1.1.1.1.2.1.1.1.13.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.8.2.1.1.1.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.19 660) --- 1_7_7.557(w)/src/bsd.c Tue, 19 Aug 2003 23:36:00 -0500 dunemush (pennmush/c/38_bsd.c 1.58.1.11.1.2.1.5.1.7.1.14.1.13.1.9.1.4.1.2.1.12.1.1.1.1.1.2.1.1.1.13.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.8.2.1.1.1.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.21 660) *************** *** 165,171 **** extern int errno; /**< Error number for routines that use it */ #endif #endif - extern int reserved; /**< A reserved file descriptor */ static int extrafd; int shutdown_flag = 0; /**< Is it time to shut down? */ extern int paranoid_dump; /**< Are we doing a paranoid dump? */ --- 165,170 ---- *************** *** 268,275 **** --- 267,276 ---- static const char *register_success = "Registration successful! You will receive your password by email."; static const char *shutdown_message = "Going down - Bye"; + #ifdef HAS_OPENSSL static const char *ssl_shutdown_message = "GAME: SSL connections must be dropped, sorry."; + #endif static const char *asterisk_line = "**********************************************************************"; /** Where we save the descriptor info across reboots. */ *************** *** 296,303 **** DESC *descriptor_list = NULL; /**< The linked list of descriptors */ ! static int sock, sslsock = 0; #ifdef HAS_OPENSSL SSL *ssl_master_socket = NULL; #endif static int ndescriptors = 0; --- 297,305 ---- DESC *descriptor_list = NULL; /**< The linked list of descriptors */ ! static int sock; #ifdef HAS_OPENSSL + static int sslsock = 0; SSL *ssl_master_socket = NULL; #endif static int ndescriptors = 0; *************** *** 640,648 **** init_game_config(confname); /* save a file descriptor */ #ifndef macintosh #ifndef WIN32 - reserved = open("/dev/null", O_RDWR); extrafd = open("/dev/null", O_RDWR); #endif #endif --- 642,650 ---- init_game_config(confname); /* save a file descriptor */ + reserve_fd(); #ifndef macintosh #ifndef WIN32 extrafd = open("/dev/null", O_RDWR); #endif #endif *************** *** 1411,1424 **** int fd, n; struct stat sb; ! #ifndef macintosh ! close(reserved); ! #endif if ((fd = open(filename, O_RDONLY, 0)) < 0) { do_log(LT_ERR, 0, 0, T("Couldn't open cached text file '%s'"), filename); ! #ifndef macintosh ! reserved = open("/dev/null", O_RDWR); ! #endif return -1; } --- 1413,1422 ---- int fd, n; struct stat sb; ! release_fd(); if ((fd = open(filename, O_RDONLY, 0)) < 0) { do_log(LT_ERR, 0, 0, T("Couldn't open cached text file '%s'"), filename); ! reserve_fd(); return -1; } *************** *** 1426,1434 **** do_log(LT_ERR, 0, 0, T("Couldn't get the size of text file '%s'"), filename); close(fd); ! #ifndef macintosh ! reserved = open("/dev/null", O_RDWR); ! #endif return -1; } --- 1424,1430 ---- do_log(LT_ERR, 0, 0, T("Couldn't get the size of text file '%s'"), filename); close(fd); ! reserve_fd(); return -1; } *************** *** 1437,1445 **** do_log(LT_ERR, 0, 0, T("Couldn't allocate %d bytes of memory for '%s'!"), (int) sb.st_size, filename); close(fd); ! #ifndef macintosh ! reserved = open("/dev/null", O_RDWR); ! #endif return -1; } --- 1433,1439 ---- do_log(LT_ERR, 0, 0, T("Couldn't allocate %d bytes of memory for '%s'!"), (int) sb.st_size, filename); close(fd); ! reserve_fd(); return -1; } *************** *** 1448,1463 **** close(fd); mush_free(fb->buff, "fcache_data"); fb->buff = NULL; ! #ifndef macintosh ! reserved = open("/dev/null", O_RDWR); ! #endif return -1; } close(fd); ! #ifndef macintosh ! reserved = open("/dev/null", O_RDWR); ! #endif fb->len = sb.st_size; #ifdef macintosh --- 1442,1453 ---- close(fd); mush_free(fb->buff, "fcache_data"); fb->buff = NULL; ! reserve_fd(); return -1; } close(fd); ! reserve_fd(); fb->len = sb.st_size; #ifdef macintosh *************** *** 1669,1674 **** --- 1659,1665 ---- ndescriptors--; } + /* ARGSUSED */ static DESC * initializesock(int s, char *addr, char *ip, int use_ssl) { *************** *** 2532,2537 **** --- 2523,2529 ---- } + /* ARGSUSED */ static int process_input(DESC *d, int output_ready) { *** 1_7_7.551/src/attrib.c Sun, 17 Aug 2003 15:38:47 -0500 dunemush (pennmush/c/40_attrib.c 1.15.1.2.1.5.1.1.1.3.1.3.1.2.1.2.1.2.2.1.1.2.1.2.1.2.1.1.1.3.1.1.1.1.1.1.3.23 660) --- 1_7_7.557(w)/src/attrib.c Tue, 19 Aug 2003 23:36:00 -0500 dunemush (pennmush/c/40_attrib.c 1.15.1.2.1.5.1.1.1.3.1.3.1.2.1.2.1.2.2.1.1.2.1.2.1.2.1.1.1.3.1.1.1.1.1.1.3.24 660) *************** *** 594,605 **** if (!wildcard(name)) { ptr = atr_get_noparent(thing, strupper(name)); ! if (ptr && (object_visual || Is_Visible_Attr(thing, ptr))) result = func(player, thing, name, ptr, args); } else { for (ptr = List(thing); ptr; ptr = next) { next = AL_NEXT(ptr); ! if ((object_visual || Is_Visible_Attr(thing, ptr)) && local_wild_match(name, AL_NAME(ptr))) result += func(player, thing, name, ptr, args); } --- 594,607 ---- if (!wildcard(name)) { ptr = atr_get_noparent(thing, strupper(name)); ! if (ptr && (object_visual ? Can_Read_Attr(player, thing, ptr) ! : Is_Visible_Attr(thing, ptr))) result = func(player, thing, name, ptr, args); } else { for (ptr = List(thing); ptr; ptr = next) { next = AL_NEXT(ptr); ! if ((object_visual ? Can_Read_Attr(player, thing, ptr) ! : Is_Visible_Attr(thing, ptr)) && local_wild_match(name, AL_NAME(ptr))) result += func(player, thing, name, ptr, args); } *** 1_7_7.551/src/access.c Mon, 16 Jun 2003 23:53:35 -0500 dunemush (pennmush/c/43_access.c 1.11.1.2.1.4.1.6 660) --- 1_7_7.557(w)/src/access.c Tue, 19 Aug 2003 23:36:00 -0500 dunemush (pennmush/c/43_access.c 1.11.1.2.1.4.1.7 660) *************** *** 114,120 **** }; static struct access *access_top; - extern int reserved; /**< reserved file descriptor */ static int add_access_node (const char *host, const dbref who, const int can, const int cant, const char *comment); --- 114,119 ---- *************** *** 177,185 **** } access_top = NULL; /* Be sure we have a file descriptor */ ! #ifndef WIN32 ! close(reserved); ! #endif #ifdef macintosh fp = fopen(ACCESS_FILE, "rb"); #else --- 176,182 ---- } access_top = NULL; /* Be sure we have a file descriptor */ ! release_fd(); #ifdef macintosh fp = fopen(ACCESS_FILE, "rb"); #else *************** *** 227,235 **** retval = 1; fclose(fp); } ! #ifndef WIN32 ! reserved = open("/dev/null", O_RDWR); ! #endif return retval; } --- 224,230 ---- retval = 1; fclose(fp); } ! reserve_fd(); return retval; } *************** *** 246,254 **** sprintf(tmpf, "%s.tmp", ACCESS_FILE); /* Be sure we have a file descriptor */ ! #ifndef WIN32 ! close(reserved); ! #endif #ifdef macintosh fp = fopen(tmpf, "wb"); #else --- 241,247 ---- sprintf(tmpf, "%s.tmp", ACCESS_FILE); /* Be sure we have a file descriptor */ ! release_fd(); #ifdef macintosh fp = fopen(tmpf, "wb"); #else *************** *** 296,304 **** #endif rename(tmpf, ACCESS_FILE); } ! #ifndef WIN32 ! reserved = open("/dev/null", O_RDWR); ! #endif return; } --- 289,295 ---- #endif rename(tmpf, ACCESS_FILE); } ! reserve_fd(); return; } *** 1_7_7.551/hdrs/csrimalloc.h Mon, 28 Apr 2003 22:37:00 -0500 dunemush (pennmush/c/45_csrimalloc 1.8 660) --- 1_7_7.557(w)/hdrs/csrimalloc.h Tue, 19 Aug 2003 23:36:08 -0500 dunemush (pennmush/c/45_csrimalloc 1.9 660) *************** *** 90,96 **** --- 90,98 ---- * SunOS3.5, this works fine. */ #ifdef __GNUC__ + #ifndef alloca #define alloca(n) __builtin_alloca(n) + #endif #endif /* __GNUC__ */ #ifdef sparc #define alloca(n) __builtin_alloca(n) *** 1_7_7.551/hdrs/version.h Mon, 11 Aug 2003 16:14:42 -0500 dunemush (pennmush/c/47_version.h 1.32.1.2.1.7.1.9.1.1.1.17.1.21 660) --- 1_7_7.557(w)/hdrs/version.h Tue, 19 Aug 2003 23:36:09 -0500 dunemush (pennmush/c/47_version.h 1.32.1.2.1.7.1.9.1.1.1.17.1.22 660) *************** *** 1,3 **** ! #define VERSION "PennMUSH version 1.7.7 patchlevel 17 [08/11/2003]" ! #define SHORTVN "PennMUSH 1.7.7p17" ! #define NUMVERSION 001007007017 --- 1,3 ---- ! #define VERSION "PennMUSH version 1.7.7 patchlevel 18 [08/19/2003]" ! #define SHORTVN "PennMUSH 1.7.7p18" ! #define NUMVERSION 001007007018 *** 1_7_7.551/hdrs/game.h Mon, 03 Feb 2003 11:05:37 -0600 dunemush (pennmush/d/12_game.h 1.28.1.2.1.1.1.1.1.1.1.7.1.5 660) --- 1_7_7.557(w)/hdrs/game.h Tue, 19 Aug 2003 23:36:08 -0500 dunemush (pennmush/d/12_game.h 1.28.1.2.1.1.1.1.1.1.1.7.1.6 660) *************** *** 16,22 **** extern void init_func_hashtab(void); /* eval.c */ extern void init_math_hashtab(void); /* funmath.c */ extern void init_aname_table(void); /* atr_tab.c */ ! extern void init_flag_table(void); /* flags.c */ extern void init_tag_hashtab(void); /* funstr.c */ extern void init_pronouns(void); /* funstr.c */ --- 16,23 ---- extern void init_func_hashtab(void); /* eval.c */ extern void init_math_hashtab(void); /* funmath.c */ extern void init_aname_table(void); /* atr_tab.c */ ! extern void init_flagspaces(void); /* flags.c */ ! extern void init_flag_table(const char *ns); /* flags.c */ extern void init_tag_hashtab(void); /* funstr.c */ extern void init_pronouns(void); /* funstr.c */ *** 1_7_7.551/hdrs/flags.h Tue, 11 Mar 2003 12:38:07 -0600 dunemush (pennmush/d/14_flags.h 1.1.1.1.1.1.1.1.1.2.1.3.2.1.1.4.1.1.1.1.2.1.1.24 660) --- 1_7_7.557(w)/hdrs/flags.h Tue, 19 Aug 2003 23:36:08 -0500 dunemush (pennmush/d/14_flags.h 1.1.1.1.1.1.1.1.1.2.1.3.2.1.1.4.1.1.1.1.2.1.1.25 660) *************** *** 6,11 **** --- 6,13 ---- #define __FLAGS_H #include "conf.h" + #include "ptab.h" + typedef struct flag_info FLAG; /** A flag. *************** *** 52,59 **** const char *realname; /**< The real name of the power */ }; /* From flags.c */ - extern FLAG *flag_hash_lookup(const char *name, int type); extern int has_flag_by_name(dbref thing, const char *flag, int type); extern const char *unparse_flags(dbref thing, dbref player); extern const char *flag_description(dbref player, dbref thing); --- 54,75 ---- const char *realname; /**< The real name of the power */ }; + typedef struct flagspace FLAGSPACE; + + /** A flagspace. + * A structure that contains all the information necessary to manage + * a set of flags, powers, or whatever. + */ + struct flagspace { + PTAB *tab; /**< Prefix table storing flags by name/alias */ + FLAG **flags; /**< Variable-length array of pointers to canonical flags, indexed by bit */ + int flagbits; /**< Current length of the flags array */ + FLAG *flag_table; /**< Pointer to flag table */ + FLAG_ALIAS *flag_alias_table; /**< Pointer to flag alias table */ + }; + + /* From flags.c */ extern int has_flag_by_name(dbref thing, const char *flag, int type); extern const char *unparse_flags(dbref thing, dbref player); extern const char *flag_description(dbref player, dbref thing); *************** *** 62,97 **** int hear, int listener); extern const char *power_description(dbref thing); extern int find_power(const char *name); ! extern int flaglist_check(dbref player, dbref it, const char *fstr, int type); ! extern int flaglist_check_long(dbref player, dbref it, const char *fstr, ! int type); extern FLAG *match_flag(const char *name); extern int match_power(const char *name); extern const char *show_command_flags(object_flag_type flags, int powers); ! extern void twiddle_flag_internal(dbref thing, const char *flag, int negate); ! extern object_flag_type new_flag_bitmask(void); ! extern object_flag_type clone_flag_bitmask(object_flag_type given); ! extern void copy_flag_bitmask(object_flag_type dest, object_flag_type given); extern void destroy_flag_bitmask(object_flag_type bitmask); extern void set_flag_bitmask(object_flag_type bitmask, int bit); extern void clear_flag_bitmask(object_flag_type bitmask, int bit); extern int has_bit(object_flag_type bitmask, int bitpos); ! extern int has_all_bits(object_flag_type source, object_flag_type bitmask); ! extern int null_flagmask(object_flag_type source); ! extern int has_any_bits(object_flag_type source, object_flag_type bitmask); ! extern object_flag_type string_to_bits(const char *str); ! extern const char *bits_to_string(object_flag_type bitmask, dbref privs, ! dbref thing); ! extern void flag_write_all(FILE *); ! extern void flag_read_all(FILE *); extern int type_from_old_flags(long old_flags); extern object_flag_type flags_from_old_flags(long old_flags, long old_toggles, int type); extern void add_flag(const char *name, const char letter, int type, int perms, int negate_perms); extern void do_list_flags(dbref player, const char *arg, int lc); ! extern char *list_all_flags(const char *name, dbref privs, int which); ! extern void do_flag_info(dbref player, const char *name); extern void do_flag_delete(dbref player, const char *name); extern void do_flag_disable(dbref player, const char *name); extern void do_flag_alias(dbref player, const char *name, const char *alias); --- 78,120 ---- int hear, int listener); extern const char *power_description(dbref thing); extern int find_power(const char *name); ! extern int flaglist_check(const char *ns, dbref player, dbref it, ! const char *fstr, int type); ! extern int flaglist_check_long(const char *ns, dbref player, dbref it, ! const char *fstr, int type); extern FLAG *match_flag(const char *name); extern int match_power(const char *name); extern const char *show_command_flags(object_flag_type flags, int powers); ! extern void twiddle_flag_internal(const char *ns, dbref thing, const char *flag, ! int negate); ! extern object_flag_type new_flag_bitmask(const char *ns); ! extern object_flag_type clone_flag_bitmask(const char *ns, ! object_flag_type given); ! extern void copy_flag_bitmask(const char *ns, object_flag_type dest, ! object_flag_type given); extern void destroy_flag_bitmask(object_flag_type bitmask); extern void set_flag_bitmask(object_flag_type bitmask, int bit); extern void clear_flag_bitmask(object_flag_type bitmask, int bit); extern int has_bit(object_flag_type bitmask, int bitpos); ! extern int has_all_bits(const char *ns, object_flag_type source, ! object_flag_type bitmask); ! extern int null_flagmask(const char *ns, object_flag_type source); ! extern int has_any_bits(const char *ns, object_flag_type source, ! object_flag_type bitmask); ! extern object_flag_type string_to_bits(const char *ns, const char *str); ! extern const char *bits_to_string(const char *ns, object_flag_type bitmask, ! dbref privs, dbref thing); ! extern void flag_write_all(FILE *, const char *); ! extern void flag_read_all(FILE *, const char *); extern int type_from_old_flags(long old_flags); extern object_flag_type flags_from_old_flags(long old_flags, long old_toggles, int type); extern void add_flag(const char *name, const char letter, int type, int perms, int negate_perms); extern void do_list_flags(dbref player, const char *arg, int lc); ! extern char *list_all_flags(const char *ns, const char *name, dbref privs, ! int which); ! extern void do_flag_info(const char *ns, dbref player, const char *name); extern void do_flag_delete(dbref player, const char *name); extern void do_flag_disable(dbref player, const char *name); extern void do_flag_alias(dbref player, const char *name, const char *alias); *************** *** 103,114 **** #define twiddle_flag_bitmask(bm,b,neg) (neg ? clear_flag_bitmask(bm,b) : \ set_flag_bitmask(bm,b)) ! #define has_all_flags_by_mask(x,bm) has_all_bits(Flags(x),bm) ! #define has_any_flags_by_mask(x,bm) has_any_bits(Flags(x),bm) #define twiddle_flag(thing,f,negate) \ twiddle_flag_bitmask(Flags(thing),f->bitpos,negate) ! #define set_flag_internal(t,f) twiddle_flag_internal(t,f,0) ! #define clear_flag_internal(t,f) twiddle_flag_internal(t,f,1) /*--------------------------------------------------------------------- * Object types (no longer part of the flags) --- 126,137 ---- #define twiddle_flag_bitmask(bm,b,neg) (neg ? clear_flag_bitmask(bm,b) : \ set_flag_bitmask(bm,b)) ! #define has_all_flags_by_mask(x,bm) has_all_bits("FLAG",Flags(x),bm) ! #define has_any_flags_by_mask(x,bm) has_any_bits("FLAG",Flags(x),bm) #define twiddle_flag(thing,f,negate) \ twiddle_flag_bitmask(Flags(thing),f->bitpos,negate) ! #define set_flag_internal(t,f) twiddle_flag_internal("FLAG",t,f,0) ! #define clear_flag_internal(t,f) twiddle_flag_internal("FLAG",t,f,1) /*--------------------------------------------------------------------- * Object types (no longer part of the flags) *** 1_7_7.551/hdrs/externs.h Thu, 17 Jul 2003 16:30:15 -0500 dunemush (pennmush/d/16_externs.h 1.1.1.53.1.2.1.8.2.1.1.2.1.1.1.1.1.2.1.6.1.3.1.4.3.1.1.1.1.12 660) --- 1_7_7.557(w)/hdrs/externs.h Tue, 19 Aug 2003 23:36:08 -0500 dunemush (pennmush/d/16_externs.h 1.1.1.53.1.2.1.8.2.1.1.2.1.1.1.1.1.2.1.6.1.3.1.4.3.1.1.1.1.13 660) *************** *** 181,186 **** --- 181,189 ---- extern dbref orator; int parse_chat(dbref player, char *command); extern void fork_and_dump(int forking); + void reserve_fd(void); + void release_fd(void); + /* From look.c */ /** Enumeration of types of looks that can be performed */ *** 1_7_7.551/win32/funs.h Mon, 18 Aug 2003 12:06:39 -0500 dunemush (pennmush/f/12_funs.h 1.11.1.9.2.8.2.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.8.1.3.1.7.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.9 660) --- 1_7_7.557(w)/win32/funs.h Tue, 19 Aug 2003 17:50:07 -0500 dunemush (pennmush/f/12_funs.h 1.11.1.9.2.8.2.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.8.1.3.1.7.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.10 660) *************** *** 322,324 **** --- 322,325 ---- FUNCTION_PROTO(fun_zemit); FUNCTION_PROTO(fun_zfun); FUNCTION_PROTO(fun_zone); + FUNCTION_PROTO(local_fun_silly); *** 1_7_7.551/win32/cmds.h Tue, 12 Aug 2003 11:05:22 -0500 dunemush (pennmush/f/15_cmds.h 1.9.1.4.1.1.1.1.1.1.1.1.2.1.1.1.2.1.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.9.1.7.2.4.1.2.3.1.1.1.1.1.1.6 660) --- 1_7_7.557(w)/win32/cmds.h Tue, 19 Aug 2003 17:50:03 -0500 dunemush (pennmush/f/15_cmds.h 1.9.1.4.1.1.1.1.1.1.1.1.2.1.1.1.2.1.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.9.1.7.2.4.1.2.3.1.1.1.1.1.1.7 660) *************** *** 62,67 **** --- 62,68 ---- COMMAND_PROTO(cmd_link); COMMAND_PROTO(cmd_list); COMMAND_PROTO(cmd_listmotd); + COMMAND_PROTO(cmd_local_silly); COMMAND_PROTO(cmd_lock); COMMAND_PROTO(cmd_log); COMMAND_PROTO(cmd_logwipe); *** 1_7_7.551/game/txt/hlp/pennvOLD.hlp Wed, 02 Jul 2003 14:19:13 -0500 dunemush (pennmush/g/30_pennvOLD.h 1.1.1.1.1.1.1.1.1.1.1.2 660) --- 1_7_7.557(w)/game/txt/hlp/pennvOLD.hlp Tue, 19 Aug 2003 23:36:10 -0500 dunemush (pennmush/g/30_pennvOLD.h 1.1.1.1.1.1.1.1.1.1.1.3 660) *************** *** 4417,4423 **** For information on a specific patchlevel of one of the versions listed, type 'help p'. For example, 'help 1.7.2p3' ! 1.7.7: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 1.7.6: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 1.7.5: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 1.7.4: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, --- 4417,4423 ---- For information on a specific patchlevel of one of the versions listed, type 'help p'. For example, 'help 1.7.2p3' ! 1.7.7: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 1.7.6: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 1.7.5: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 1.7.4: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, *** 1_7_7.551/game/txt/hlp/pennv177.hlp Sun, 17 Aug 2003 08:30:54 -0500 dunemush (pennmush/g/34_pennv177.h 1.97 660) --- 1_7_7.557(w)/game/txt/hlp/pennv177.hlp Tue, 19 Aug 2003 23:36:09 -0500 dunemush (pennmush/g/34_pennv177.h 1.102 660) *************** *** 1,4 **** ! & 1.7.7p17 & changes This is a list of changes in this patchlevel which are probably of interest to players. More information about new commands and functions --- 1,4 ---- ! & 1.7.7p18 & changes This is a list of changes in this patchlevel which are probably of interest to players. More information about new commands and functions *************** *** 11,16 **** --- 11,34 ---- A list of the patchlevels associated with each release can be read in 'help patchlevels'. + Version 1.7.7 patchlevel 18 August 19, 2003 + + Major Changes: + * The flag handling code has been additionally abstracted to + allow, in a future patchlevel, @powers to be handled in the + same way that flags are now. + Minor Changes: + * Wrap the OS-dependant code for making sure the mush always has a free + file descriptor available for use in a pair of functions. [SW] + Fixes: + * Linted some ssl-related warnings. Reported by Cheetah@M*U*S*H. + * Compile failed in timer.c unless USE_MAILER was defined. + Reported by Sunny@M*U*S*H. + * Bug allowing players to view internal and mortal_dark attributes + introduced in p17 has been fixed. [TAP] + + + & 1.7.7p17 Version 1.7.7 patchlevel 17 August 11, 2003 Major changes: *** 1_7_7.551/src/myssl.c Sun, 10 Aug 2003 14:55:57 -0500 dunemush (pennmush/g/40_myssl.c 1.15 660) --- 1_7_7.557(w)/src/myssl.c Tue, 19 Aug 2003 23:36:03 -0500 dunemush (pennmush/g/40_myssl.c 1.17 660) *************** *** 1,4 **** ! /* Code to support SSL connections */ #include "copyrite.h" #include "config.h" --- 1,14 ---- ! /** ! * \file myssl.c ! * ! * \brief Code to support SSL connections in PennMUSH. ! * ! * This file contains nearly all of the code that interacts with the ! * OpenSSL libraries to suppose SSL connections in PennMUSH. ! * ! * Lots of stuff here taken from Eric Rescorla's 2001 Linux Journal ! * articles "An Introduction to OpenSSL Programming" ! */ #include "copyrite.h" #include "config.h" *************** *** 90,109 **** static int client_verify_callback(int preverify_ok, X509_STORE_CTX * x509_ctx); static DH *get_dh1024(void); - /* Right now, we expect to call this from the loop in bsd.c, but - * ideally, this API will also allow us to write a separate - * SSL thread and call these functions there instead. - * - * Functions: - * ssl_init() - initialize the ssl stuff - * - * Lots of stuff here taken from Eric Rescorla's 2001 Linux Journal - * articles "An Introduction to OpenSSL Programming" - */ static BIO *bio_err = NULL; static SSL_CTX *ctx = NULL; SSL_CTX * ssl_init(void) { --- 100,112 ---- static int client_verify_callback(int preverify_ok, X509_STORE_CTX * x509_ctx); static DH *get_dh1024(void); static BIO *bio_err = NULL; static SSL_CTX *ctx = NULL; + /** Initialize the SSL context. + * \return pointer to SSL context object. + */ SSL_CTX * ssl_init(void) { *************** *** 239,244 **** --- 242,249 ---- /** Associate an SSL object with a socket and return it. + * \param sock socket descriptor to associate with an SSL object. + * \return pointer to SSL object. */ SSL * ssl_setup_socket(int sock) *************** *** 253,258 **** --- 258,270 ---- return ssl; } + /** Close down an SSL connection and free the object. + * \param ssl pointer to SSL object to close down. + * Technically, this function sends a shutdown notification + * and then frees the object without waiting for acknowledgement + * of the shutdown. If there were a good way to do that, it would + * be better. + */ void ssl_close_connection(SSL * ssl) { *************** *** 293,298 **** --- 305,317 ---- } + /** Perform an SSL handshake. + * In some cases, a handshake may block, so we may have to call this + * function again. Accordingly, we return state information that + * tells us if we need to do that. + * \param ssl pointer to an SSL object. + * \return resulting state of the object. + */ int ssl_handshake(SSL * ssl) { *************** *** 305,323 **** /* We must want for the socket to be readable, and then repeat * the call. */ ! ssl_debugdump("SSL_resume wants read"); state = MYSSL_RB | MYSSL_HANDSHAKE; break; case SSL_ERROR_WANT_WRITE: /* We must want for the socket to be writable, and then repeat * the call. */ ! ssl_debugdump("SSL_resume wants write"); state = MYSSL_WB | MYSSL_HANDSHAKE; break; default: /* Oops, don't know what's wrong */ ! ssl_errordump("Error resuming connection"); state = -1; } } else { --- 324,342 ---- /* We must want for the socket to be readable, and then repeat * the call. */ ! ssl_debugdump("SSL_do_handshake wants read"); state = MYSSL_RB | MYSSL_HANDSHAKE; break; case SSL_ERROR_WANT_WRITE: /* We must want for the socket to be writable, and then repeat * the call. */ ! ssl_debugdump("SSL_do_handshake wants write"); state = MYSSL_WB | MYSSL_HANDSHAKE; break; default: /* Oops, don't know what's wrong */ ! ssl_errordump("Error in ssl_handshake"); state = -1; } } else {