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.128 2004/05/06 13:34:37 grubba Exp $"; + constant cvs_version= "$Id: filesystem.pike,v 1.129 2004/05/08 14:57:03 grubba 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)
Roxen.git/server/modules/filesystems/filesystem.pike:574:    id->misc->stat = fs;    if( stat_cache ) cache_set("stat_cache",(X),({fs}));    return fs[ST_SIZE];    } else if( stat_cache )    cache_set("stat_cache",(X),({0}));    return -1;   }      int contains_symlinks(string root, string path)   { -  array arr = path/"/"; -  Stat rr; -  -  foreach(arr - ({ "" }), path) { +  foreach(path/"/" - ({ "" }), path) {    root += "/" + path; -  +  Stat rr;    if (rr = file_stat(decode_path(root), 1)) {    if (rr[1] == -3) {    return(1);    }    } else {    return(0);    }    }    return(0);   }
Roxen.git/server/modules/filesystems/filesystem.pike:660:    int err_code = errno();    privs = 0;       TRACE_ENTER(sprintf("%s: Accepted", id->method), 0);       if (code) {    chmod(norm_f, 0777 & ~(id->misc->umask || 022));    TRACE_LEAVE(sprintf("%s: Success", id->method));    TRACE_LEAVE(sprintf("%s: Success", id->method));    if (id->method == "MKCOL") { -  return http_low_answer(201, "Created"); +  return Roxen.http_low_answer(201, "Created");    }    return Roxen.http_string_answer("Ok");    }       TRACE_LEAVE(sprintf("%s: Failed", id->method));    id->misc->error_code = 507;    if (err_code ==   #if constant(system.ENOENT)    system.ENOENT   #elif constant(System.ENOENT)    System.ENOENT   #else    2   #endif    ) {    TRACE_LEAVE(sprintf("%s: Missing intermediate.", id->method)); -  id->misc->error_code = 409; +  return Roxen.http_low_answer(409, "Missing intermediate.");    } else {    TRACE_LEAVE(sprintf("%s: Failed.", id->method));    }    return 0;   }      mixed find_file( string f, RequestID id )   {    TRACE_ENTER("find_file(\""+f+"\")", 0);    object o;
Roxen.git/server/modules/filesystems/filesystem.pike:734:       /* Adjust not_query */    id->not_query = mountpoint + replace(norm_f[sizeof(normalized_path)..],    "\\", "/");    if (sizeof(oldf) && (oldf[-1] == '/')) {    id->not_query += "/";    }   #endif /* constant(system.normalize_path) */    };    +  // NOTE: Sets id->misc->stat.    size = _file_size( f, id );       FILESYSTEM_WERR(sprintf("_file_size(%O, %O) ==> %d\n", f, id, size));       /*    * FIXME: Should probably move path-info extraction here.    * /grubba 1998-08-26    */       switch(id->method)
Roxen.git/server/modules/filesystems/filesystem.pike:891:       if (code) {    chmod(f, 0777 & ~(id->misc->umask || 022));    TRACE_LEAVE(sprintf("%s: Success", id->method));    TRACE_LEAVE("Success");    if (id->method == "MKCOL") {    return http_low_answer(201, "Created");    }    return Roxen.http_string_answer("Ok");    } else { -  TRACE_LEAVE(sprintf("%s: Failed", id->method)); +  SIMPLE_TRACE_LEAVE("%s: Failed (errcode:%d)", id->method, errcode);    TRACE_LEAVE("Failure");    if (id->method == "MKCOL") {    if (err_code ==   #if constant(system.ENOENT)    system.ENOENT   #elif constant(System.ENOENT)    System.ENOENT   #else    2   #endif
Roxen.git/server/modules/filesystems/filesystem.pike:933:    TRACE_LEAVE("PUT of internal file is disallowed");    return 0;    }       if(query("check_auth") && (!id->conf->authenticate( id ) ) ) {    TRACE_LEAVE("PUT: Permission denied");    return Roxen.http_auth_required("foo",    "<h1>Permission to 'PUT' files denied</h1>");    }    -  if (mapping(string:mixed) ret = write_access(f, 0, id)) { +  if (mapping(string:mixed) ret = write_access(oldf, 0, id)) {    TRACE_LEAVE("PUT: Locked");    return ret;    }       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++;
Roxen.git/server/modules/filesystems/filesystem.pike:1054:    TRACE_LEAVE("CHMOD of internal file is disallowed");    return 0;    }       if(query("check_auth") && (!id->conf->authenticate( id ) ) ) {    TRACE_LEAVE("CHMOD: Permission denied");    return Roxen.http_auth_required("foo",    "<h1>Permission to 'CHMOD' files denied</h1>");    }    -  if (mapping(string:mixed) ret = write_access(f, 0, id)) { +  if (mapping(string:mixed) ret = write_access(oldf, 0, id)) {    TRACE_LEAVE("PUT: Locked");    return ret;    }       SETUID_TRACE("CHMODing file", 0);       if (query("no_symlinks") && (contains_symlinks(path, oldf))) {    privs = 0;    errors++;    TRACE_LEAVE("CHMOD: Contains symlinks. Permission denied");
Roxen.git/server/modules/filesystems/filesystem.pike:1122:    return 0;    }       if(query("check_auth") && (!id->conf->authenticate( id ) ) ) {    TRACE_LEAVE("MV: Permission denied");    return Roxen.http_auth_required("foo",    "<h1>Permission to 'MV' files denied</h1>");    }    string movefrom;    if(!id->misc->move_from || +  !has_prefix(id->misc->move_from, mountpoint) ||    !(movefrom = id->conf->real_file(id->misc->move_from, id))) {    id->misc->error_code = 405;    errors++;    TRACE_LEAVE("MV: No source file");    return 0;    }    -  +  string relative_from = id->misc->move_from[sizeof(mountpoint)..]; +     if (FILTER_INTERNAL_FILE (movefrom, id) ||    FILTER_INTERNAL_FILE (f, id)) {    id->misc->error_code = 405;    TRACE_LEAVE("MV to or from internal file is disallowed");    return 0;    }    -  // FIXME: What about moving of directories containing locked files? -  if (mapping(string:mixed) ret = write_access(f, 0, id) || -  write_access(id->misc->move_from, 0, id)) { -  TRACE_LEAVE("MV: Locked"); -  return ret; -  } -  -  SETUID_TRACE("Moving file", 0); -  +     if (query("no_symlinks") &&    ((contains_symlinks(path, oldf)) ||    (contains_symlinks(path, id->misc->move_from)))) { -  privs = 0; +     errors++;    TRACE_LEAVE("MV: Contains symlinks. Permission denied");    return http_low_answer(403, "<h2>Permission denied.</h2>");    }    -  +  // FIXME: What about moving of directories containing locked files? +  if (mapping(string:mixed) ret = write_access(oldf, 0, id) || +  write_access(relative_from, 0, id)) { +  TRACE_LEAVE("MV: Locked"); +  return ret; +  } +  +  SETUID_TRACE("Moving file", 0); +     code = mv(movefrom, f);    privs = 0;       moves++;       TRACE_ENTER("MV: Accepted", 0);       /* Clear the stat-cache for this file */    if (stat_cache) {    cache_set("stat_cache", movefrom, 0);
Roxen.git/server/modules/filesystems/filesystem.pike:1230:    if (div > 0) {    new_uri = new_uri[div..];    } else {    new_uri = "/";    }    } else {    new_uri = combine_path(URI + "/../", new_uri);    }       // FIXME: The code below doesn't allow for this module being overloaded. -  if (new_uri[..sizeof(mountpoint)-1] != mountpoint) { +  if (!has_prefix(new_uri, mountpoint)) {    id->misc->error_code = 405;    TRACE_LEAVE("MOVE: Dest file on other filesystem.");    return(0);    } -  string moveto = path + "/" + new_uri[sizeof(mountpoint)..]; +  new_uri = new_uri[sizeof(mountpoint)..]; +  string moveto = path + "/" + new_uri;       if (FILTER_INTERNAL_FILE (f, id) ||    FILTER_INTERNAL_FILE (moveto, id)) {    id->misc->error_code = 405;    TRACE_LEAVE("MOVE to or from internal file is disallowed");    return 0;    }       size = _file_size(moveto,id);   
Roxen.git/server/modules/filesystems/filesystem.pike:1260:    return 0;    }       if(size < -1)    {    id->misc->error_code = 405;    TRACE_LEAVE("MOVE: Cannot overwrite directory");    return 0;    }    -  if (mapping(string:mixed) ret = -  write_access(moveto, 0, id) || -  write_access(f, 0, id)) { -  TRACE_LEAVE("MOVE: Locked"); -  return ret; -  } -  -  SETUID_TRACE("Moving file", 0); -  +     if (query("no_symlinks") &&    ((contains_symlinks(path, f)) ||    (contains_symlinks(path, moveto)))) {    privs = 0;    errors++;    TRACE_LEAVE("MOVE: Contains symlinks. Permission denied");    return http_low_answer(403, "<h2>Permission denied.</h2>");    }    -  +  if (mapping(string:mixed) ret = +  write_access(new_uri, 0, id) || +  write_access(oldf, 0, id)) { +  TRACE_LEAVE("MOVE: Locked"); +  return ret; +  } +  +  SETUID_TRACE("Moving file", 0); +     code = mv(f, decode_path(moveto));    privs = 0;       TRACE_ENTER("MOVE: Accepted", 0);       moves++;       /* Clear the stat-cache for this file */    if (stat_cache) {    cache_set("stat_cache", moveto, 0);
Roxen.git/server/modules/filesystems/filesystem.pike:1345:    (String.trim_whites(id->request_headers->depth||"infinity") !=    "infinity")) {    // RFC 2518 8.6.2:    // The DELETE method on a collection MUST act as if a "Depth: infinity"    // header was used on it.    TRACE_LEAVE(sprintf("DELETE: Bad depth header: %O.",    id->request_headers->depth));    return http_low_answer(400, "<h2>Unsupported depth.</h2>");    }    +  // FIXME: write_access(). +     if (size < 0) {    report_notice(LOCALE(64,"DELETING the directory %s.\n"), f);       accesses++;       SETUID_TRACE("Deleting directory", 0);       int start_ms_size = id->multi_status_size();    recursive_rm(f, query_location() + oldf, id);   
Roxen.git/server/modules/filesystems/filesystem.pike:1413:    id->misc->error_code = 501;    TRACE_LEAVE("Not supported");    return 0;    }    TRACE_LEAVE("Not reached");    return 0;   }      mapping copy_file(string path, string dest, int(-1..1) behavior, RequestID id)   { -  TRACE_ENTER("COPY: Copy %O to %O.", this_object()); +  SIMPLE_TRACE_ENTER(this, "COPY: Copy %O to %O.", path, dest);    Stat source_st = stat_file(path, id);    if (!source_st) {    TRACE_LEAVE("COPY: Source doesn't exist.");    return Roxen.http_low_answer(404, "File not found.");    }    Stat dest_st = stat_file(path, id);    if (dest_st) {    if ((source_st->isreg != dest_st->isreg) ||    (source_st->isdir != dest_st->isdir)) {    TRACE_LEAVE("COPY: Resource types for source and destination differ.");
Roxen.git/server/modules/filesystems/filesystem.pike:1492:    System.ENOENT   #else    2   #endif    ) {    return http_low_answer(409, "Missing intermediate.");    } else {    return http_low_answer(507, "Failed.");    }    } +  } else { +  TRACE_LEAVE("COPY: is file. Not supported yet."); +  return Roxen.http_status(Protocols.HTTP.HTTP_NOT_IMPL);    }   }      string query_name()   {    if (sizeof(path) > 20) {    return sprintf((string)LOCALE(63,"%s from %s...%s"),    mountpoint, path[..7], path[sizeof(path)-8..]);    }    return sprintf((string)LOCALE(50,"%s from %s"), mountpoint, path);   }