mux/src/set.cpp

Go to the documentation of this file.
00001 // set.cpp -- Commands which set parameters.
00002 //
00003 // $Id: set.cpp,v 1.30 2006/01/07 08:23:38 sdennis Exp $
00004 //
00005 #include "copyright.h"
00006 #include "autoconf.h"
00007 #include "config.h"
00008 #include "externs.h"
00009 
00010 #include "ansi.h"
00011 #include "attrs.h"
00012 #include "command.h"
00013 #include "powers.h"
00014 
00015 void set_modified(dbref thing)
00016 {
00017     CLinearTimeAbsolute ltaNow;
00018     ltaNow.GetLocal();
00019     atr_add_raw(thing, A_MODIFIED, ltaNow.ReturnDateString(7));
00020 }
00021 
00022 dbref match_controlled_handler(dbref executor, const char *name, bool bQuiet)
00023 {
00024     dbref mat;
00025     init_match(executor, name, NOTYPE);
00026     match_everything(MAT_EXIT_PARENTS);
00027     if (bQuiet)
00028     {
00029         mat = match_result();
00030     }
00031     else
00032     {
00033         mat = noisy_match_result();
00034     }
00035     if (!Good_obj(mat))
00036     {
00037         return mat;
00038     }
00039 
00040     if (Controls(executor, mat))
00041     {
00042         return mat;
00043     }
00044     if (!bQuiet)
00045     {
00046         notify_quiet(executor, NOPERM_MESSAGE);
00047     }
00048     return NOTHING;
00049 }
00050 
00051 void do_chzone
00052 (
00053     dbref executor,
00054     dbref caller,
00055     dbref enactor,
00056     int   key,
00057     int   nargs,
00058     char *name,
00059     char *newobj
00060 )
00061 {
00062     UNUSED_PARAMETER(caller);
00063     UNUSED_PARAMETER(enactor);
00064     UNUSED_PARAMETER(key);
00065     UNUSED_PARAMETER(nargs);
00066 
00067     if (!mudconf.have_zones)
00068     {
00069         notify(executor, "Zones disabled.");
00070         return;
00071     }
00072     init_match(executor, name, NOTYPE);
00073     match_everything(0);
00074     dbref thing = noisy_match_result();
00075     if (thing == NOTHING)
00076     {
00077         return;
00078     }
00079 
00080     dbref zone;
00081     if (  newobj[0] == '\0'
00082        || !mux_stricmp(newobj, "none"))
00083     {
00084         zone = NOTHING;
00085     }
00086     else
00087     {
00088         init_match(executor, newobj, NOTYPE);
00089         match_everything(0);
00090         zone = noisy_match_result();
00091         if (zone == NOTHING)
00092         {
00093             return;
00094         }
00095         if (  !isThing(zone)
00096            && !isRoom(zone))
00097         {
00098             notify(executor, "Invalid zone object type.");
00099             return;
00100         }
00101     }
00102 
00103     if (  !Wizard(executor)
00104        && !Controls(executor, thing)
00105        && !check_zone_handler(executor, thing, true)
00106        && db[executor].owner != db[thing].owner)
00107     {
00108         notify(executor, "You don't have the power to shift reality.");
00109         return;
00110     }
00111 
00112     // A player may change an object's zone to NOTHING or to an object he owns.
00113     //
00114     if (  zone != NOTHING
00115        && !Wizard(executor)
00116        && !Controls(executor, zone)
00117        && db[executor].owner != db[zone].owner)
00118     {
00119         notify(executor, "You cannot move that object to that zone.");
00120         return;
00121     }
00122 
00123     // Only rooms may be zoned to other rooms.
00124     //
00125     if (  zone != NOTHING
00126        && isRoom(zone)
00127        && !isRoom(thing))
00128     {
00129         notify(executor, "Only rooms may have parent rooms.");
00130         return;
00131     }
00132 
00133     // Everything is okay, do the change.
00134     //
00135     db[thing].zone = zone;
00136     if (!isPlayer(thing))
00137     {
00138         // If the object is a player, resetting these flags is rather
00139         // inconvenient -- although this may pose a bit of a security risk. Be
00140         // careful when @chzone'ing wizard or royal players.
00141         //
00142         Flags(thing) &= ~(WIZARD | ROYALTY | INHERIT);
00143 
00144         // Wipe out all powers.
00145         //
00146         Powers(thing) = 0;
00147     }
00148     notify(executor, "Zone changed.");
00149 }
00150 
00151 void do_name
00152 (
00153     dbref executor,
00154     dbref caller,
00155     dbref enactor,
00156     int   key,
00157     int   nargs,
00158     char *name,
00159     char *newname
00160 )
00161 {
00162     UNUSED_PARAMETER(caller);
00163     UNUSED_PARAMETER(enactor);
00164     UNUSED_PARAMETER(key);
00165 
00166     dbref thing = match_controlled(executor, name);
00167     if (thing == NOTHING)
00168     {
00169         return;
00170     }
00171 
00172     // Check for bad name.
00173     //
00174     if (  nargs < 2
00175        || newname[0] == '\0')
00176     {
00177         notify_quiet(executor, "Give it what new name?");
00178         return;
00179     }
00180 
00181     // Check for renaming a player.
00182     //
00183     if (isPlayer(thing))
00184     {
00185         char *buff = trim_spaces(newname);
00186         if (  !ValidatePlayerName(buff)
00187            || !badname_check(buff))
00188         {
00189             notify_quiet(executor, "You can't use that name.");
00190             free_lbuf(buff);
00191             return;
00192         }
00193         else if (  string_compare(buff, Name(thing))
00194                 && lookup_player(NOTHING, buff, false) != NOTHING)
00195         {
00196             // string_compare allows changing foo to Foo, etc.
00197             //
00198             notify_quiet(executor, "That name is already in use.");
00199             free_lbuf(buff);
00200             return;
00201         }
00202 
00203         // Everything ok, notify.
00204         //
00205         STARTLOG(LOG_SECURITY, "SEC", "CNAME");
00206         log_name(thing),
00207         log_text(" renamed to ");
00208         log_text(buff);
00209         ENDLOG;
00210         if (Suspect(thing))
00211         {
00212             raw_broadcast(WIZARD, "[Suspect] %s renamed to %s", Name(thing), buff);
00213         }
00214         delete_player_name(thing, Name(thing));
00215         s_Name(thing, buff);
00216         set_modified(thing);
00217         add_player_name(thing, Name(thing));
00218         if (!Quiet(executor) && !Quiet(thing))
00219         {
00220             notify_quiet(executor, "Name set.");
00221         }
00222         free_lbuf(buff);
00223         return;
00224     }
00225     else
00226     {
00227         int nValidName;
00228         bool bValid;
00229         char *pValidName;
00230 
00231         if (isExit(thing))
00232         {
00233             pValidName = MakeCanonicalExitName(newname, &nValidName, &bValid);
00234         }
00235         else
00236         {
00237             pValidName = MakeCanonicalObjectName(newname, &nValidName, &bValid);
00238         }
00239 
00240         if (!bValid)
00241         {
00242             notify_quiet(executor, "That is not a reasonable name.");
00243             return;
00244         }
00245 
00246         // Everything ok, change the name.
00247         //
00248         s_Name(thing, pValidName);
00249         set_modified(thing);
00250         if (!Quiet(executor) && !Quiet(thing))
00251         {
00252             notify_quiet(executor, "Name set.");
00253         }
00254     }
00255 }
00256 
00257 /*
00258  * ---------------------------------------------------------------------------
00259  * * do_alias: Make an alias for a player or object.
00260  */
00261 
00262 void do_alias
00263 (
00264     dbref executor,
00265     dbref caller,
00266     dbref enactor,
00267     int   key,
00268     int   nargs,
00269     char *name,
00270     char *alias
00271 )
00272 {
00273     UNUSED_PARAMETER(caller);
00274     UNUSED_PARAMETER(enactor);
00275     UNUSED_PARAMETER(key);
00276     UNUSED_PARAMETER(nargs);
00277 
00278     dbref thing = match_controlled(executor, name);
00279     if (thing == NOTHING)
00280     {
00281         return;
00282     }
00283 
00284     // Check for renaming a player.
00285     //
00286     dbref aowner;
00287     int aflags;
00288     ATTR *ap = atr_num(A_ALIAS);
00289     if (isPlayer(thing))
00290     {
00291         // Fetch the old alias.
00292         //
00293         char *oldalias = atr_pget(thing, A_ALIAS, &aowner, &aflags);
00294         char *trimalias = trim_spaces(alias);
00295 
00296         if (!Controls(executor, thing))
00297         {
00298             // Make sure we have rights to do it. We can't do the
00299             // normal Set_attr check because ALIAS is only
00300             // writable by GOD and we want to keep people from
00301             // doing &ALIAS and bypassing the player name checks.
00302             //
00303             notify_quiet(executor, NOPERM_MESSAGE);
00304         }
00305         else if (!*trimalias)
00306         {
00307             // New alias is null, just clear it.
00308             //
00309             delete_player_name(thing, oldalias);
00310             atr_clr(thing, A_ALIAS);
00311             if (!Quiet(executor))
00312             {
00313                 notify_quiet(executor, "Alias removed.");
00314             }
00315         }
00316         else if (lookup_player(NOTHING, trimalias, false) != NOTHING)
00317         {
00318             // Make sure new alias isn't already in use.
00319             //
00320             notify_quiet(executor, "That name is already in use.");
00321         }
00322         else if (  !(badname_check(trimalias)
00323                 && ValidatePlayerName(trimalias)))
00324         {
00325             notify_quiet(executor, "That's a silly name for a player!");
00326         }
00327         else
00328         {
00329             // Remove the old name and add the new name.
00330             //
00331             delete_player_name(thing, oldalias);
00332             atr_add(thing, A_ALIAS, trimalias, Owner(executor), aflags);
00333             if (add_player_name(thing, trimalias))
00334             {
00335                 if (!Quiet(executor))
00336                 {
00337                     notify_quiet(executor, "Alias set.");
00338                 }
00339             }
00340             else
00341             {
00342                 notify_quiet(executor,
00343                     "That name is already in use or is illegal, alias cleared.");
00344                 atr_clr(thing, A_ALIAS);
00345             }
00346         }
00347         free_lbuf(trimalias);
00348         free_lbuf(oldalias);
00349     }
00350     else
00351     {
00352         atr_pget_info(thing, A_ALIAS, &aowner, &aflags);
00353 
00354         // Make sure we have rights to do it.
00355         //
00356         if (!bCanSetAttr(executor, thing, ap))
00357         {
00358             notify_quiet(executor, NOPERM_MESSAGE);
00359         }
00360         else
00361         {
00362             atr_add(thing, A_ALIAS, alias, Owner(executor), aflags);
00363             if (!Quiet(executor))
00364             {
00365                 notify_quiet(executor, "Set.");
00366             }
00367         }
00368     }
00369 }
00370 
00371 // ---------------------------------------------------------------------------
00372 // do_forwardlist: Set a forwardlist.
00373 // ---------------------------------------------------------------------------
00374 void do_forwardlist
00375 (
00376     dbref executor,
00377     dbref caller,
00378     dbref enactor,
00379     int   key,
00380     int   nargs,
00381     char *target,
00382     char *newlist
00383 )
00384 {
00385     UNUSED_PARAMETER(caller);
00386     UNUSED_PARAMETER(enactor);
00387     UNUSED_PARAMETER(key);
00388     UNUSED_PARAMETER(nargs);
00389 
00390     dbref thing = match_controlled(executor, target);
00391     if (thing == NOTHING)
00392     {
00393         return;
00394     }
00395     dbref aowner, aflags;
00396     atr_pget_info(thing, A_FORWARDLIST, &aowner, &aflags);
00397 
00398     if (!Controls(executor, thing))
00399     {
00400         notify_quiet(executor, NOPERM_MESSAGE);
00401         return;
00402     }
00403     else if (!*newlist)
00404     {
00405         // New forwardlist is null, just clear it.
00406         //
00407         atr_clr(thing, A_FORWARDLIST);
00408         set_modified(thing);
00409         if (!Quiet(executor))
00410         {
00411             notify_quiet(executor, "Forwardlist removed.");
00412         }
00413     }
00414     else if (!fwdlist_ck(executor, thing, A_FORWARDLIST, newlist))
00415     {
00416         notify_quiet(executor, "Invalid forwardlist.");
00417         return;
00418     }
00419     else
00420     {
00421         atr_add(thing, A_FORWARDLIST, newlist, Owner(executor), aflags);
00422         if (!Quiet(executor))
00423         {
00424             notify_quiet(executor, "Set.");
00425         }
00426     }
00427 }
00428 
00429 /*
00430  * ---------------------------------------------------------------------------
00431  * * do_lock: Set a lock on an object or attribute.
00432  */
00433 
00434 void do_lock
00435 (
00436     dbref executor,
00437     dbref caller,
00438     dbref enactor,
00439     int   key,
00440     int   nargs,
00441     char *name,
00442     char *keytext
00443 )
00444 {
00445     UNUSED_PARAMETER(caller);
00446     UNUSED_PARAMETER(enactor);
00447     UNUSED_PARAMETER(nargs);
00448 
00449     dbref thing;
00450     ATTR *ap;
00451 
00452     if (  parse_attrib(executor, name, &thing, &ap)
00453        && ap)
00454     {
00455         dbref aowner;
00456         int aflags;
00457         if (!atr_get_info(thing, ap->number, &aowner, &aflags))
00458         {
00459             notify_quiet(executor, "Attribute not present on object.");
00460             return;
00461         }
00462 
00463         if (bCanLockAttr(executor, thing, ap))
00464         {
00465             aflags |= AF_LOCK;
00466             atr_set_flags(thing, ap->number, aflags);
00467             if (  !Quiet(executor)
00468                && !Quiet(thing))
00469             {
00470                 notify_quiet(executor, "Attribute locked.");
00471             }
00472         }
00473         else
00474         {
00475             notify_quiet(executor, NOPERM_MESSAGE);
00476         }
00477         return;
00478     }
00479     init_match(executor, name, NOTYPE);
00480     match_everything(MAT_EXIT_PARENTS);
00481     thing = match_result();
00482 
00483     switch (thing)
00484     {
00485     case NOTHING:
00486         notify_quiet(executor, "I don't see what you want to lock!");
00487         return;
00488 
00489     case AMBIGUOUS:
00490         notify_quiet(executor, "I don't know which one you want to lock!");
00491         return;
00492 
00493     default:
00494         if (!Controls(executor, thing))
00495         {
00496             notify_quiet(executor, "You can't lock that!");
00497             return;
00498         }
00499     }
00500 
00501     char *pRestrictedKeyText = RemoveSetOfCharacters(keytext, "\r\n\t");
00502     struct boolexp *okey = parse_boolexp(executor, pRestrictedKeyText, false);
00503     if (okey == TRUE_BOOLEXP)
00504     {
00505         notify_quiet(executor, "I don't understand that key.");
00506     }
00507     else
00508     {
00509         // Everything ok, do it.
00510         //
00511         if (!key)
00512         {
00513             key = A_LOCK;
00514         }
00515         atr_add_raw(thing, key, unparse_boolexp_quiet(executor, okey));
00516         if (  !Quiet(executor)
00517            && !Quiet(thing))
00518         {
00519             notify_quiet(executor, "Locked.");
00520         }
00521     }
00522     free_boolexp(okey);
00523 }
00524 
00525 /*
00526  * ---------------------------------------------------------------------------
00527  * * Remove a lock from an object of attribute.
00528  */
00529 
00530 void do_unlock(dbref executor, dbref caller, dbref enactor, int key, char *name)
00531 {
00532     UNUSED_PARAMETER(caller);
00533     UNUSED_PARAMETER(enactor);
00534 
00535     dbref thing;
00536     ATTR *ap;
00537 
00538     if (  parse_attrib(executor, name, &thing, &ap)
00539        && ap)
00540     {
00541         // We have been asked to unlock an attribute.
00542         //
00543         dbref aowner;
00544         int aflags;
00545         if (!atr_get_info(thing, ap->number, &aowner, &aflags))
00546         {
00547             notify_quiet(executor, "Attribute not present on object.");
00548             return;
00549         }
00550 
00551         if (bCanLockAttr(executor, thing, ap))
00552         {
00553             aflags &= ~AF_LOCK;
00554             atr_set_flags(thing, ap->number, aflags);
00555             if (  !Quiet(executor)
00556                && !Quiet(thing))
00557             {
00558                 notify_quiet(executor, "Attribute unlocked.");
00559             }
00560         }
00561         else
00562         {
00563             notify_quiet(executor, NOPERM_MESSAGE);
00564         }
00565         return;
00566     }
00567 
00568     // We have been asked to change the ownership of an object.
00569     //
00570     if (!key)
00571     {
00572         key = A_LOCK;
00573     }
00574     thing = match_controlled(executor, name);
00575     if (thing != NOTHING)
00576     {
00577         atr_clr(thing, key);
00578         set_modified(thing);
00579         if (!Quiet(executor) && !Quiet(thing))
00580         {
00581             notify_quiet(executor, "Unlocked.");
00582         }
00583     }
00584 }
00585 
00586 /*
00587  * ---------------------------------------------------------------------------
00588  * * do_unlink: Unlink an exit from its destination or remove a dropto.
00589  */
00590 
00591 void do_unlink(dbref executor, dbref caller, dbref enactor, int key, char *name)
00592 {
00593     UNUSED_PARAMETER(caller);
00594     UNUSED_PARAMETER(enactor);
00595     UNUSED_PARAMETER(key);
00596 
00597     dbref exit;
00598 
00599     init_match(executor, name, TYPE_EXIT);
00600     match_everything(0);
00601     exit = match_result();
00602 
00603     switch (exit)
00604     {
00605     case NOTHING:
00606 
00607         notify_quiet(executor, "Unlink what?");
00608         break;
00609 
00610     case AMBIGUOUS:
00611 
00612         notify_quiet(executor, "I don't know which one you mean!");
00613         break;
00614 
00615     default:
00616 
00617         if (!Controls(executor, exit))
00618         {
00619             notify_quiet(executor, NOPERM_MESSAGE);
00620         }
00621         else
00622         {
00623             switch (Typeof(exit))
00624             {
00625             case TYPE_EXIT:
00626 
00627                 s_Location(exit, NOTHING);
00628                 if (!Quiet(executor))
00629                 {
00630                     notify_quiet(executor, "Unlinked.");
00631                 }
00632                 giveto(Owner(exit), mudconf.linkcost);
00633                 break;
00634 
00635             case TYPE_ROOM:
00636 
00637                 s_Dropto(exit, NOTHING);
00638                 if (!Quiet(executor))
00639                 {
00640                     notify_quiet(executor, "Dropto removed.");
00641                 }
00642                 break;
00643 
00644             default:
00645 
00646                 notify_quiet(executor, "You can't unlink that!");
00647                 break;
00648             }
00649         }
00650     }
00651 }
00652 
00653 /*
00654  * ---------------------------------------------------------------------------
00655  * * do_chown: Change ownership of an object or attribute.
00656  */
00657 
00658 void do_chown
00659 (
00660     dbref executor,
00661     dbref caller,
00662     dbref enactor,
00663     int   key,
00664     int   nargs,
00665     char *name,
00666     char *newown
00667 )
00668 {
00669     UNUSED_PARAMETER(caller);
00670     UNUSED_PARAMETER(enactor);
00671     UNUSED_PARAMETER(key);
00672     UNUSED_PARAMETER(nargs);
00673 
00674     dbref nOwnerOrig, nOwnerNew, thing;
00675     bool bDoit;
00676     ATTR *ap;
00677 
00678     if (  parse_attrib(executor, name, &thing, &ap)
00679        && ap
00680        && See_attr(executor, thing, ap))
00681     {
00682         // An attribute was given, so we worry about changing the owner of the
00683         // attribute.
00684         //
00685         nOwnerOrig = Owner(thing);
00686         if (!*newown)
00687         {
00688             nOwnerNew = nOwnerOrig;
00689         }
00690         else if (!string_compare(newown, "me"))
00691         {
00692             nOwnerNew = Owner(executor);
00693         }
00694         else
00695         {
00696             nOwnerNew = lookup_player(executor, newown, true);
00697         }
00698 
00699         // You may chown an attr to yourself if you own the object and the attr
00700         // is not locked. You may chown an attr to the owner of the object if
00701         // you own the attribute. To do anything else you must be a wizard.
00702         // Only #1 can chown attributes on #1.
00703         //
00704         dbref aowner;
00705         int   aflags;
00706         if (!atr_get_info(thing, ap->number, &aowner, &aflags))
00707         {
00708             notify_quiet(executor, "Attribute not present on object.");
00709             return;
00710         }
00711         bDoit = false;
00712         if (nOwnerNew == NOTHING)
00713         {
00714             notify_quiet(executor, "I couldn't find that player.");
00715         }
00716         else if (  God(thing)
00717                 && !God(executor))
00718         {
00719             notify_quiet(executor, NOPERM_MESSAGE);
00720         }
00721         else if (Wizard(executor))
00722         {
00723             bDoit = true;
00724         }
00725         else if (nOwnerNew == Owner(executor))
00726         {
00727             // Chown to me: only if I own the obj and !locked
00728             //
00729             if (  !Controls(executor, thing)
00730                || (aflags & AF_LOCK))
00731             {
00732                 notify_quiet(executor, NOPERM_MESSAGE);
00733             }
00734             else
00735             {
00736                 bDoit = true;
00737             }
00738         }
00739         else if (nOwnerNew == nOwnerOrig)
00740         {
00741             // chown to obj owner: only if I own attr and !locked
00742             //
00743             if (  Owner(executor) != aowner
00744                || (aflags & AF_LOCK))
00745             {
00746                 notify_quiet(executor, NOPERM_MESSAGE);
00747             }
00748             else
00749             {
00750                 bDoit = true;
00751             }
00752         }
00753         else
00754         {
00755             notify_quiet(executor, NOPERM_MESSAGE);
00756         }
00757 
00758         if (!bDoit)
00759         {
00760             return;
00761         }
00762 
00763         if (!bCanSetAttr(executor, executor, ap))
00764         {
00765             notify_quiet(executor, NOPERM_MESSAGE);
00766             return;
00767         }
00768         char *buff = atr_get(thing, ap->number, &aowner, &aflags);
00769         atr_add(thing, ap->number, buff, nOwnerNew, aflags);
00770         free_lbuf(buff);
00771         if (!Quiet(executor))
00772         {
00773             notify_quiet(executor, "Attribute owner changed.");
00774         }
00775         return;
00776     }
00777 
00778     // An attribute was not specified, so we are being asked to change the
00779     // owner of the object.
00780     //
00781     init_match(executor, name, TYPE_THING);
00782     match_possession();
00783     match_here();
00784     match_exit();
00785     match_me();
00786     if (Chown_Any(executor))
00787     {
00788         match_player();
00789         match_absolute();
00790     }
00791     switch (thing = match_result())
00792     {
00793     case NOTHING:
00794 
00795         notify_quiet(executor, "You don't have that!");
00796         return;
00797 
00798     case AMBIGUOUS:
00799 
00800         notify_quiet(executor, "I don't know which you mean!");
00801         return;
00802     }
00803     nOwnerOrig = Owner(thing);
00804 
00805     if (!*newown || !(string_compare(newown, "me")))
00806     {
00807         nOwnerNew = Owner(executor);
00808     }
00809     else
00810     {
00811         nOwnerNew = lookup_player(executor, newown, true);
00812     }
00813 
00814     int cost = 1, quota = 1;
00815 
00816     switch (Typeof(thing))
00817     {
00818     case TYPE_ROOM:
00819 
00820         cost = mudconf.digcost;
00821         quota = mudconf.room_quota;
00822         break;
00823 
00824     case TYPE_THING:
00825 
00826         cost = OBJECT_DEPOSIT(Pennies(thing));
00827         quota = mudconf.thing_quota;
00828         break;
00829 
00830     case TYPE_EXIT:
00831 
00832         cost = mudconf.opencost;
00833         quota = mudconf.exit_quota;
00834         break;
00835 
00836     case TYPE_PLAYER:
00837 
00838         cost = mudconf.robotcost;
00839         quota = mudconf.player_quota;
00840         break;
00841     }
00842 
00843     bool bPlayerControlsThing = Controls(executor, thing);
00844     if (  isGarbage(thing)
00845        && bPlayerControlsThing)
00846     {
00847         notify_quiet(executor, "You shouldn't be rummaging through the garbage.");
00848     }
00849     else if (nOwnerNew == NOTHING)
00850     {
00851         notify_quiet(executor, "I couldn't find that player.");
00852     }
00853     else if (  isPlayer(thing)
00854             && !God(executor))
00855     {
00856         notify_quiet(executor, "Players always own themselves.");
00857     }
00858     else if (  (  !bPlayerControlsThing
00859                && !Chown_Any(executor)
00860                && !Chown_ok(thing))
00861             || (  isThing(thing)
00862                && Location(thing) != executor
00863                && !Chown_Any(executor))
00864             || !Controls(executor, nOwnerNew)
00865             || God(thing))
00866     {
00867         notify_quiet(executor, NOPERM_MESSAGE);
00868     }
00869     else if (canpayfees(executor, nOwnerNew, cost, quota))
00870     {
00871         giveto(nOwnerOrig, cost);
00872         if (mudconf.quotas)
00873         {
00874             add_quota(nOwnerOrig, quota);
00875         }
00876         if (!God(executor))
00877         {
00878             nOwnerNew = Owner(nOwnerNew);
00879         }
00880         s_Owner(thing, nOwnerNew);
00881         atr_chown(thing);
00882         db[thing].fs.word[FLAG_WORD1] &= ~(CHOWN_OK | INHERIT);
00883         db[thing].fs.word[FLAG_WORD1] |= HALT;
00884         s_Powers(thing, 0);
00885         s_Powers2(thing, 0);
00886         halt_que(NOTHING, thing);
00887         if (!Quiet(executor))
00888         {
00889             char *buff = alloc_lbuf("do_chown.notify");
00890             char *bp = buff;
00891 
00892             char *p;
00893             p = tprintf("Owner of %s(#%d) changed from ", Name(thing), thing);
00894             safe_str(p, buff, &bp);
00895             p = tprintf("%s(#%d) to ", Name(nOwnerOrig), nOwnerOrig);
00896             safe_str(p, buff, &bp);
00897             p = tprintf("%s(#%d).", Name(nOwnerNew), nOwnerNew);
00898             safe_str(p, buff, &bp);
00899             *bp = '\0';
00900             notify_quiet(executor, buff);
00901             free_lbuf(buff);
00902         }
00903     }
00904 }
00905 
00906 /*
00907  * ---------------------------------------------------------------------------
00908  * * do_set: Set flags or attributes on objects, or flags on attributes.
00909  */
00910 
00911 static void set_attr_internal(dbref player, dbref thing, int attrnum, char *attrtext, int key)
00912 {
00913     dbref aowner;
00914     int aflags;
00915     ATTR *pattr = atr_num(attrnum);
00916     atr_pget_info(thing, attrnum, &aowner, &aflags);
00917     if (  pattr
00918        && bCanSetAttr(player, thing, pattr))
00919     {
00920         bool could_hear = Hearer(thing);
00921         atr_add(thing, attrnum, attrtext, Owner(player), aflags);
00922         handle_ears(thing, could_hear, Hearer(thing));
00923         if (  !(key & SET_QUIET)
00924            && !Quiet(player)
00925            && !Quiet(thing))
00926         {
00927             notify_quiet(player, "Set.");
00928         }
00929     }
00930     else
00931     {
00932         notify_quiet(player, NOPERM_MESSAGE);
00933     }
00934 }
00935 
00936 void do_set
00937 (
00938     dbref executor,
00939     dbref caller,
00940     dbref enactor,
00941     int   key,
00942     int   nargs,
00943     char *name,
00944     char *flagname
00945 )
00946 {
00947     UNUSED_PARAMETER(caller);
00948     UNUSED_PARAMETER(enactor);
00949     UNUSED_PARAMETER(nargs);
00950 
00951     dbref thing, aowner;
00952     int aflags;
00953     ATTR *pattr;
00954 
00955     // See if we have the <obj>/<attr> form, which is how you set
00956     // attribute flags.
00957     //
00958     if (parse_attrib(executor, name, &thing, &pattr))
00959     {
00960         if (  pattr
00961            && See_attr(executor, thing, pattr))
00962         {
00963             // You must specify a flag name.
00964             //
00965             if (  !flagname
00966                || flagname[0] == '\0')
00967             {
00968                 notify_quiet(executor, "I don't know what you want to set!");
00969                 return;
00970             }
00971 
00972             // Check for clearing.
00973             //
00974             bool clear = false;
00975             if (flagname[0] == NOT_TOKEN)
00976             {
00977                 flagname++;
00978                 clear = true;
00979             }
00980 
00981             // Make sure player specified a valid attribute flag.
00982             //
00983             int flagvalue;
00984             if (!search_nametab(executor, indiv_attraccess_nametab, flagname, &flagvalue))
00985             {
00986                 notify_quiet(executor, "You can't set that!");
00987                 return;
00988             }
00989 
00990             // Make sure the object has the attribute present.
00991             //
00992             if (!atr_get_info(thing, pattr->number, &aowner, &aflags))
00993             {
00994                 notify_quiet(executor, "Attribute not present on object.");
00995                 return;
00996             }
00997 
00998             // Make sure we can write to the attribute.
00999             //
01000             if (!bCanSetAttr(executor, thing, pattr))
01001             {
01002                 notify_quiet(executor, NOPERM_MESSAGE);
01003                 return;
01004             }
01005 
01006             // Go do it.
01007             //
01008             if (clear)
01009             {
01010                 aflags &= ~flagvalue;
01011             }
01012             else
01013             {
01014                 aflags |= flagvalue;
01015             }
01016             bool could_hear = Hearer(thing);
01017 
01018             atr_set_flags(thing, pattr->number, aflags);
01019 
01020             // Tell the player about it.
01021             //
01022             handle_ears(thing, could_hear, Hearer(thing));
01023 
01024             if (  !(key & SET_QUIET)
01025                && !Quiet(executor)
01026                && !Quiet(thing))
01027             {
01028                 if (clear)
01029                 {
01030                     notify_quiet(executor, "Cleared.");
01031                 }
01032                 else
01033                 {
01034                     notify_quiet(executor, "Set.");
01035                 }
01036             }
01037             return;
01038         }
01039     }
01040 
01041     // Find thing.
01042     //
01043     thing = match_controlled(executor, name);
01044     if (!Good_obj(thing))
01045     {
01046         return;
01047     }
01048 
01049     // Check for attribute set first.
01050     //
01051     char *p;
01052     for (p = flagname; *p && (*p != ':'); p++)
01053     {
01054         ; // Nothing.
01055     }
01056 
01057     if (*p)
01058     {
01059         *p++ = 0;
01060         int atr = mkattr(executor, flagname);
01061         if (atr <= 0)
01062         {
01063             notify_quiet(executor, "Couldn't create attribute.");
01064             return;
01065         }
01066         pattr = atr_num(atr);
01067         if (!pattr)
01068         {
01069             notify_quiet(executor, NOPERM_MESSAGE);
01070             return;
01071         }
01072         if (!bCanSetAttr(executor, thing, pattr))
01073         {
01074             notify_quiet(executor, NOPERM_MESSAGE);
01075             return;
01076         }
01077         char *buff = alloc_lbuf("do_set");
01078 
01079         // Check for _
01080         //
01081         if (*p == '_')
01082         {
01083             ATTR *pattr2;
01084             dbref thing2;
01085 
01086             strcpy(buff, p + 1);
01087             if (!( parse_attrib(executor, p + 1, &thing2, &pattr2)
01088                 && pattr2))
01089             {
01090                 notify_quiet(executor, "No match.");
01091                 free_lbuf(buff);
01092                 return;
01093             }
01094             p = buff;
01095             atr_pget_str(buff, thing2, pattr2->number, &aowner, &aflags);
01096 
01097             if (!See_attr(executor, thing2, pattr2))
01098             {
01099                 notify_quiet(executor, NOPERM_MESSAGE);
01100                 free_lbuf(buff);
01101                 return;
01102             }
01103         }
01104 
01105         // Go set it.
01106         //
01107         set_attr_internal(executor, thing, atr, p, key);
01108         free_lbuf(buff);
01109         return;
01110     }
01111 
01112     // Set or clear a flag.
01113     //
01114     flag_set(thing, executor, flagname, key);
01115 }
01116 
01117 void do_power
01118 (
01119     dbref executor,
01120     dbref caller,
01121     dbref enactor,
01122     int   key,
01123     int   nargs,
01124     char *name,
01125     char *flag
01126 )
01127 {
01128     UNUSED_PARAMETER(caller);
01129     UNUSED_PARAMETER(enactor);
01130     UNUSED_PARAMETER(nargs);
01131 
01132     if (  !flag
01133        || !*flag)
01134     {
01135         notify_quiet(executor, "I don't know what you want to set!");
01136         return;
01137     }
01138 
01139     // Find thing.
01140     //
01141     dbref thing = match_controlled(executor, name);
01142     if (thing == NOTHING)
01143     {
01144         return;
01145     }
01146     power_set(thing, executor, flag, key);
01147 }
01148 
01149 void do_setattr
01150 (
01151     dbref executor,
01152     dbref caller,
01153     dbref enactor,
01154     int   attrnum,
01155     int   nargs,
01156     char *name,
01157     char *attrtext
01158 )
01159 {
01160     UNUSED_PARAMETER(caller);
01161     UNUSED_PARAMETER(enactor);
01162     UNUSED_PARAMETER(nargs);
01163 
01164     init_match(executor, name, NOTYPE);
01165     match_everything(MAT_EXIT_PARENTS);
01166     dbref thing = noisy_match_result();
01167 
01168     if (!Good_obj(thing))
01169     {
01170         return;
01171     }
01172     set_attr_internal(executor, thing, attrnum, attrtext, 0);
01173 }
01174 
01175 void do_cpattr(dbref executor, dbref caller, dbref enactor, int key,
01176                char *oldpair, char *newpair[], int nargs)
01177 {
01178     UNUSED_PARAMETER(key);
01179 
01180     int i;
01181     char *oldthing, *oldattr, *newthing, *newattr;
01182 
01183     if (  !*oldpair
01184        || !**newpair
01185        || !oldpair
01186        || !*newpair
01187        || nargs < 1)
01188     {
01189         return;
01190     }
01191 
01192     oldattr = oldpair;
01193     oldthing = parse_to(&oldattr, '/', 1);
01194 
01195     for (i = 0; i < nargs; i++)
01196     {
01197         newattr = newpair[i];
01198         newthing = parse_to(&newattr, '/', 1);
01199 
01200         if (!oldattr)
01201         {
01202             if (!newattr)
01203             {
01204                 do_set(executor, caller, enactor, 0, 2, newthing,
01205                     tprintf("%s:_%s/%s", oldthing, "me", oldthing));
01206             }
01207             else
01208             {
01209                 do_set(executor, caller, enactor, 0, 2, newthing,
01210                     tprintf("%s:_%s/%s", newattr, "me", oldthing));
01211             }
01212         }
01213         else
01214         {
01215             if (!newattr)
01216             {
01217                 do_set(executor, caller, enactor, 0, 2, newthing,
01218                     tprintf("%s:_%s/%s", oldattr, oldthing, oldattr));
01219             }
01220             else
01221             {
01222                 do_set(executor, caller, enactor, 0, 2, newthing,
01223                     tprintf("%s:_%s/%s", newattr, oldthing, oldattr));
01224             }
01225         }
01226     }
01227 }
01228 
01229 
01230 void do_mvattr(dbref executor, dbref caller, dbref enactor, int key,
01231                char *what, char *args[], int nargs)
01232 {
01233     UNUSED_PARAMETER(caller);
01234     UNUSED_PARAMETER(enactor);
01235     UNUSED_PARAMETER(key);
01236 
01237     // Make sure we have something to do.
01238     //
01239     if (nargs < 2)
01240     {
01241         notify_quiet(executor, "Nothing to do.");
01242         return;
01243     }
01244 
01245     // Find and make sure we control the target object.
01246     //
01247     dbref thing = match_controlled(executor, what);
01248     if (thing == NOTHING)
01249     {
01250         return;
01251     }
01252 
01253     // Look up the source attribute.  If it either doesn't exist or isn't
01254     // readable, use an empty string.
01255     //
01256     int in_anum = -1;
01257     char *astr = alloc_lbuf("do_mvattr");
01258     ATTR *in_attr =