tmi2_fluffos_v2/
tmi2_fluffos_v2/bin/
tmi2_fluffos_v2/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/ChangeLog.old/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/Win32/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/simuls/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/clone/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/command/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/data/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/master/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/log/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/compiler/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/efuns/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/operators/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/u/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/tmp/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/windows/
tmi2_fluffos_v2/lib/
tmi2_fluffos_v2/lib/adm/
tmi2_fluffos_v2/lib/adm/daemons/languages/
tmi2_fluffos_v2/lib/adm/daemons/network/I3/
tmi2_fluffos_v2/lib/adm/daemons/virtual/
tmi2_fluffos_v2/lib/adm/daemons/virtual/template/
tmi2_fluffos_v2/lib/adm/news/
tmi2_fluffos_v2/lib/adm/obj/
tmi2_fluffos_v2/lib/adm/obj/master/
tmi2_fluffos_v2/lib/adm/priv/
tmi2_fluffos_v2/lib/adm/shell/
tmi2_fluffos_v2/lib/adm/tmp/
tmi2_fluffos_v2/lib/cmds/
tmi2_fluffos_v2/lib/d/
tmi2_fluffos_v2/lib/d/Conf/
tmi2_fluffos_v2/lib/d/Conf/adm/
tmi2_fluffos_v2/lib/d/Conf/boards/
tmi2_fluffos_v2/lib/d/Conf/cmds/
tmi2_fluffos_v2/lib/d/Conf/data/
tmi2_fluffos_v2/lib/d/Conf/logs/
tmi2_fluffos_v2/lib/d/Conf/obj/
tmi2_fluffos_v2/lib/d/Conf/text/help/
tmi2_fluffos_v2/lib/d/Fooland/adm/
tmi2_fluffos_v2/lib/d/Fooland/data/
tmi2_fluffos_v2/lib/d/Fooland/data/attic/
tmi2_fluffos_v2/lib/d/Fooland/items/
tmi2_fluffos_v2/lib/d/TMI/
tmi2_fluffos_v2/lib/d/TMI/adm/
tmi2_fluffos_v2/lib/d/TMI/boards/
tmi2_fluffos_v2/lib/d/TMI/data/
tmi2_fluffos_v2/lib/d/TMI/rooms/
tmi2_fluffos_v2/lib/d/grid/
tmi2_fluffos_v2/lib/d/grid/adm/
tmi2_fluffos_v2/lib/d/grid/data/
tmi2_fluffos_v2/lib/d/std/
tmi2_fluffos_v2/lib/d/std/adm/
tmi2_fluffos_v2/lib/data/adm/
tmi2_fluffos_v2/lib/data/adm/daemons/
tmi2_fluffos_v2/lib/data/adm/daemons/doc_d/
tmi2_fluffos_v2/lib/data/adm/daemons/emoted/
tmi2_fluffos_v2/lib/data/adm/daemons/network/http/
tmi2_fluffos_v2/lib/data/adm/daemons/network/services/mail_q/
tmi2_fluffos_v2/lib/data/adm/daemons/network/smtp/
tmi2_fluffos_v2/lib/data/adm/daemons/news/archives/
tmi2_fluffos_v2/lib/data/attic/connection/
tmi2_fluffos_v2/lib/data/attic/user/
tmi2_fluffos_v2/lib/data/std/connection/b/
tmi2_fluffos_v2/lib/data/std/connection/l/
tmi2_fluffos_v2/lib/data/std/user/a/
tmi2_fluffos_v2/lib/data/std/user/b/
tmi2_fluffos_v2/lib/data/std/user/d/
tmi2_fluffos_v2/lib/data/std/user/f/
tmi2_fluffos_v2/lib/data/std/user/l/
tmi2_fluffos_v2/lib/data/std/user/x/
tmi2_fluffos_v2/lib/data/u/d/dm/working/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/smtp/
tmi2_fluffos_v2/lib/doc/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/interactive/
tmi2_fluffos_v2/lib/doc/driverdoc/concepts/
tmi2_fluffos_v2/lib/doc/driverdoc/driver/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/arrays/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/buffers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/compile/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/ed/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/filesystem/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/floats/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/functions/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/general/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/mappings/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/numbers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/parsing/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/constructs/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/preprocessor/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/types/
tmi2_fluffos_v2/lib/doc/driverdoc/platforms/
tmi2_fluffos_v2/lib/doc/mudlib/
tmi2_fluffos_v2/lib/ftp/
tmi2_fluffos_v2/lib/include/driver/
tmi2_fluffos_v2/lib/log/
tmi2_fluffos_v2/lib/log/driver/
tmi2_fluffos_v2/lib/obj/net/
tmi2_fluffos_v2/lib/obj/shells/
tmi2_fluffos_v2/lib/obj/tools/
tmi2_fluffos_v2/lib/std/adt/
tmi2_fluffos_v2/lib/std/board/
tmi2_fluffos_v2/lib/std/body/
tmi2_fluffos_v2/lib/std/fun/
tmi2_fluffos_v2/lib/std/living/
tmi2_fluffos_v2/lib/std/object/
tmi2_fluffos_v2/lib/std/shop/
tmi2_fluffos_v2/lib/std/socket/
tmi2_fluffos_v2/lib/std/user/
tmi2_fluffos_v2/lib/std/virtual/
tmi2_fluffos_v2/lib/student/
tmi2_fluffos_v2/lib/student/kalypso/
tmi2_fluffos_v2/lib/student/kalypso/armor/
tmi2_fluffos_v2/lib/student/kalypso/rooms/
tmi2_fluffos_v2/lib/student/kalypso/weapons/
tmi2_fluffos_v2/lib/u/l/leto/
tmi2_fluffos_v2/lib/u/l/leto/cmds/
tmi2_fluffos_v2/lib/www/errors/
tmi2_fluffos_v2/lib/www/gateways/
tmi2_fluffos_v2/lib/www/images/
tmi2_fluffos_v2/old/
tmi2_fluffos_v2/win32/
/*
// File:      /adm/daemons/quota.c
// Purpose:   maintain preset disk quotas by checking how much disk space
//            a user is using before allowing them to use more
// 93-05-15   Created by Watcher@TMI-2
//            This file is part of the TMI-2 distribution.
//            Please keep this header if you use any of this code.
// 93-07-30   Grendel@TMI-2 Fixed a bug which didn't allow anyone
//            to write to the root directory properly.
// 93-08-18   Pallando@TMI-2 Fixed another bug which was still preventing
//            mv from working with files in the root directory.
*/
 
