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 - 1998, Idonex AB.      // 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 "roxenlib";   inherit "socket";    - constant cvs_version= "$Id: filesystem.pike,v 1.51 1999/04/21 16:48:05 grubba Exp $"; + constant cvs_version= "$Id: filesystem.pike,v 1.52 1999/05/05 20:19:59 grubba Exp $";   constant thread_safe=1;         #include <module.h>   #include <roxen.h>   #include <stat.h>      #if DEBUG_LEVEL > 20   # ifndef FILESYSTEM_DEBUG   # define FILESYSTEM_DEBUG
Roxen.git/server/modules/filesystems/filesystem.pike:229:    // Pass _all_ files, hide none.    if(QUERY(tilde) && QUERY(.files)) /* This is quite a lot faster */    return dir;       return Array.filter(dir, dir_filter_function);   }         mapping putting = ([]);    - void done_with_put( array(object) id ) + void done_with_put( array(object|string) id_arr )   {   // perror("Done with put.\n"); -  id[0]->close(); -  id[1]->set_blocking(); -  if (putting[id[1]] && (putting[id[1]] != 0x7fffffff)) { +  object to; +  object from; +  object id; +  string oldf; +  +  [to, from, id, oldf] = id_arr; +  +  to->close(); +  from->set_blocking(); +  m_delete(putting, from); +  +  if (putting[from] && (putting[from] != 0x7fffffff)) {    // Truncated! -  id[1]->write("400 Bad Request - Expected more data.\r\n" -  "Content-Length: 0\r\n\r\n"); +  id->send_result(http_low_answer(400, +  "<h2>Bad Request - " +  "Expected more data.</h2>"));    } else { -  id[1]->write("HTTP/1.0 200 Transfer Complete.\r\n" -  "Content-Length: 0\r\n\r\n"); +  id->send_result(http_low_answer(200, "<h2>Transfer Complete.</h2>"));    } -  id[1]->close(); -  m_delete(putting, id[1]); -  destruct(id[0]); -  destruct(id[1]); +    }    - void got_put_data( array (object) id, string data ) + void got_put_data( array (object|string) id_arr, string data )   {   // perror(strlen(data)+" .. "); -  +  +  object to; +  object from; +  object id; +  string oldf; +  +  [to, from, id, oldf] = id_arr; +     // Truncate at end. -  data = data[..putting[id[1]]]; +  data = data[..putting[from]];    -  int bytes = id[0]->write( data ); +  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>")); +  return; +  } +  +  int bytes = to->write( data );    if (bytes < sizeof(data)) {    // Out of disk! -  id[0]->close(); -  id[1]->set_blocking(); -  id[1]->write("HTTP/1.0 413 Disk full.\r\n" -  "Content-Length: 0\r\n\r\n"); -  id[1]->close(); -  m_delete(putting, id[1]); -  destruct(id[0]); -  destruct(id[1]); +  to->close(); +  from->set_blocking(); +  m_delete(putting, from); +  id->send_result(http_low_answer(413, "<h2>Disk full.</h2>")); +  return;    } else { -  if (putting[id[1]] != 0x7fffffff) { -  putting[id[1]] -= bytes; +  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>")); +  return;    } -  if(putting[id[1]] <= 0) { -  putting[id[1]] = 0; // Paranoia -  done_with_put( id ); +  if (putting[from] != 0x7fffffff) { +  putting[from] -= bytes;    } -  +  if(putting[from] <= 0) { +  putting[from] = 0; // Paranoia +  done_with_put( id_arr );    }    } -  + }      int _file_size(string X,object id)   {    array fs;    if(!id->pragma["no-cache"]&&(fs=cache_lookup("stat_cache",(X))))    {    id->misc->stat = fs[0];    return fs[0]?fs[0][ST_SIZE]:-1;    }    if(fs = file_stat(X))
Roxen.git/server/modules/filesystems/filesystem.pike:496:    id->misc->error_code = 405;    TRACE_LEAVE("PUT disallowed");    return 0;    }       if(QUERY(check_auth) && (!id->auth || !id->auth[0])) {    TRACE_LEAVE("PUT: Permission denied");    return http_auth_required("foo",    "<h1>Permission to 'PUT' files denied</h1>");    } +     puts++;    -  + #ifdef QUOTA_DEBUG +  report_debug("Checking quota.\n"); + #endif /* QUOTA_DEBUG */ +  if (id->misc->quota_obj && +  !id->misc->quota_obj->check_quota(oldf, id->misc->len)) { +  errors++; +  report_warning("Creation of " + f + " failed. Out of quota.\n"); +  TRACE_LEAVE("PUT: Out of quota."); +  return http_low_answer(413, "<h2>Out of quota.</h2>"); +  } +     object privs;      // #ifndef THREADS // Ouch. This is is _needed_. Well well...    if (((int)id->misc->uid) && ((int)id->misc->gid)) {    // NB: Root-access is prevented.    privs=Privs("Saving file", (int)id->misc->uid, (int)id->misc->gid );    }   // #endif       if (QUERY(no_symlinks) && (contains_symlinks(path, oldf))) {
Roxen.git/server/modules/filesystems/filesystem.pike:520:    report_error("Creation of " + f + " failed. Permission denied.\n");    TRACE_LEAVE("PUT: Contains symlinks. Permission denied");    return http_low_answer(403, "<h2>Permission denied.</h2>");    }       TRACE_ENTER("PUT: Accepted", 0);       rm( f );    mkdirhier( f );    +  if (id->misc->quota_obj) { + #ifdef QUOTA_DEBUG +  report_debug("Checking if the file already exists.\n"); + #endif /* QUOTA_DEBUG */ +  if (size > 0) { + #ifdef QUOTA_DEBUG +  report_debug("Deallocating " + size + "bytes.\n"); + #endif /* QUOTA_DEBUG */ +  id->misc->quota_obj->deallocate(oldf, size); +  } +  if (size) { + #ifdef QUOTA_DEBUG +  report_debug("Deleting old file.\n"); + #endif /* QUOTA_DEBUG */ +  rm(f); +  } +  } +     /* Clear the stat-cache for this file */    if (stat_cache) {    cache_set("stat_cache", f, 0);    }       object to = open(f, "wct");       privs = 0;       if(!to)    {    id->misc->error_code = 403;    TRACE_LEAVE("PUT: Open failed");    TRACE_LEAVE("Failure");    return 0;    }       // FIXME: Race-condition.    chmod(f, 0666 & ~(id->misc->umask || 022));    -  putting[id->my_fd]=id->misc->len; +  putting[id->my_fd] = id->misc->len;    if(id->data && strlen(id->data))    { -  +  // FIXME: What if sizeof(id->data) > id->misc->len ? +  if (id->misc->len > 0) {    putting[id->my_fd] -= strlen(id->data); -  to->write( id->data ); +     } -  +  int bytes = to->write( id->data ); +  if (id->misc->quota_obj) { + #ifdef QUOTA_DEBUG +  report_debug("Allocating " + bytes + "bytes.\n"); + #endif /* QUOTA_DEBUG */ +  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 quota.</h2>"); +  } +  } +  }    if(!putting[id->my_fd]) {    TRACE_LEAVE("PUT: Just a string");    TRACE_LEAVE("Put: Success");    return http_string_answer("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->my_fd->set_id( ({ to, id->my_fd, id, oldf }) );    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 http_pipe_in_progress();    break;       case "CHMOD":    // Change permission of a file.       if(!QUERY(put))
Roxen.git/server/modules/filesystems/filesystem.pike:621:    TRACE_LEAVE("Failure");    return 0;    }    TRACE_LEAVE("CHMOD: Success");    TRACE_LEAVE("Success");    return http_string_answer("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)");    return 0;    }    if(!QUERY(delete) && size != -1)    {    id->misc->error_code = 405;    TRACE_LEAVE("MV disallowed (DELE disabled, can't overwrite file)");
Roxen.git/server/modules/filesystems/filesystem.pike:706:    TRACE_LEAVE("Failure");    return 0;    }    TRACE_LEAVE("MV: Success");    TRACE_LEAVE("Success");    return http_string_answer("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)");    return 0;    }    if(size != -1)    {    id->misc->error_code = 404;    TRACE_LEAVE("MOVE failed (no such file)");
Roxen.git/server/modules/filesystems/filesystem.pike:849:       if(!rm(f))    {    privs = 0;    id->misc->error_code = 405;    TRACE_LEAVE("DELETE: Failed");    return 0;    }    privs = 0;    deletes++; +  +  if (id->misc->quota_obj) { +  id->misc->quota_obj->deallocate(oldf, size); +  } +     TRACE_LEAVE("DELETE: Success");    return http_low_answer(200,(f+" DELETED from the server"));       default:    TRACE_LEAVE("Not supported");    return 0;    }    report_error("Not reached..\n");    TRACE_LEAVE("Not reached");    return 0;   }      string query_name()   {    return sprintf("<i>%s</i> mounted on <i>%s</i>", query("searchpath"),    query("mountpoint"));   }