Roxen.git / server / modules / filesystems / filesystem.pike

version» Context lines:

Roxen.git/server/modules/filesystems/filesystem.pike:1:   // This is a roxen module. Copyright © 1996 - 2001, Roxen IS.      // This is a virtual "file-system".   // It will be located somewhere in the name-space of the server.   // Also inherited by some of the other filesystems.      inherit "module";   inherit "socket";    - constant cvs_version= "$Id: filesystem.pike,v 1.116 2001/12/21 13:09:17 grubba Exp $"; - constant thread_safe=1; + constant cvs_version = "$Id: filesystem.pike,v 1.117 2002/06/13 19:43:15 nilsson Exp $"; + constant thread_safe = 1;      #include <module.h> - #include <roxen.h> +    #include <stat.h>   #include <request_trace.h>    -  - //<locale-token project="mod_filesystem">LOCALE</locale-token> - #define LOCALE(X,Y) _DEF_LOCALE("mod_filesystem",X,Y) - // end of the locale related stuff -  +    #ifdef FILESYSTEM_DEBUG   # define FILESYSTEM_WERR(X) werror("Filesystem: "+X+"\n")   #else   # define FILESYSTEM_WERR(X)   #endif      #ifdef QUOTA_DEBUG   # define QUOTA_WERR(X) werror("QUOTA: "+X+"\n")   #else   # define QUOTA_WERR(X)   #endif      #if constant(system.normalize_path)   #define NORMALIZE_PATH(X) system.normalize_path(X)   #else /* !constant(system.normalize_path) */   #define NORMALIZE_PATH(X) (X)   #endif /* constant(system.normalize_path) */      constant module_type = MODULE_LOCATION; - LocaleString module_name = LOCALE(51,"File systems: Normal File system"); - LocaleString module_doc = - LOCALE(2,"This is the basic file system module that makes it possible " + constant module_name = "File systems: Normal File system"; + constant module_doc = + ("This is the basic file system module that makes it possible "    "to mount a directory structure in the virtual file system of "    "your site.");   constant module_unique = 0;      int redirects, accesses, errors, dirlists;   int puts, deletes, mkdirs, moves, chmods;      static mapping http_low_answer(int errno, string data, string|void desc)   {    mapping res = Roxen.http_low_answer(errno, data);
Roxen.git/server/modules/filesystems/filesystem.pike:57:    res->rettext = desc;    }       return res;   }      static int do_stat = 1;      string status()   { -  return "<h2>"+LOCALE(3,"Accesses to this filesystem")+"</h2>"+ -  (redirects?"<b>"+LOCALE(4,"Redirects")+"</b>: "+redirects+"<br>":"")+ -  (accesses?"<b>"+LOCALE(5,"Normal files")+"</b>: "+accesses+"<br>" -  :LOCALE(6,"No file accesses)")+"<br>")+ -  (query("put")&&puts?"<b>"+LOCALE(7,"PUTs")+"</b>: "+puts+"<br>":"")+ -  (query("put")&&mkdirs?"<b>"+LOCALE(8,"MKDIRs")+"</b>: "+mkdirs+"<br>":"")+ +  return "<h2>Accesses to this filesystem</h2>"+ +  (redirects?"<b>Redirects</b>: "+redirects+"<br />":"")+ +  (accesses?"<b>Normal files</b>: "+accesses+"<br />" +  :"No file accesses<br />")+ +  (query("put")&&puts?"<b>PUTs</b>: "+puts+"<br />":"")+ +  (query("put")&&mkdirs?"<b>MKDIRs</b>: "+mkdirs+"<br />":"")+    (query("put")&&query("delete")&&moves? -  "<b>"+LOCALE(9,"Moved files")+"</b>: "+moves+"<br>":"")+ -  (query("put")&&chmods?"<b>"+LOCALE(10,"CHMODs")+"</b>: "+chmods+"<br>":"")+ -  (query("delete")&&deletes?"<b>"+LOCALE(11,"Deletes")+"</b>: "+deletes+"<br>":"")+ -  (errors?"<b>"+LOCALE(12,"Permission denied")+"</b>: "+errors -  +" ("+LOCALE(13,"not counting .htaccess")+")<br>":"")+ -  (dirlists?"<b>"+LOCALE(14,"Directories")+"</b>:"+dirlists+"<br>":""); +  "<b>Moved files</b>: "+moves+"<br />":"")+ +  (query("put")&&chmods?"<b>CHMODs</b>: "+chmods+"<br />":"")+ +  (query("delete")&&deletes?"<b>Deletes</b>: "+deletes+"<br />":"")+ +  (errors?"<b>Permission denied</b>: "+errors +  +" (not counting .htaccess)<br />":"")+ +  (dirlists?"<b>Directories</b>:"+dirlists+"<br />":"");   }      void create()   { -  defvar("mountpoint", "/", LOCALE(15,"Mount point"), +  defvar("mountpoint", "/", "Mount point",    TYPE_LOCATION|VAR_INITIAL|VAR_NO_DEFAULT, -  LOCALE(16,"Where the module will be mounted in the site's virtual " -  "file system.")); +  "Where the module will be mounted in the site's virtual file system.");    -  defvar("searchpath", "NONE", LOCALE(17,"Search path"), +  defvar("searchpath", "NONE", "Search path",    TYPE_DIR|VAR_INITIAL|VAR_NO_DEFAULT, -  LOCALE(18,"The directory that contains the files.")); +  "The directory that contains the files.");    -  defvar(".files", 0, LOCALE(19,"Show hidden files"), TYPE_FLAG|VAR_MORE, -  LOCALE(20,"If set, hidden files, ie files that begin with a '.', " +  defvar(".files", 0, "Show hidden files", TYPE_FLAG|VAR_MORE, +  ("If set, hidden files, ie files that begin with a '.', "    "will be shown in directory listings." ));    -  defvar("dir", 1, LOCALE(21,"Enable directory listings per default"), +  defvar("dir", 1, "Enable directory listings per default",    TYPE_FLAG|VAR_MORE, -  LOCALE(22,"If set, it will be possible to get a directory listings " +  ("If set, it will be possible to get a directory listings "    "from directories in this file system. It is possible to "    "force a directory to never be browsable by putting a "    "<tt>.www_not_browsable</tt> or a <tt>.nodiraccess</tt> file "    "in it. Similarly it is possible to let a directory be "    "browsable, even if the file system is not, by putting a "    "<tt>.www_browsable</tt> file in it.\n"));       defvar("nobrowse", ({ ".www_not_browsable", ".nodiraccess" }), -  LOCALE(23,"List prevention files"), TYPE_STRING_LIST|VAR_MORE, -  LOCALE(24,"All directories containing any of these files will not be " -  "browsable.")); +  "List prevention files", TYPE_STRING_LIST|VAR_MORE, +  "All directories containing any of these files will not be browsable.");    -  -  defvar("tilde", 0, LOCALE(25,"Show backup files"), TYPE_FLAG|VAR_MORE, -  LOCALE(26,"If set, files ending with '~', '#' or '.bak' will "+ +  defvar("tilde", 0, "Show backup files", TYPE_FLAG|VAR_MORE, +  ("If set, files ending with '~', '#' or '.bak' will "    "be shown in directory listings"));    -  defvar("put", 0, LOCALE(27,"Handle the PUT method"), TYPE_FLAG, -  LOCALE(28,"If set, it will be possible to upload files with the HTTP " +  defvar("put", 0, "Handle the PUT method", TYPE_FLAG, +  ("If set, it will be possible to upload files with the HTTP "    "method PUT, or through FTP."));    -  defvar("delete", 0, LOCALE(29,"Handle the DELETE method"), TYPE_FLAG, -  LOCALE(30,"If set, it will be possible to delete files with the HTTP " +  defvar("delete", 0, "Handle the DELETE method", TYPE_FLAG, +  ("If set, it will be possible to delete files with the HTTP "    "method DELETE, or through FTP."));    -  defvar("check_auth", 1, LOCALE(31,"Require authentication for modification"), +  defvar("check_auth", 1, "Require authentication for modification",    TYPE_FLAG, -  LOCALE(32,"Only allow users authenticated by a authentication module " +  ("Only allow users authenticated by a authentication module "    "to use methods that can modify the files, such as PUT or "    "DELETE. If this is not set the file system will be a "    "<b>very</b> public one since anyone will be able to edit "    "files."));    -  defvar("stat_cache", 0, LOCALE(33,"Cache the results of stat(2)"), +  defvar("stat_cache", 0, "Cache the results of stat(2)",    TYPE_FLAG|VAR_MORE, -  LOCALE(34,"A performace option that can speed up retrieval of files " +  ("A performace option that can speed up retrieval of files "    "from NFS with up to 50%. In turn it uses some memory and the "    "file system will not notice that files have changed unless "    "it gets a pragma no-cache request (produced e.g. by "    "Alt-Ctrl-Reload in Netscape). Therefore this option should "    "not be used on file systems that change a lot."));    -  defvar("access_as_user", 0, LOCALE(35,"Access files as the logged in user"), +  defvar("access_as_user", 0, "Access files as the logged in user",    TYPE_FLAG|VAR_MORE, -  LOCALE(36,"If set, the module will access files as the authenticated " +  ("If set, the module will access files as the authenticated "    "user. This assumes that a authentication module which imports"    " the users from the operating systems, such as the <i>User "    "database</i> module is used. This option is very useful for "    "named FTP sites, but it will have severe performance impacts "    "since all threads will be locked for each access."));       defvar("access_as_user_db",    Variable.UserDBChoice( " all", VAR_MORE, -  LOCALE(53,"Authentication database to use"), -  LOCALE(54,"The User database module to use " +  "Authentication database to use", +  ("The User database module to use "    "when authenticating users for the "    "access file as the logged in user "    "feature."),    my_configuration()));       defvar( "access_as_user_throw", 0, -  LOCALE(55,"Access files as the logged in user forces login"), +  "Access files as the logged in user forces login",    TYPE_FLAG|VAR_MORE, -  LOCALE(56,"If true, a user will have to be logged in to access files in " +  ("If true, a user will have to be logged in to access files in "    "this filesystem") );    -  defvar("no_symlinks", 0, LOCALE(37,"Forbid access to symlinks"), +  defvar("no_symlinks", 0, "Forbid access to symlinks",    TYPE_FLAG|VAR_MORE, -  LOCALE(38,"It set, the file system will not follow symbolic links. " +  ("It set, the file system will not follow symbolic links. "    "This option can lower performace by a lot." ));    -  defvar("charset", "iso-8859-1", LOCALE(39,"File contents charset"), +  defvar("charset", "iso-8859-1", "File contents charset",    TYPE_STRING, -  LOCALE(40,"The charset of the contents of the files on this file " +  ("The charset of the contents of the files on this file "    "system. This variable makes it possible for Roxen to use " -  "any text file, no matter what charset it is written in. If" -  " necessary, Roxen will convert the file to Unicode before " +  "any text file, no matter what charset it is written in. If " +  "necessary, Roxen will convert the file to Unicode before "    "processing the file."));    -  defvar("path_encoding", "iso-8859-1", LOCALE(41,"Filename charset"), +  defvar("path_encoding", "iso-8859-1", "Filename charset",    TYPE_STRING, -  LOCALE(42,"The charset of the file names of the files on this file " +  ("The charset of the file names of the files on this file "    "system. Unlike the <i>File contents charset</i> variable, "    "this might not work for all charsets simply because not "    "all browsers support anything except ISO-8859-1 "    "in URLs."));    -  defvar("internal_files", ({}), LOCALE(43,"Internal files"), TYPE_STRING_LIST, -  LOCALE(44,"A list of glob patterns that matches files which should be " +  defvar("internal_files", ({}), "Internal files", TYPE_STRING_LIST, +  ("A list of glob patterns that matches files which should be "    "considered internal. Internal files cannot be requested "    "directly from a browser, won't show up in directory listings "    "and can never be uploaded, moved or deleted by a browser." -  "They can only be accessed internally, e.g. with the RXML tags" -  " <tt>&lt;insert&gt;</tt> and <tt>&lt;use&gt;</tt>.")); +  "They can only be accessed internally, e.g. with the RXML tags " +  "<tt>&lt;insert&gt;</tt> and <tt>&lt;use&gt;</tt>."));   }      string path, mountpoint, charset, path_encoding, normalized_path;   int stat_cache, dotfiles, access_as_user, no_symlinks, tilde;   array(string) internal_files;   UserDB access_as_user_db;   int access_as_user_throw;   void start()   {    tilde = query("tilde");
Roxen.git/server/modules/filesystems/filesystem.pike:222: Inside #if constant(system.normalize_path)
   normalized_path = system.normalize_path(path + ".");    } else {    normalized_path = system.normalize_path(path);    }   #ifdef __NT__    normalized_path += "\\";   #else /* !__NT__ */    normalized_path += "/";   #endif /* __NT__ */    }) { -  report_error(LOCALE(1, "Path verification of %s failed.\n"), mountpoint); +  report_error("Path verification of %s failed.\n", mountpoint);    normalized_path = path;    }   #else /* !constant(system.normalize_path) */    normalized_path = path;   #endif /* constant(system.normalize_path) */    FILESYSTEM_WERR("Online at "+query("mountpoint")+" (path="+path+")");    cache_expire("stat_cache");   }      string query_location()
Roxen.git/server/modules/filesystems/filesystem.pike:537: Inside #if constant(system.normalize_path)
   f = norm_f = NORMALIZE_PATH(f = decode_path(path + f));   #if constant(system.normalize_path)    if (!has_prefix(norm_f, normalized_path) &&   #ifdef __NT__    (norm_f+"\\" != normalized_path)   #else /* !__NT__ */    (norm_f+"/" != normalized_path)   #endif /* __NT__ */    ) {    errors++; -  report_error(LOCALE(52, "Path verification of %O failed:\n" -  "%O is not a prefix of %O\n" -  ), oldf, normalized_path, norm_f); +  report_error("Path verification of %O failed:\n" +  "%O is not a prefix of %O\n", +  oldf, normalized_path, norm_f);    TRACE_LEAVE("");    TRACE_LEAVE("Permission denied.");    return http_low_answer(403, "<h2>File exists, but access forbidden "    "by user</h2>");    }       /* Adjust not_query */    id->not_query = mountpoint + replace(norm_f[sizeof(normalized_path)..],    "\\", "/");    if (sizeof(oldf) && (oldf[-1] == '/')) {
Roxen.git/server/modules/filesystems/filesystem.pike:616:    object privs;    SETUID_TRACE("Open file", 1);       o = Stdio.File( );    if(!o->open(norm_f, "r" )) o = 0;    privs = 0;       if(!o || (no_symlinks && (contains_symlinks(path, oldf))))    {    errors++; -  report_error(LOCALE(45,"Open of %s failed. Permission denied.\n"),f); +  report_error("Open of %s failed. Permission denied.\n",f);       TRACE_LEAVE("");    TRACE_LEAVE("Permission denied.");    return http_low_answer(403, "<h2>File exists, but access forbidden "    "by user</h2>");    }       id->realfile = norm_f;    TRACE_LEAVE("");    accesses++;
Roxen.git/server/modules/filesystems/filesystem.pike:669:    return Roxen.http_auth_required("foo",    "<h1>Permission to 'MKDIR' denied</h1>");    }    mkdirs++;    object privs;    SETUID_TRACE("Creating file", 0);       if (query("no_symlinks") && (contains_symlinks(path, oldf))) {    privs = 0;    errors++; -  report_error(LOCALE(46,"Creation of %s failed. Permission denied.\n"), +  report_error("Creation of %s failed. Permission denied.\n",    oldf);    TRACE_LEAVE("MKDIR: Contains symlinks. Permission denied");    return http_low_answer(403, "<h2>Permission denied.</h2>");    }       int code = mkdir(f);    privs = 0;       TRACE_ENTER("MKDIR: Accepted", 0);   
Roxen.git/server/modules/filesystems/filesystem.pike:719:    return Roxen.http_auth_required("foo",    "<h1>Permission to 'PUT' files denied</h1>");    }       puts++;       QUOTA_WERR("Checking quota.\n");    if (id->misc->quota_obj && (id->misc->len > 0) &&    !id->misc->quota_obj->check_quota(URI, id->misc->len)) {    errors++; -  report_warning(LOCALE(47,"Creation of %s failed. Out of quota.\n"),f); +  report_warning("Creation of %s failed. Out of quota.\n",f);    TRACE_LEAVE("PUT: Out of quota.");    return http_low_answer(413, "<h2>Out of disk quota.</h2>",    "413 Out of disk quota");    }          SETUID_TRACE("Saving file", 0);       if (query("no_symlinks") && (contains_symlinks(path, oldf))) {    privs = 0;    errors++; -  report_error(LOCALE(46,"Creation of %s failed. Permission denied.\n"),f); +  report_error("Creation of %s failed. Permission denied.\n",f);    TRACE_LEAVE("PUT: Contains symlinks. Permission denied");    return http_low_answer(403, "<h2>Permission denied.</h2>");    }       rm(f);    mkdirhier(f);       if (id->misc->quota_obj) {    QUOTA_WERR("Checking if the file already existed.");    if (size > 0) {
Roxen.git/server/modules/filesystems/filesystem.pike:1059:    return 0;    }       if(query("check_auth") && (!id->conf->authenticate( id ) ) ) {    TRACE_LEAVE("DELETE: Permission denied");    return http_low_answer(403, "<h1>Permission to DELETE file denied</h1>");    }       if (query("no_symlinks") && (contains_symlinks(path, oldf))) {    errors++; -  report_error(LOCALE(48,"Deletion of %s failed. Permission denied.\n"),f); +  report_error("Deletion of %s failed. Permission denied.\n",f);    TRACE_LEAVE("DELETE: Contains symlinks");    return http_low_answer(403, "<h2>Permission denied.</h2>");    }    -  report_notice(LOCALE(49,"DELETING the file %s.\n"),f); +  report_notice("DELETING the file %s.\n",f);    accesses++;       SETUID_TRACE("Deleting file", 0);       /* Clear the stat-cache for this file */    if (stat_cache) {    cache_set("stat_cache", f, 0);    }       if(!rm(f))
Roxen.git/server/modules/filesystems/filesystem.pike:1101:    default:    TRACE_LEAVE("Not supported");    return 0;    }    TRACE_LEAVE("Not reached");    return 0;   }      string query_name()   { -  if (sizeof(path) > 20) { -  return sprintf((string)LOCALE(50,"%s from %s...%s"), -  mountpoint, path[..7], path[sizeof(path)-8..]); +  if (sizeof(path) > 20) +  return mountpoint + " from " + path[..7]...path[sizeof(path)-8..]; +  return mountpoint + " from " + path;   } -  return sprintf((string)LOCALE(50,"%s from %s"), mountpoint, path); - } +