#include <uid.h>
#include <mudlib.h>
 
inherit DAEMON;
 
#define MAX_RECURSION	6
 
#define DEFAULT_QUOTA	200
#define STUDENT_QUOTA	100
 
#define USER_QUOTAS	"/adm/etc/user_quotas"
 
void load_quotas();
int dir_size(string where, int level);
 
mapping quotas;
 

void create() {  seteuid(getuid());  load_quotas();  }
 
//  This function loads up all the preset user quotas

void load_quotas() {
   string *tmp, file, name;
   int loop, amount;

   quotas = ([ ]);			// Initialize the quotas mapping

   file = read_file(USER_QUOTAS);
   if(!file || !(tmp = explode(file, "\n")))  return;

   for(loop=0; loop<sizeof(tmp); loop++)
     if(tmp[loop][0] == '#' || tmp[loop][0] == '\n' || tmp[loop] == "" ||
	sscanf(tmp[loop], "%s:%d", name, amount) != 2)  continue;
     else  quotas[name] = amount;

}
 
 
//  Allow an external user quota query to go through...but if it isn't
//  coming from a ROOT daemon, only give them a copy of the mapping.
 
mapping query_quotas() {  
 //if(geteuid(previous_object()) == ROOT_UID)  return quotas;
 //else return copy(quotas);
   return copy(quotas);
}
 
 
//  This function actually performs the quota check and returns whether
//  the write is allowed or not to the master system.
 
int quota_check(string dir) {
   string *path;
   int quota;
 
   if(!dir || !stringp(dir)) return 0; // error
 
   //	Parse out the directory path

   path = explode(dir, "/");
 
   if(!path || !sizeof(path)) return 1; // root directory
 
   //	If an admin is trying to write somewhere ... let them.

   if(this_player() && adminp(geteuid(this_player())))
	return 1;

   //	First lets see if the requested file/dir is actually a
   //	user directory ... at least at the root user dir level.
 
   if(path[0] == "u" && sizeof(path) >= 3) {

	//  Let Admins use as much space as they want ... they know best.

	if(adminp(path[2]))  return 1;
 
	//  Check to see if there is a preset quota in place for
	//  this particular user, if not, use the DEFAULT_QUOTA.
 
	quota = quotas[path[2]];
	if(!quota)  quota = DEFAULT_QUOTA;
 
	//  Will this write put the user beyond their quota?

	if(dir_size("/u/" + path[1] + "/" + path[2], 0)/1000 >= quota)
	  return 0;
 
	else return 1; 
   }
 
   else if(path[0] == "student" && sizeof(path) > 3) {

        //  Check to see if there is a preset quota in place for
        //  this particular user, if not, use the STUDENT_QUOTA.

        quota = quotas[path[2]];
        if(!quota)  quota = STUDENT_QUOTA;

        //  Will this write put the user beyond their quota?

  	if(dir_size("/student/" + path[1], 0)/1000 >= quota)
          return 0;

        else return 1;
   }
 
   //	Well, if we've gotten this far, its probably an admin or
   //   system directory, and since there are no quotas there, 
   //	let the file write continue.
 
return 1; }
 

//  This function performs the actual totaling of the files and
//  subdirectories within the requested directory.
 
int dir_size(string path, int level) {
   string *dir;
   int loop, size, sub;

   if(level > MAX_RECURSION) return 0;

   size = file_size(path);
 
   if(size == -1)  return 0;
 
   if(size == -2) {
     size = 0;
     dir = get_dir(path + "/");

     if(dir) {
     	sub = sizeof(dir);
	for(loop=0; loop<sub; loop++)
	  size += dir_size(path + "/" + dir[loop], level + 1);
      }
 
   }
 
return size; }