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.117 2002/06/13 19:43:15 nilsson Exp $"; + constant cvs_version = "$Id: filesystem.pike,v 1.118 2002/06/13 22:33:05 nilsson Exp $";   constant thread_safe = 1;      #include <module.h>   #include <stat.h>   #include <request_trace.h> -  + #include <roxen.h>    -  + //<locale-token project="mod_filesystem">LOCALE</locale-token> + #define LOCALE(X,Y) _STR_LOCALE("mod_filesystem",X,Y) + // end of the locale related stuff + // NGSERVER: Make an API where a module can send back an error token which is + // then substituted with the apropriate message for the protocol and locale. + // This would enable us to theme other error pages than the now special case 404. +    #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)
Roxen.git/server/modules/filesystems/filesystem.pike:382:    FILESYSTEM_WERR(sprintf("done_with_put(%O)\n"    "from: %O\n",    id_arr, mkmapping(indices(from), values(from))));       to->close();    from->set_blocking();    m_delete(putting, from);       if (putting[from] && (putting[from] != 0x7fffffff)) {    // Truncated! -  id->send_result(http_low_answer(400, -  "<h2>Bad Request - " -  "Expected more data.</h2>")); -  } else { -  id->send_result(http_low_answer(200, "<h2>Transfer Complete.</h2>")); +  id->send_result(http_low_answer +  (400, +  "<h2>" + LOCALE(63, "Bad Request - Expected more data.") + +  "</h2>")); +  } else +  id->send_result(http_low_answer +  (200, "<h2>" + LOCALE(64, "Transfer Complete.") + "</h2>"));   } - } +       void got_put_data( array (object|string) id_arr, string data )   {   // werror(strlen(data)+" .. ");       object to;    object from;    object id;    string oldf;       [to, from, id, oldf] = id_arr;       // Truncate at end.    data = data[..putting[from]];       if (id->misc->quota_obj &&    !id->misc->quota_obj->check_quota(oldf, sizeof(data))) {    to->close();    from->set_blocking();    m_delete(putting, from); -  id->send_result(http_low_answer(413, "<h2>Out of disk quota.</h2>", -  "413 Out of disk quota")); +  id->send_result(http_low_answer +  (413, "<h2>" + LOCALE(65, "Out of disk quota.") + "</h2>", +  "413 " + LOCALE(65, "Out of disk quota.") ));    return;    }       int bytes = to->write( data );    if (bytes < sizeof(data)) {    // Out of disk!    to->close();    from->set_blocking();    m_delete(putting, from); -  id->send_result(http_low_answer(413, "<h2>Disk full.</h2>")); +  id->send_result(http_low_answer(413, "<h2>" + LOCALE(66, "Disk full.") + "</h2>"));    return;    } else {    if (id->misc->quota_obj &&    !id->misc->quota_obj->allocate(oldf, bytes)) {    to->close();    from->set_blocking();    m_delete(putting, from); -  id->send_result(http_low_answer(413, "<h2>Out of disk quota.</h2>", -  "413 Out of disk quota")); +  id->send_result(http_low_answer +  (413, "<h2>" + LOCALE(65, "Out of disk quota.") + "</h2>", +  "413 " + LOCALE(65, "Out of disk quota.") ));    return;    }    if (putting[from] != 0x7fffffff) {    putting[from] -= bytes;    }    if(putting[from] <= 0) {    putting[from] = 0; // Paranoia    done_with_put( id_arr );    }    }
Roxen.git/server/modules/filesystems/filesystem.pike:533: Inside #if constant(system.normalize_path)
  #else /* !__NT__ */    (norm_f+"/" != normalized_path)   #endif /* __NT__ */    ) {    errors++;    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>"); +  return http_low_answer +  (403, "<h2>" + LOCALE(67, "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] == '/')) {    id->not_query += "/";    }   #endif /* constant(system.normalize_path) */    };
Roxen.git/server/modules/filesystems/filesystem.pike:611:    if(!o->open(norm_f, "r" )) o = 0;    privs = 0;       if(!o || (no_symlinks && (contains_symlinks(path, oldf))))    {    errors++;    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>"); +  return http_low_answer +  (403, "<h2>" + LOCALE(67, "File exists, but access forbidden by user.") + +  "</h2>");    }       id->realfile = norm_f;    TRACE_LEAVE("");    accesses++;    TRACE_LEAVE("Normal return");    if( charset != "iso-8859-1" )    {    if( id->misc->set_output_charset )    id->misc->set_output_charset( charset, 2 );
Roxen.git/server/modules/filesystems/filesystem.pike:650:    return 0;    }       if (size != -1) {    TRACE_LEAVE("MKDIR failed. Directory name already exists. ");    return 0;    }       if(query("check_auth") && (!id->conf->authenticate( id ) ) ) {    TRACE_LEAVE("MKDIR: Permission denied"); -  return Roxen.http_auth_required("foo", -  "<h1>Permission to 'MKDIR' denied</h1>"); +  return Roxen.http_auth_required +  ("foo", "<h1>" + LOCALE(68, "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("Creation of %s failed. Permission denied.\n",    oldf);    TRACE_LEAVE("MKDIR: Contains symlinks. Permission denied"); -  return http_low_answer(403, "<h2>Permission denied.</h2>"); +  return http_low_answer(403, "<h2>" + LOCALE(69, "Permission denied.") + "</h2>");    }       int code = mkdir(f);    privs = 0;       TRACE_ENTER("MKDIR: Accepted", 0);       if (code) {    chmod(f, 0777 & ~(id->misc->umask || 022));    TRACE_LEAVE("MKDIR: Success");    TRACE_LEAVE("Success"); -  return Roxen.http_string_answer("Ok"); +  return Roxen.http_string_answer(LOCALE(70, "Ok"));    } else {    TRACE_LEAVE("MKDIR: Failed");    TRACE_LEAVE("Failure");    return 0;    }       break;       case "PUT":    if(!query("put"))
Roxen.git/server/modules/filesystems/filesystem.pike:700:    }       if (FILTER_INTERNAL_FILE (f, id)) {    id->misc->error_code = 405;    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>"); +  return Roxen.http_auth_required +  ("foo", "<h1>" + LOCALE(71, "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("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"); +  return http_low_answer(413, "<h2>" + LOCALE(65, "Out of disk quota.") + "</h2>", +  "413 " + LOCALE(65, "Out of disk quota.") );    }          SETUID_TRACE("Saving file", 0);       if (query("no_symlinks") && (contains_symlinks(path, oldf))) {    privs = 0;    errors++;    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>"); +  return http_low_answer(403, "<h2>" + LOCALE(69, "Permission denied.") + "</h2>");    }       rm(f);    mkdirhier(f);       if (id->misc->quota_obj) {    QUOTA_WERR("Checking if the file already existed.");    if (size > 0) {    QUOTA_WERR("Deallocating " + size + "bytes.");    id->misc->quota_obj->deallocate(URI, size);
Roxen.git/server/modules/filesystems/filesystem.pike:772:    // FIXME: What if sizeof(id->data) > id->misc->len ?    if (id->misc->len > 0) {    putting[id->my_fd] -= strlen(id->data);    }    int bytes = to->write( id->data );    if (id->misc->quota_obj) {    QUOTA_WERR("Allocating " + bytes + "bytes.");    if (!id->misc->quota_obj->allocate(f, bytes)) {    TRACE_LEAVE("PUT: A string");    TRACE_LEAVE("PUT: Out of quota"); -  return http_low_answer(413, "<h2>Out of disk quota.</h2>", -  "413 Out of disk quota"); +  return http_low_answer(413, "<h2>" + LOCALE(65, "Out of disk quota.") + "</h2>", +  "413 " + LOCALE(65, "Out of disk quota.") );    }    }    }    if(!putting[id->my_fd]) {    TRACE_LEAVE("PUT: Just a string");    TRACE_LEAVE("Put: Success"); -  return Roxen.http_string_answer("Ok"); +  return Roxen.http_string_answer(LOCALE(70, "Ok"));    }       if(id->clientprot == "HTTP/1.1") {    id->my_fd->write("HTTP/1.1 100 Continue\r\n");    }    id->my_fd->set_id( ({ to, id->my_fd, id, URI }) );    id->my_fd->set_nonblocking(got_put_data, 0, done_with_put);    TRACE_LEAVE("PUT: Pipe in progress");    TRACE_LEAVE("PUT: Success so far");    return Roxen.http_pipe_in_progress();
Roxen.git/server/modules/filesystems/filesystem.pike:812:    }       if (FILTER_INTERNAL_FILE (f, id)) {    id->misc->error_code = 405;    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>"); +  return Roxen.http_auth_required("foo", "<h1>" + LOCALE(73, "Permission to 'CHMOD' files denied.") + +  "</h1>");    }          SETUID_TRACE("CHMODing file", 0);       if (query("no_symlinks") && (contains_symlinks(path, oldf))) {    privs = 0;    errors++;    TRACE_LEAVE("CHMOD: Contains symlinks. Permission denied"); -  return http_low_answer(403, "<h2>Permission denied.</h2>"); +  return http_low_answer(403, "<h2>" + LOCALE(69, "Permission denied.") + "</h2>");    }       array err = catch(chmod(f, id->misc->mode & 0777));    privs = 0;       chmods++;       TRACE_ENTER("CHMOD: Accepted", 0);       if (stat_cache) {
Roxen.git/server/modules/filesystems/filesystem.pike:846:       if(err)    {    id->misc->error_code = 403;    TRACE_LEAVE("CHMOD: Failure");    TRACE_LEAVE("Failure");    return 0;    }    TRACE_LEAVE("CHMOD: Success");    TRACE_LEAVE("Success"); -  return Roxen.http_string_answer("Ok"); +  return Roxen.http_string_answer(LOCALE(70, "Ok"));       case "MV":    // This little kluge is used by ftp2 to move files.       // FIXME: Support for quota.       if(!query("put"))    {    id->misc->error_code = 405;    TRACE_LEAVE("MV disallowed (since PUT is disallowed)");
Roxen.git/server/modules/filesystems/filesystem.pike:875:       if(size < -1)    {    id->misc->error_code = 405;    TRACE_LEAVE("MV: Cannot overwrite directory");    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>"); +  return Roxen.http_auth_required("foo", "<h1>" + LOCALE(74, "Permission to 'MV' files denied.") + +  "</h1>");    }    string movefrom;    if(!id->misc->move_from ||    !(movefrom = id->conf->real_file(id->misc->move_from, id))) {    id->misc->error_code = 405;    errors++;    TRACE_LEAVE("MV: No source file");    return 0;    }   
Roxen.git/server/modules/filesystems/filesystem.pike:902:    }       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>"); +  return http_low_answer(403, "<h2>" + LOCALE(69, "Permission denied.") + "</h2>");    }       code = mv(movefrom, f);    privs = 0;       moves++;       TRACE_ENTER("MV: Accepted", 0);       /* Clear the stat-cache for this file */
Roxen.git/server/modules/filesystems/filesystem.pike:927:       if(!code)    {    id->misc->error_code = 403;    TRACE_LEAVE("MV: Move failed");    TRACE_LEAVE("Failure");    return 0;    }    TRACE_LEAVE("MV: Success");    TRACE_LEAVE("Success"); -  return Roxen.http_string_answer("Ok"); +  return Roxen.http_string_answer(LOCALE(70, "Ok"));       case "MOVE":    // This little kluge is used by NETSCAPE 4.5       // FIXME: Support for quota.       if(!query("put"))    {    id->misc->error_code = 405;    TRACE_LEAVE("MOVE disallowed (since PUT is disallowed)");
Roxen.git/server/modules/filesystems/filesystem.pike:949:    }    if(size != -1)    {    id->misc->error_code = 404;    TRACE_LEAVE("MOVE failed (no such file)");    return 0;    }       if(query("check_auth") && (!id->conf->authenticate( id ) ) ) {    TRACE_LEAVE("MOVE: Permission denied"); -  return Roxen.http_auth_required("foo", -  "<h1>Permission to 'MOVE' files denied</h1>"); +  return Roxen.http_auth_required("foo", "<h1>" + LOCALE(75, "Permission to 'MOVE' files denied.") + +  "</h1>");    }       if(!sizeof(id->misc["new-uri"] || "")) {    id->misc->error_code = 405;    errors++;    TRACE_LEAVE("MOVE: No dest file");    return 0;    }    string new_uri = combine_path(URI + "/../",    id->misc["new-uri"]);
Roxen.git/server/modules/filesystems/filesystem.pike:1001:    }       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>"); +  return http_low_answer(403, "<h2>" + LOCALE(69, "Permission denied.") + "</h2>");    }       code = mv(f, decode_path(moveto));    privs = 0;       TRACE_ENTER("MOVE: Accepted", 0);       moves++;       /* Clear the stat-cache for this file */
Roxen.git/server/modules/filesystems/filesystem.pike:1026:       if(!code)    {    id->misc->error_code = 403;    TRACE_LEAVE("MOVE: Move failed");    TRACE_LEAVE("Failure");    return 0;    }    TRACE_LEAVE("MOVE: Success");    TRACE_LEAVE("Success"); -  return Roxen.http_string_answer("Ok"); +  return Roxen.http_string_answer(LOCALE(70, "Ok"));          case "DELETE":    if(!query("delete") || size==-1)    {    id->misc->error_code = 405;    TRACE_LEAVE("DELETE: Disabled");    return 0;    }       if (FILTER_INTERNAL_FILE (f, id)) {    id->misc->error_code = 405;    TRACE_LEAVE("DELETE of internal file is disallowed");    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>"); +  return http_low_answer(403, "<h1>" + LOCALE(76, "Permission to DELETE file denied.") + "</h1>");    }       if (query("no_symlinks") && (contains_symlinks(path, oldf))) {    errors++;    report_error("Deletion of %s failed. Permission denied.\n",f);    TRACE_LEAVE("DELETE: Contains symlinks"); -  return http_low_answer(403, "<h2>Permission denied.</h2>"); +  return http_low_answer(403, "<h2>" + LOCALE(69, "Permission denied.") + "</h2>");    }       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);
Roxen.git/server/modules/filesystems/filesystem.pike:1080:    return 0;    }    privs = 0;    deletes++;       if (id->misc->quota_obj && (size > 0)) {    id->misc->quota_obj->deallocate(oldf, size);    }       TRACE_LEAVE("DELETE: Success"); -  return http_low_answer(200,(f+" DELETED from the server")); +  return http_low_answer(200, sprintf( LOCALE("%s DELETED from the server."), f));       default:    TRACE_LEAVE("Not supported");    return 0;    }    TRACE_LEAVE("Not reached");    return 0;   }      string query_name()   {    if (sizeof(path) > 20)    return mountpoint + " from " + path[..7]...path[sizeof(path)-8..];    return mountpoint + " from " + path;   }