b655bf | 2004-06-30 | Martin Stjernholm | |
|
57f45e | 1996-11-27 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
57f45e | 1996-11-27 | Per Hedbor | |
|
f6d62d | 1997-03-26 | Per Hedbor | |
|
190901 | 1998-02-24 | Henrik Grubbström (Grubba) | | inherit "module";
inherit "socket";
|
c0132a | 2007-05-09 | Henrik Grubbström (Grubba) | | constant cvs_version= "$Id: filesystem.pike,v 1.156 2007/05/09 16:35:34 grubba Exp $";
|
190901 | 1998-02-24 | Henrik Grubbström (Grubba) | | constant thread_safe=1;
|
6682b9 | 1997-08-31 | Peter Bortas | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | #include <module.h>
|
48fa36 | 1997-04-05 | Per Hedbor | | #include <roxen.h>
|
14179b | 1997-01-29 | Per Hedbor | | #include <stat.h>
|
c5e096 | 1999-10-04 | Per Hedbor | | #include <request_trace.h>
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
79ca87 | 2000-11-24 | Per Hedbor | |
#define LOCALE(X,Y) _DEF_LOCALE("mod_filesystem",X,Y)
|
ac69b5 | 1999-12-28 | Martin Nilsson | | #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
|
f53aae | 2004-05-13 | Martin Stjernholm | | #if constant(System.normalize_path)
#define NORMALIZE_PATH(X) System.normalize_path(X)
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | #else /* !constant(system.normalize_path) */
#define NORMALIZE_PATH(X) (X)
#endif /* constant(system.normalize_path) */
|
c5e096 | 1999-10-04 | Per Hedbor | | constant module_type = MODULE_LOCATION;
|
f2e348 | 2001-05-20 | Martin Nilsson | | LocaleString module_name = LOCALE(51,"File systems: Normal File system");
|
f0d694 | 2001-01-29 | Per Hedbor | | LocaleString module_doc =
|
de9ca8 | 2000-11-27 | Per Hedbor | | LOCALE(2,"This is the basic file system module that makes it possible "
|
79ca87 | 2000-11-24 | Per Hedbor | | "to mount a directory structure in the virtual file system of "
"your site.");
|
c5e096 | 1999-10-04 | Per Hedbor | | constant module_unique = 0;
|
639611 | 1997-02-14 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | int redirects, accesses, errors, dirlists;
|
6cec00 | 1998-05-14 | David Hedbor | | int puts, deletes, mkdirs, moves, chmods;
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
1358d5 | 1999-05-06 | Henrik Grubbström (Grubba) | | static mapping http_low_answer(int errno, string data, string|void desc)
{
|
7f5966 | 2000-05-16 | Henrik Grubbström (Grubba) | | mapping res = Roxen.http_low_answer(errno, data);
|
1358d5 | 1999-05-06 | Henrik Grubbström (Grubba) | |
if (desc) {
res->rettext = desc;
}
return res;
}
|
f53aae | 2004-05-13 | Martin Stjernholm | |
static mapping(string:mixed) errno_to_status (int err, int(0..1) create,
RequestID id)
{
switch (err) {
case System.ENOENT:
if (!create) {
SIMPLE_TRACE_LEAVE ("File not found");
id->misc->error_code = Protocols.HTTP.HTTP_NOT_FOUND;
return 0;
}
case System.ENOTDIR:
TRACE_LEAVE(sprintf("%s: Missing intermediate.", id->method));
id->misc->error_code = Protocols.HTTP.HTTP_CONFLICT;
return 0;
case System.ENOSPC:
SIMPLE_TRACE_LEAVE("%s: Insufficient space", id->method);
return Roxen.http_status (Protocols.HTTP.DAV_STORAGE_FULL);
case System.EPERM:
TRACE_LEAVE(sprintf("%s: Permission denied", id->method));
return Roxen.http_status(Protocols.HTTP.HTTP_FORBIDDEN,
"Permission denied.");
case System.EEXIST:
TRACE_LEAVE(sprintf("%s failed. Directory name already exists. ",
id->method));
return Roxen.http_method_not_allowed("GET, HEAD",
"Collection already exists.");
#if constant(System.ENAMETOOLONG)
case System.ENAMETOOLONG:
SIMPLE_TRACE_LEAVE ("Path too long");
return Roxen.http_status (Protocols.HTTP.HTTP_URI_TOO_LONG);
#endif
default:
SIMPLE_TRACE_LEAVE ("Unexpected I/O error: %s", strerror (err));
return Roxen.http_status (Protocols.HTTP.HTTP_INTERNAL_ERR,
"Unexpected I/O error: %s",
strerror (err));
}
}
|
b1fca0 | 1996-11-12 | Per Hedbor | | static int do_stat = 1;
string status()
{
|
de9ca8 | 2000-11-27 | Per Hedbor | | 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>"
|
cc5602 | 2002-07-01 | Anders Johansson | | :LOCALE(6,"No file accesses")+"<br>")+
|
ed540b | 2001-01-13 | Martin Nilsson | | (query("put")&&puts?"<b>"+LOCALE(7,"PUTs")+"</b>: "+puts+"<br>":"")+
(query("put")&&mkdirs?"<b>"+LOCALE(8,"MKDIRs")+"</b>: "+mkdirs+"<br>":"")+
(query("put")&&query("delete")&&moves?
|
de9ca8 | 2000-11-27 | Per Hedbor | | "<b>"+LOCALE(9,"Moved files")+"</b>: "+moves+"<br>":"")+
|
ed540b | 2001-01-13 | Martin Nilsson | | (query("put")&&chmods?"<b>"+LOCALE(10,"CHMODs")+"</b>: "+chmods+"<br>":"")+
(query("delete")&&deletes?"<b>"+LOCALE(11,"Deletes")+"</b>: "+deletes+"<br>":"")+
|
de9ca8 | 2000-11-27 | Per Hedbor | | (errors?"<b>"+LOCALE(12,"Permission denied")+"</b>: "+errors
+" ("+LOCALE(13,"not counting .htaccess")+")<br>":"")+
(dirlists?"<b>"+LOCALE(14,"Directories")+"</b>:"+dirlists+"<br>":"");
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
void create()
{
|
b1e867 | 2001-08-01 | Per Hedbor | | defvar("mountpoint", "/", LOCALE(15,"Mount point"),
TYPE_LOCATION|VAR_INITIAL|VAR_NO_DEFAULT,
|
de9ca8 | 2000-11-27 | Per Hedbor | | LOCALE(16,"Where the module will be mounted in the site's virtual "
|
79ca87 | 2000-11-24 | Per Hedbor | | "file system."));
|
b1e867 | 2001-08-01 | Per Hedbor | | defvar("searchpath", "NONE", LOCALE(17,"Search path"),
TYPE_DIR|VAR_INITIAL|VAR_NO_DEFAULT,
|
de9ca8 | 2000-11-27 | Per Hedbor | | LOCALE(18,"The directory that contains the files."));
|
79ca87 | 2000-11-24 | Per Hedbor | |
|
de9ca8 | 2000-11-27 | Per Hedbor | | defvar(".files", 0, LOCALE(19,"Show hidden files"), TYPE_FLAG|VAR_MORE,
LOCALE(20,"If set, hidden files, ie files that begin with a '.', "
|
79ca87 | 2000-11-24 | Per Hedbor | | "will be shown in directory listings." ));
|
de9ca8 | 2000-11-27 | Per Hedbor | | defvar("dir", 1, LOCALE(21,"Enable directory listings per default"),
|
79ca87 | 2000-11-24 | Per Hedbor | | TYPE_FLAG|VAR_MORE,
|
de9ca8 | 2000-11-27 | Per Hedbor | | LOCALE(22,"If set, it will be possible to get a directory listings "
|
79ca87 | 2000-11-24 | Per Hedbor | | "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"));
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
c4908f | 2000-05-06 | Martin Nilsson | | defvar("nobrowse", ({ ".www_not_browsable", ".nodiraccess" }),
|
de9ca8 | 2000-11-27 | Per Hedbor | | LOCALE(23,"List prevention files"), TYPE_STRING_LIST|VAR_MORE,
LOCALE(24,"All directories containing any of these files will not be "
|
79ca87 | 2000-11-24 | Per Hedbor | | "browsable."));
|
c4908f | 2000-05-06 | Martin Nilsson | |
|
11ad7e | 2006-12-13 | Henrik Grubbström (Grubba) | | defvar("no-parse", 0, LOCALE(0, "Raw files"), TYPE_FLAG|VAR_MORE,
LOCALE(0, "If set files from this filesystem will be returned "
"without any further processing. This disables eg RXML "
"parsing of files."));
|
c4908f | 2000-05-06 | Martin Nilsson | |
|
de9ca8 | 2000-11-27 | Per Hedbor | | defvar("tilde", 0, LOCALE(25,"Show backup files"), TYPE_FLAG|VAR_MORE,
LOCALE(26,"If set, files ending with '~', '#' or '.bak' will "+
|
79ca87 | 2000-11-24 | Per Hedbor | | "be shown in directory listings"));
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
de9ca8 | 2000-11-27 | Per Hedbor | | 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 "
|
79ca87 | 2000-11-24 | Per Hedbor | | "method PUT, or through FTP."));
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
de9ca8 | 2000-11-27 | Per Hedbor | | 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 "
|
79ca87 | 2000-11-24 | Per Hedbor | | "method DELETE, or through FTP."));
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
de9ca8 | 2000-11-27 | Per Hedbor | | defvar("check_auth", 1, LOCALE(31,"Require authentication for modification"),
|
b1fca0 | 1996-11-12 | Per Hedbor | | TYPE_FLAG,
|
de9ca8 | 2000-11-27 | Per Hedbor | | LOCALE(32,"Only allow users authenticated by a authentication module "
|
79ca87 | 2000-11-24 | Per Hedbor | | "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."));
|
14179b | 1997-01-29 | Per Hedbor | |
|
de9ca8 | 2000-11-27 | Per Hedbor | | defvar("stat_cache", 0, LOCALE(33,"Cache the results of stat(2)"),
|
79ca87 | 2000-11-24 | Per Hedbor | | TYPE_FLAG|VAR_MORE,
|
de9ca8 | 2000-11-27 | Per Hedbor | | LOCALE(34,"A performace option that can speed up retrieval of files "
|
79ca87 | 2000-11-24 | Per Hedbor | | "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."));
|
527dc3 | 2001-09-21 | Per Hedbor | | defvar("access_as_user", 0, LOCALE(35,"Access files as the logged in user"),
|
9b9f70 | 1997-08-12 | Per Hedbor | | TYPE_FLAG|VAR_MORE,
|
de9ca8 | 2000-11-27 | Per Hedbor | | LOCALE(36,"If set, the module will access files as the authenticated "
|
79ca87 | 2000-11-24 | Per Hedbor | | "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."));
|
527dc3 | 2001-09-21 | Per Hedbor | | defvar("access_as_user_db",
Variable.UserDBChoice( " all", VAR_MORE,
|
80c5ae | 2001-09-27 | Martin Nilsson | | LOCALE(53,"Authentication database to use"),
LOCALE(54,"The User database module to use "
|
527dc3 | 2001-09-21 | Per Hedbor | | "when authenticating users for the "
"access file as the logged in user "
"feature."),
my_configuration()));
defvar( "access_as_user_throw", 0,
|
80c5ae | 2001-09-27 | Martin Nilsson | | LOCALE(55,"Access files as the logged in user forces login"),
|
527dc3 | 2001-09-21 | Per Hedbor | | TYPE_FLAG|VAR_MORE,
|
80c5ae | 2001-09-27 | Martin Nilsson | | LOCALE(56,"If true, a user will have to be logged in to access files in "
|
527dc3 | 2001-09-21 | Per Hedbor | | "this filesystem") );
|
de9ca8 | 2000-11-27 | Per Hedbor | | defvar("no_symlinks", 0, LOCALE(37,"Forbid access to symlinks"),
|
9b9f70 | 1997-08-12 | Per Hedbor | | TYPE_FLAG|VAR_MORE,
|
de9ca8 | 2000-11-27 | Per Hedbor | | LOCALE(38,"It set, the file system will not follow symbolic links. "
|
79ca87 | 2000-11-24 | Per Hedbor | | "This option can lower performace by a lot." ));
|
de9ca8 | 2000-11-27 | Per Hedbor | | defvar("charset", "iso-8859-1", LOCALE(39,"File contents charset"),
|
79ca87 | 2000-11-24 | Per Hedbor | | TYPE_STRING,
|
de9ca8 | 2000-11-27 | Per Hedbor | | LOCALE(40,"The charset of the contents of the files on this file "
|
79ca87 | 2000-11-24 | Per Hedbor | | "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 "
"processing the file."));
|
de9ca8 | 2000-11-27 | Per Hedbor | | defvar("path_encoding", "iso-8859-1", LOCALE(41,"Filename charset"),
|
79ca87 | 2000-11-24 | Per Hedbor | | TYPE_STRING,
|
de9ca8 | 2000-11-27 | Per Hedbor | | LOCALE(42,"The charset of the file names of the files on this file "
|
79ca87 | 2000-11-24 | Per Hedbor | | "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."));
|
de9ca8 | 2000-11-27 | Per Hedbor | | defvar("internal_files", ({}), LOCALE(43,"Internal files"), TYPE_STRING_LIST,
LOCALE(44,"A list of glob patterns that matches files which should be "
|
79ca87 | 2000-11-24 | Per Hedbor | | "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><insert></tt> and <tt><use></tt>."));
|
54b480 | 2000-03-07 | Martin Stjernholm | | }
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | string path, mountpoint, charset, path_encoding, normalized_path;
|
a2f3c7 | 2000-08-13 | Per Hedbor | | int stat_cache, dotfiles, access_as_user, no_symlinks, tilde;
array(string) internal_files;
|
527dc3 | 2001-09-21 | Per Hedbor | | UserDB access_as_user_db;
int access_as_user_throw;
|
b1fca0 | 1996-11-12 | Per Hedbor | | void start()
{
|
ed540b | 2001-01-13 | Martin Nilsson | | tilde = query("tilde");
charset = query("charset");
path_encoding = query("path_encoding");
no_symlinks = query("no_symlinks");
access_as_user = query("access_as_user");
|
527dc3 | 2001-09-21 | Per Hedbor | | access_as_user_throw = query("access_as_user_throw");
access_as_user_db =
my_configuration()->find_user_database( query("access_as_user_db") );
|
ed540b | 2001-01-13 | Martin Nilsson | | dotfiles = query(".files");
path = query("searchpath");
mountpoint = query("mountpoint");
stat_cache = query("stat_cache");
internal_files = query("internal_files");
|
527dc3 | 2001-09-21 | Per Hedbor | |
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | #if constant(system.normalize_path)
if (catch {
if ((<'/','\\'>)[path[-1]]) {
normalized_path = system.normalize_path(path + ".");
} else {
normalized_path = system.normalize_path(path);
}
#ifdef __NT__
normalized_path += "\\";
#else /* !__NT__ */
normalized_path += "/";
#endif /* __NT__ */
}) {
|
191ff3 | 2001-08-24 | Per Hedbor | | report_error(LOCALE(1, "Path verification of %s failed.\n"), mountpoint);
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | normalized_path = path;
}
#else /* !constant(system.normalize_path) */
normalized_path = path;
#endif /* constant(system.normalize_path) */
|
ed540b | 2001-01-13 | Martin Nilsson | | FILESYSTEM_WERR("Online at "+query("mountpoint")+" (path="+path+")");
|
8d10df | 2000-01-06 | Martin Stjernholm | | cache_expire("stat_cache");
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
string query_location()
{
|
a2f3c7 | 2000-08-13 | Per Hedbor | | return mountpoint;
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
54b480 | 2000-03-07 | Martin Stjernholm | | #define FILTER_INTERNAL_FILE(f, id) \
|
a2f3c7 | 2000-08-13 | Per Hedbor | | (!id->misc->internal_get && sizeof (filter (internal_files, glob, (f/"/")[-1])))
|
54b480 | 2000-03-07 | Martin Stjernholm | |
|
4bc95b | 2001-09-11 | Per Hedbor | | #define SETUID(X) \
|
31eeb5 | 2001-12-21 | Henrik Grubbström (Grubba) | | if( access_as_user && !id->misc->internal_get) \
|
4bc95b | 2001-09-11 | Per Hedbor | | { \
|
527dc3 | 2001-09-21 | Per Hedbor | | User uid = id->conf->authenticate( id,access_as_user_db ); \
if( access_as_user_throw && !uid ) \
return id->conf->authenticate_throw( id, "User",access_as_user_db);\
if( uid && uid->uid() ) \
privs=Privs(X, uid->uid(), uid->gid() ); \
}
|
4dea32 | 2001-12-21 | Henrik Grubbström (Grubba) | | #define SETUID_TRACE(X,LEVELS) \
|
31eeb5 | 2001-12-21 | Henrik Grubbström (Grubba) | | if( access_as_user && !id->misc->internal_get) \
|
4dea32 | 2001-12-21 | Henrik Grubbström (Grubba) | | { \
User uid = id->conf->authenticate( id,access_as_user_db ); \
if( access_as_user_throw && !uid ) { \
int levels = (LEVELS); \
while(levels--) TRACE_LEAVE(""); \
TRACE_LEAVE(X ": Auth required."); \
return id->conf->authenticate_throw( id, "User",access_as_user_db);\
} \
if( uid && uid->uid() ) \
privs=Privs(X, uid->uid(), uid->gid() ); \
}
|
527dc3 | 2001-09-21 | Per Hedbor | | #define SETUID_NT(X) \
|
31eeb5 | 2001-12-21 | Henrik Grubbström (Grubba) | | if( access_as_user && !id->misc->internal_get ) \
|
527dc3 | 2001-09-21 | Per Hedbor | | { \
User uid = id->conf->authenticate( id,access_as_user_db ); \
|
4bc95b | 2001-09-11 | Per Hedbor | | if( uid && uid->uid() ) \
privs=Privs(X, uid->uid(), uid->gid() ); \
}
|
54b480 | 2000-03-07 | Martin Stjernholm | | mixed stat_file( string f, RequestID id )
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
1f4a6c | 2000-08-28 | Per Hedbor | | Stat fs;
|
54b480 | 2000-03-07 | Martin Stjernholm | |
|
cdf053 | 2000-06-23 | Martin Stjernholm | | FILESYSTEM_WERR("stat_file for \""+f+"\"" +
(id->misc->internal_get ? " (internal)" : ""));
|
54b480 | 2000-03-07 | Martin Stjernholm | |
|
2c0a3e | 2001-08-13 | Per Hedbor | | f = path+f;
|
ae4620 | 2001-06-27 | Per Hedbor | | if (FILTER_INTERNAL_FILE (f, id))
return 0;
|
54b480 | 2000-03-07 | Martin Stjernholm | |
|
64c51c | 1997-10-11 | Henrik Grubbström (Grubba) | | if(stat_cache && !id->pragma["no-cache"] &&
|
2c0a3e | 2001-08-13 | Per Hedbor | | (fs=cache_lookup("stat_cache",f)))
|
1b8f6b | 1998-02-24 | Per Hedbor | | return fs[0];
object privs;
|
527dc3 | 2001-09-21 | Per Hedbor | | SETUID_NT("Statting file");
|
8afc81 | 1998-02-04 | Per Hedbor | |
|
ec0dab | 2000-04-03 | Per Hedbor | |
|
2c0a3e | 2001-08-13 | Per Hedbor | | fs = file_stat(decode_path(f));
|
64c51c | 1997-10-11 | Henrik Grubbström (Grubba) | | privs = 0;
|
a2f3c7 | 2000-08-13 | Per Hedbor | | if(!stat_cache) return fs;
|
2c0a3e | 2001-08-13 | Per Hedbor | | cache_set("stat_cache", f, ({fs}));
|
14179b | 1997-01-29 | Per Hedbor | | return fs;
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | string decode_path( string p )
{
if( path_encoding != "iso-8859-1" )
p = Locale.Charset.encoder( path_encoding )->feed( p )->drain();
#ifndef __NT__
if( String.width( p ) != 8 )
p = string_to_utf8( p );
#else
while( strlen(p) && p[-1] == '/' )
p = p[..strlen(p)-2];
#endif
return p;
}
string real_path(string f, RequestID id)
{
f = path + f;
if (FILTER_INTERNAL_FILE(f, id)) return 0;
catch {
f = NORMALIZE_PATH(decode_path(f));
if (has_prefix(f, normalized_path) ||
#ifdef __NT__
(f+"\\" == normalized_path)
#else /* !__NT__ */
(f+"/" == normalized_path)
#endif /* __NT__ */
) {
return f;
}
};
return 0;
}
|
54b480 | 2000-03-07 | Martin Stjernholm | | string real_file( string f, RequestID id )
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | if(stat_file( f, id )) {
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | return real_path(f, id);
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | }
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
699fa7 | 2004-05-06 | Henrik Grubbström (Grubba) | |
mapping(string:mixed) lock_file(string path, DAVLock lock, RequestID id)
{
if (!query("put")) return 0;
|
9040d5 | 2004-05-15 | Henrik Grubbström (Grubba) | | if (query("check_auth") && (!id->conf->authenticate( id )) ) {
TRACE_LEAVE("LOCK: Permission denied");
|
699fa7 | 2004-05-06 | Henrik Grubbström (Grubba) | | return
|
5c2778 | 2004-05-12 | Martin Stjernholm | |
|
699fa7 | 2004-05-06 | Henrik Grubbström (Grubba) | | Roxen.http_auth_required("foo",
|
fafdea | 2005-12-13 | Anders Johansson | | "<h1>Permission to 'LOCK' files denied</h1>",
id);
|
699fa7 | 2004-05-06 | Henrik Grubbström (Grubba) | | }
register_lock(path, lock, id);
return 0;
}
|
204529 | 2004-05-14 | Martin Stjernholm | | mapping(string:mixed) unlock_file(string path, DAVLock lock, RequestID|int(0..0) id)
{
if (!query("put")) return 0;
|
9040d5 | 2004-05-15 | Henrik Grubbström (Grubba) | | if (id && query("check_auth") && (!id->conf->authenticate( id )) ) {
TRACE_LEAVE("UNLOCK: Permission denied");
|
204529 | 2004-05-14 | Martin Stjernholm | | return
Roxen.http_auth_required("foo",
|
fafdea | 2005-12-13 | Anders Johansson | | "<h1>Permission to 'UNLOCK' files denied</h1>",
id);
|
204529 | 2004-05-14 | Martin Stjernholm | | }
unregister_lock(path, lock, id);
return 0;
}
|
54b480 | 2000-03-07 | Martin Stjernholm | | int dir_filter_function(string f, RequestID id)
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
a2f3c7 | 2000-08-13 | Per Hedbor | | if(f[0]=='.' && !dotfiles) return 0;
if(!tilde && Roxen.backup_extension(f)) return 0;
|
b1fca0 | 1996-11-12 | Per Hedbor | | return 1;
}
|
c4908f | 2000-05-06 | Martin Nilsson | | array(string) list_lock_files() {
|
ed540b | 2001-01-13 | Martin Nilsson | | return query("nobrowse");
|
c4908f | 2000-05-06 | Martin Nilsson | | }
|
556b83 | 2004-05-13 | Henrik Grubbström (Grubba) | | static mapping(string:mixed)|int(0..1) write_access(string path,
int(0..1) recursive,
RequestID id)
{
SIMPLE_TRACE_ENTER(this, "write_access(%O, %O, %O)\n", path, recursive, id);
if(query("check_auth") && (!id->conf->authenticate( id ) ) ) {
SIMPLE_TRACE_LEAVE("%s: Authentication required.", id->method);
return
Roxen.http_auth_required("foo",
sprintf("<h1>Permission to '%s' denied</h1>",
|
fafdea | 2005-12-13 | Anders Johansson | | id->method), id);
|
556b83 | 2004-05-13 | Henrik Grubbström (Grubba) | | }
TRACE_LEAVE("Fall back to the default write access checks.");
return ::write_access(path, recursive, id);
}
|
54b480 | 2000-03-07 | Martin Stjernholm | | array find_dir( string f, RequestID id )
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
array dir;
|
cdf053 | 2000-06-23 | Martin Stjernholm | | FILESYSTEM_WERR("find_dir for \""+f+"\"" +
(id->misc->internal_get ? " (internal)" : ""));
|
54b480 | 2000-03-07 | Martin Stjernholm | |
|
0216e2 | 1997-08-12 | Henrik Grubbström (Grubba) | | object privs;
|
527dc3 | 2001-09-21 | Per Hedbor | | SETUID_NT("Read dir");
|
0216e2 | 1997-08-12 | Henrik Grubbström (Grubba) | |
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | if (catch {
f = NORMALIZE_PATH(decode_path(path + f));
} || !(dir = get_dir(f))) {
|
64c51c | 1997-10-11 | Henrik Grubbström (Grubba) | | privs = 0;
|
b1fca0 | 1996-11-12 | Per Hedbor | | return 0;
|
64c51c | 1997-10-11 | Henrik Grubbström (Grubba) | | }
|
0216e2 | 1997-08-12 | Henrik Grubbström (Grubba) | | privs = 0;
|
ed540b | 2001-01-13 | Martin Nilsson | | if(!query("dir"))
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
c4908f | 2000-05-06 | Martin Nilsson | | if(! has_value(dir, ".www_browsable"))
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
errors++;
return 0;
}
|
ed540b | 2001-01-13 | Martin Nilsson | | if( sizeof(dir & query("nobrowse")) )
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
errors++;
return 0;
}
dirlists++;
|
a2f3c7 | 2000-08-13 | Per Hedbor | | if(tilde && dotfiles &&
(!sizeof( internal_files ) || id->misc->internal_get))
|
b1fca0 | 1996-11-12 | Per Hedbor | | return dir;
|
3bf15e | 2000-03-08 | Martin Stjernholm | | dir = Array.filter(dir, dir_filter_function, id);
if (!id->misc->internal_get)
|
a2f3c7 | 2000-08-13 | Per Hedbor | | foreach (internal_files, string globstr)
|
3bf15e | 2000-03-08 | Martin Stjernholm | | dir -= glob (globstr, dir);
return dir;
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
39edd9 | 2004-05-05 | Martin Stjernholm | | void recursive_rm(string real_dir, string virt_dir,
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | int(0..1) check_status_needed, RequestID id)
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | {
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | SIMPLE_TRACE_ENTER(this, "Deleting all files in directory %O...", real_dir);
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | foreach(get_dir(real_dir) || ({}), string fname) {
string real_fname = combine_path(real_dir, fname);
|
39edd9 | 2004-05-05 | Martin Stjernholm | | string virt_fname = virt_dir + "/" + fname;
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | |
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | Stat stat = file_stat(real_fname);
if (!stat) {
|
39edd9 | 2004-05-05 | Martin Stjernholm | | id->set_status_for_path(virt_fname, 404);
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("File not found.");
continue;
}
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | SIMPLE_TRACE_ENTER(this, "Deleting %s %O.",
stat->isdir?"directory":"file", real_fname);
int(0..1)|mapping sub_status;
if (check_status_needed &&
mappingp(sub_status = write_access(virt_fname, 1, id))) {
id->set_status_for_path(virt_fname, sub_status->error);
TRACE_LEAVE("Write access denied.");
continue;
}
|
0c8b5b | 2003-12-23 | Henrik Grubbström (Grubba) | | if (stat->isdir) {
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | recursive_rm(real_fname, virt_fname, sub_status, id);
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | }
if (stat_cache) {
cache_set("stat_cache", real_fname, 0);
}
if (!rm(real_fname)) {
#if constant(System.EEXIST)
if (errno() != System.EEXIST)
#endif
{
|
39edd9 | 2004-05-05 | Martin Stjernholm | | id->set_status_for_path(virt_fname, 403);
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("Deletion failed.");
}
#if constant(System.EEXIST)
else {
TRACE_LEAVE("Directory not empty.");
}
#endif
} else {
deletes++;
if (id->misc->quota_obj && stat->isreg()) {
|
39edd9 | 2004-05-05 | Martin Stjernholm | | id->misc->quota_obj->deallocate(virt_fname,
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | stat->size());
}
TRACE_LEAVE("Ok.");
}
}
TRACE_LEAVE("Done.");
}
|
b1fca0 | 1996-11-12 | Per Hedbor | |
mapping putting = ([]);
|
0c8b5b | 2003-12-23 | Henrik Grubbström (Grubba) | | void done_with_put( array(object|string|int) id_arr )
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
b3ef2d | 1999-12-18 | Martin Nilsson | |
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | object to;
object from;
object id;
string oldf;
|
0c8b5b | 2003-12-23 | Henrik Grubbström (Grubba) | | int size;
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | |
|
0c8b5b | 2003-12-23 | Henrik Grubbström (Grubba) | | [to, from, id, oldf, size] = id_arr;
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | |
|
ac69b5 | 1999-12-28 | Martin Nilsson | | FILESYSTEM_WERR(sprintf("done_with_put(%O)\n"
"from: %O\n",
id_arr, mkmapping(indices(from), values(from))));
|
1358d5 | 1999-05-06 | Henrik Grubbström (Grubba) | |
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | to->close();
from->set_blocking();
m_delete(putting, from);
if (putting[from] && (putting[from] != 0x7fffffff)) {
|
016316 | 1999-04-21 | Henrik Grubbström (Grubba) | |
|
5c2778 | 2004-05-12 | Martin Stjernholm | | id->send_result(Roxen.http_status(400,
"Bad Request - "
"Expected more data."));
|
016316 | 1999-04-21 | Henrik Grubbström (Grubba) | | } else {
|
5c2778 | 2004-05-12 | Martin Stjernholm | | id->send_result(Roxen.http_status((size < 0)?201:200,
"Transfer Complete."));
|
016316 | 1999-04-21 | Henrik Grubbström (Grubba) | | }
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
0c8b5b | 2003-12-23 | Henrik Grubbström (Grubba) | | void got_put_data( array(object|string|int) id_arr, string data )
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
b3ef2d | 1999-12-18 | Martin Nilsson | |
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | |
object to;
object from;
object id;
string oldf;
|
0c8b5b | 2003-12-23 | Henrik Grubbström (Grubba) | | int size;
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | |
|
0c8b5b | 2003-12-23 | Henrik Grubbström (Grubba) | | [to, from, id, oldf, size] = id_arr;
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | |
|
016316 | 1999-04-21 | Henrik Grubbström (Grubba) | |
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | 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);
|
f53aae | 2004-05-13 | Martin Stjernholm | | id->send_result(Roxen.http_status(507, "Out of disk quota."));
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | return;
}
|
016316 | 1999-04-21 | Henrik Grubbström (Grubba) | |
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | int bytes = to->write( data );
|
016316 | 1999-04-21 | Henrik Grubbström (Grubba) | | if (bytes < sizeof(data)) {
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | to->close();
from->set_blocking();
m_delete(putting, from);
|
f53aae | 2004-05-13 | Martin Stjernholm | | id->send_result(Roxen.http_status(507, "Disk full."));
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | return;
|
016316 | 1999-04-21 | Henrik Grubbström (Grubba) | | } else {
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | if (id->misc->quota_obj &&
!id->misc->quota_obj->allocate(oldf, bytes)) {
to->close();
from->set_blocking();
m_delete(putting, from);
|
f53aae | 2004-05-13 | Martin Stjernholm | | id->send_result(Roxen.http_status(507, "Out of disk quota."));
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | return;
}
if (putting[from] != 0x7fffffff) {
putting[from] -= bytes;
|
32b4ba | 1999-04-21 | Henrik Grubbström (Grubba) | | }
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | if(putting[from] <= 0) {
putting[from] = 0;
done_with_put( id_arr );
|
016316 | 1999-04-21 | Henrik Grubbström (Grubba) | | }
}
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
c9e036 | 2000-08-28 | Johan Sundström | | int _file_size(string X, RequestID id)
|
14179b | 1997-01-29 | Per Hedbor | | {
|
1f4a6c | 2000-08-28 | Per Hedbor | | Stat fs;
|
a2f3c7 | 2000-08-13 | Per Hedbor | | if( stat_cache )
|
14179b | 1997-01-29 | Per Hedbor | | {
|
c9e036 | 2000-08-28 | Johan Sundström | | array(Stat) cached_fs;
if(!id->pragma["no-cache"] &&
(cached_fs = cache_lookup("stat_cache", X)))
|
a2f3c7 | 2000-08-13 | Per Hedbor | | {
|
c9e036 | 2000-08-28 | Johan Sundström | | id->misc->stat = cached_fs[0];
return cached_fs[0] ? cached_fs[0][ST_SIZE] : -1;
|
a2f3c7 | 2000-08-13 | Per Hedbor | | }
|
14179b | 1997-01-29 | Per Hedbor | | }
|
ec0dab | 2000-04-03 | Per Hedbor | | if(fs = file_stat(decode_path(X)))
|
14179b | 1997-01-29 | Per Hedbor | | {
id->misc->stat = fs;
|
a2f3c7 | 2000-08-13 | Per Hedbor | | if( stat_cache ) cache_set("stat_cache",(X),({fs}));
|
14179b | 1997-01-29 | Per Hedbor | | return fs[ST_SIZE];
|
a2f3c7 | 2000-08-13 | Per Hedbor | | } else if( stat_cache )
|
1b8f6b | 1998-02-24 | Per Hedbor | | cache_set("stat_cache",(X),({0}));
|
14179b | 1997-01-29 | Per Hedbor | | return -1;
}
|
afb158 | 1997-07-06 | Henrik Grubbström (Grubba) | | int contains_symlinks(string root, string path)
{
|
f81922 | 2004-05-08 | Henrik Grubbström (Grubba) | | foreach(path/"/" - ({ "" }), path) {
|
afb158 | 1997-07-06 | Henrik Grubbström (Grubba) | | root += "/" + path;
|
f81922 | 2004-05-08 | Henrik Grubbström (Grubba) | | Stat rr;
|
1f4a6c | 2000-08-28 | Per Hedbor | | if (rr = file_stat(decode_path(root), 1)) {
if (rr[1] == -3) {
|
afb158 | 1997-07-06 | Henrik Grubbström (Grubba) | | return(1);
}
} else {
return(0);
}
}
return(0);
}
|
9aea23 | 2005-10-19 | Henrik Grubbström (Grubba) | |
string safe_chmod(string path, int mask)
{
return describe_error(catch {
chmod(path, mask);
return 0;
});
}
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | mapping make_collection(string coll, RequestID id)
{
TRACE_ENTER(sprintf("make_collection(%O)", coll), this_object());
string norm_f = real_path(coll, id);
if (!norm_f) {
TRACE_LEAVE(sprintf("%s: Bad path", id->method));
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(405, "Bad path.");
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | }
if(!query("put"))
{
TRACE_LEAVE(sprintf("%s disallowed (since PUT is disallowed)",
id->method));
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(405, "Disallowed.");
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | }
int size = _file_size(norm_f, id);
if (size != -1) {
TRACE_LEAVE(sprintf("%s failed. Directory name already exists. ",
id->method));
if (id->method == "MKCOL") {
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(405,
"Collection already exists.");
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | }
return 0;
}
|
699fa7 | 2004-05-06 | Henrik Grubbström (Grubba) | |
mapping(string:mixed) ret = write_access(coll, 0, id) ||
write_access(combine_path(coll, ".."), 0, id);
if (ret) return ret;
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | mkdirs++;
object privs;
SETUID_TRACE("Creating directory/collection", 0);
if (query("no_symlinks") && (contains_symlinks(path, coll))) {
privs = 0;
errors++;
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | report_error(LOCALE(46,"Creation of %O failed. Permission denied.\n"),
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | coll);
TRACE_LEAVE(sprintf("%s: Contains symlinks. Permission denied",
id->method));
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(403, "Permission denied.");
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | }
int code = mkdir(norm_f);
int err_code = errno();
TRACE_ENTER(sprintf("%s: Accepted", id->method), 0);
if (code) {
|
9aea23 | 2005-10-19 | Henrik Grubbström (Grubba) | | string msg = safe_chmod(norm_f, 0777 & ~(id->misc->umask || 022));
privs = 0;
if (msg) {
TRACE_LEAVE(sprintf("%s: chmod %O failed: %s", id->method, norm_f, msg));
} else {
|
c0132a | 2007-05-09 | Henrik Grubbström (Grubba) | | TRACE_LEAVE(sprintf("%s: chmod ok", id->method));
|
9aea23 | 2005-10-19 | Henrik Grubbström (Grubba) | | }
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | TRACE_LEAVE(sprintf("%s: Success", id->method));
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(201, "Created");
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | }
|
9aea23 | 2005-10-19 | Henrik Grubbström (Grubba) | | privs = 0;
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | |
TRACE_LEAVE(sprintf("%s: Failed", id->method));
|
f53aae | 2004-05-13 | Martin Stjernholm | | return errno_to_status (err_code, 1, id);
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | }
|
756d3c | 2005-07-19 | Henrik Grubbström (Grubba) | | class CacheCallback(string f, int orig_size)
{
|
5347f5 | 2005-09-02 | Martin Stjernholm | | int(0..1) `()(RequestID id, mixed key)
|
756d3c | 2005-07-19 | Henrik Grubbström (Grubba) | | {
return _file_size(f, id) == orig_size;
}
}
|
54b480 | 2000-03-07 | Martin Stjernholm | | mixed find_file( string f, RequestID id )
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | | TRACE_ENTER("find_file(\""+f+"\")", 0);
|
b1fca0 | 1996-11-12 | Per Hedbor | | object o;
int size;
string tmp;
|
afb158 | 1997-07-06 | Henrik Grubbström (Grubba) | | string oldf = f;
|
7aa898 | 2004-04-20 | Martin Stjernholm | | object privs;
int code;
|
01128d | 1998-04-27 | Henrik Grubbström (Grubba) | |
|
cdf053 | 2000-06-23 | Martin Stjernholm | | FILESYSTEM_WERR("Request for \""+f+"\"" +
(id->misc->internal_get ? " (internal)" : ""));
|
01128d | 1998-04-27 | Henrik Grubbström (Grubba) | |
|
a2f3c7 | 2000-08-13 | Per Hedbor | |
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | #define URI combine_path(mountpoint + "/" + oldf, ".")
|
1358d5 | 1999-05-06 | Henrik Grubbström (Grubba) | |
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | string norm_f;
catch {
f = norm_f = NORMALIZE_PATH(f = decode_path(path + f));
#if constant(system.normalize_path)
|
bd2508 | 2001-08-16 | Henrik Grubbström (Grubba) | | if (!has_prefix(norm_f, normalized_path) &&
|
b0f68e | 2001-08-16 | Henrik Grubbström (Grubba) | | #ifdef __NT__
|
328277 | 2001-08-16 | Henrik Grubbström (Grubba) | | (norm_f+"\\" != normalized_path)
|
b0f68e | 2001-08-16 | Henrik Grubbström (Grubba) | | #else /* !__NT__ */
(norm_f+"/" != normalized_path)
#endif /* __NT__ */
) {
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | errors++;
|
191ff3 | 2001-08-24 | Per Hedbor | | report_error(LOCALE(52, "Path verification of %O failed:\n"
|
b0f68e | 2001-08-16 | Henrik Grubbström (Grubba) | | "%O is not a prefix of %O\n"
), oldf, normalized_path, norm_f);
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("");
TRACE_LEAVE("Permission denied.");
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(403, "File exists, but access forbidden "
"by user");
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | }
|
b0f68e | 2001-08-16 | Henrik Grubbström (Grubba) | |
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | id->not_query = mountpoint + replace(norm_f[sizeof(normalized_path)..],
"\\", "/");
|
bd2508 | 2001-08-16 | Henrik Grubbström (Grubba) | | if (sizeof(oldf) && (oldf[-1] == '/')) {
id->not_query += "/";
}
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | #endif /* constant(system.normalize_path) */
};
|
a2f3c7 | 2000-08-13 | Per Hedbor | |
|
f81922 | 2004-05-08 | Henrik Grubbström (Grubba) | |
|
a2f3c7 | 2000-08-13 | Per Hedbor | | size = _file_size( f, id );
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
9e759c | 2001-09-11 | Henrik Grubbström (Grubba) | | FILESYSTEM_WERR(sprintf("_file_size(%O, %O) ==> %d\n", f, id, size));
|
465eb6 | 1998-08-26 | Henrik Grubbström (Grubba) | |
|
b04ec8 | 2000-01-31 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | switch(id->method)
{
case "GET":
case "HEAD":
case "POST":
|
b04ec8 | 2000-01-31 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | switch(-size)
{
case 1:
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | | case 3:
case 4:
TRACE_LEAVE("No file");
|
b1fca0 | 1996-11-12 | Per Hedbor | | return 0;
case 2:
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("Is directory");
|
b1fca0 | 1996-11-12 | Per Hedbor | | return -1;
default:
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | if( oldf[ -1 ] == '/' ||
!norm_f) {
|
b04ec8 | 2000-01-31 | Per Hedbor | | return 0;
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | }
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
a2f3c7 | 2000-08-13 | Per Hedbor | | if(!id->misc->internal_get)
{
if (!dotfiles
|
0fb1b1 | 2000-03-26 | Martin Stjernholm | | && sizeof (tmp = (id->not_query/"/")[-1])
|
a2f3c7 | 2000-08-13 | Per Hedbor | | && tmp[0] == '.')
{
|
54b480 | 2000-03-07 | Martin Stjernholm | | TRACE_LEAVE("Is .-file");
return 0;
}
|
a2f3c7 | 2000-08-13 | Per Hedbor | | if (FILTER_INTERNAL_FILE (f, id))
{
|
54b480 | 2000-03-07 | Martin Stjernholm | | TRACE_LEAVE ("Is internal file");
return 0;
}
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | | }
|
5e5fd6 | 2000-03-07 | Martin Stjernholm | |
TRACE_ENTER("Opening file \"" + f + "\"", 0);
|
4dea32 | 2001-12-21 | Henrik Grubbström (Grubba) | | SETUID_TRACE("Open file", 1);
|
a2f3c7 | 2000-08-13 | Per Hedbor | |
o = Stdio.File( );
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | if(!o->open(norm_f, "r" )) o = 0;
|
2e7c23 | 1997-06-10 | Henrik Grubbström (Grubba) | | privs = 0;
|
a2f3c7 | 2000-08-13 | Per Hedbor | | if(!o || (no_symlinks && (contains_symlinks(path, oldf))))
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
errors++;
|
de9ca8 | 2000-11-27 | Per Hedbor | | report_error(LOCALE(45,"Open of %s failed. Permission denied.\n"),f);
|
b04ec8 | 2000-01-31 | Per Hedbor | |
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("");
TRACE_LEAVE("Permission denied.");
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(403, "File exists, but access forbidden "
"by user");
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
756d3c | 2005-07-19 | Henrik Grubbström (Grubba) | |
id->misc->_cachecallbacks += ({ CacheCallback(f, size) });
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | id->realfile = norm_f;
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("");
|
b1fca0 | 1996-11-12 | Per Hedbor | | accesses++;
|
a2f3c7 | 2000-08-13 | Per Hedbor | | if( charset != "iso-8859-1" )
{
|
6b3cb1 | 2002-07-23 | Martin Stjernholm | | if( id->set_output_charset )
id->set_output_charset( charset, 2 );
|
a2f3c7 | 2000-08-13 | Per Hedbor | | id->misc->input_charset = charset;
}
|
11ad7e | 2006-12-13 | Henrik Grubbström (Grubba) | | if (query("no-parse")) {
|
63c20f | 2006-12-14 | Henrik Grubbström (Grubba) | | TRACE_ENTER("Content-type mapping module", id->conf->types_module);
array(string) tmp = id->conf->type_from_filename(norm_f, 1);
|
11ad7e | 2006-12-13 | Henrik Grubbström (Grubba) | | TRACE_LEAVE(tmp?sprintf("Returned type %s %s.", tmp[0], tmp[1]||"")
: "Missing type.");
TRACE_LEAVE("No parse return");
return Roxen.http_file_answer(o, tmp[0]) + ([ "encoding":tmp[1] ]);
}
TRACE_LEAVE("Normal return");
|
b1fca0 | 1996-11-12 | Per Hedbor | | return o;
}
break;
|
b04ec8 | 2000-01-31 | Per Hedbor | |
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | case "MKCOL":
|
534e29 | 2004-05-10 | Martin Stjernholm | | if (id->request_headers["content-type"] || sizeof (id->data)) {
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | |
|
534e29 | 2004-05-10 | Martin Stjernholm | | SIMPLE_TRACE_LEAVE ("MKCOL failed since the request has content.");
return Roxen.http_status(415, "Unsupported media type.");
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | }
|
8764c0 | 1998-05-01 | Henrik Grubbström (Grubba) | | case "MKDIR":
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | #if 1
return make_collection(oldf, id);
#else /* !1 */
|
ed540b | 2001-01-13 | Martin Nilsson | | if(!query("put"))
|
8764c0 | 1998-05-01 | Henrik Grubbström (Grubba) | | {
id->misc->error_code = 405;
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | TRACE_LEAVE(sprintf("%s disallowed (since PUT is disallowed)",
id->method));
|
8764c0 | 1998-05-01 | Henrik Grubbström (Grubba) | | return 0;
|
b04ec8 | 2000-01-31 | Per Hedbor | | }
|
8764c0 | 1998-05-01 | Henrik Grubbström (Grubba) | |
|
54b480 | 2000-03-07 | Martin Stjernholm | | if (FILTER_INTERNAL_FILE (f, id)) {
id->misc->error_code = 405;
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | TRACE_LEAVE(sprintf("%s disallowed (since the dir name matches internal file glob)",
id->method));
|
54b480 | 2000-03-07 | Martin Stjernholm | | return 0;
}
|
9e759c | 2001-09-11 | Henrik Grubbström (Grubba) | | if (size != -1) {
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | TRACE_LEAVE(sprintf("%s failed. Directory name already exists. ",
id->method));
if (id->method == "MKCOL") {
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(405,
"Collection already exists.");
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | }
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | return 0;
}
|
556b83 | 2004-05-13 | Henrik Grubbström (Grubba) | | if (mapping(string:mixed) ret = write_access(oldf, 0, id)) {
TRACE_LEAVE("MKCOL: Write access denied.");
return ret;
|
8764c0 | 1998-05-01 | Henrik Grubbström (Grubba) | | }
|
556b83 | 2004-05-13 | Henrik Grubbström (Grubba) | |
|
8764c0 | 1998-05-01 | Henrik Grubbström (Grubba) | | mkdirs++;
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | SETUID_TRACE("Creating directory/collection", 0);
|
8764c0 | 1998-05-01 | Henrik Grubbström (Grubba) | |
|
ed540b | 2001-01-13 | Martin Nilsson | | if (query("no_symlinks") && (contains_symlinks(path, oldf))) {
|
8764c0 | 1998-05-01 | Henrik Grubbström (Grubba) | | privs = 0;
errors++;
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | report_error(LOCALE(46,"Creation of %O failed. Permission denied.\n"),
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | oldf);
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | TRACE_LEAVE(sprintf("%s: Contains symlinks. Permission denied",
id->method));
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(403, "Permission denied.");
|
8764c0 | 1998-05-01 | Henrik Grubbström (Grubba) | | }
|
7aa898 | 2004-04-20 | Martin Stjernholm | | code = mkdir(f);
|
0c8b5b | 2003-12-23 | Henrik Grubbström (Grubba) | | int err_code = errno();
|
5e5fd6 | 2000-03-07 | Martin Stjernholm | |
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | TRACE_ENTER(sprintf("%s: Accepted", id->method), 0);
|
5e5fd6 | 2000-03-07 | Martin Stjernholm | |
|
8764c0 | 1998-05-01 | Henrik Grubbström (Grubba) | | if (code) {
|
9aea23 | 2005-10-19 | Henrik Grubbström (Grubba) | | string msg = safe_chmod(f, 0777 & ~(id->misc->umask || 022));
privs = 0;
if (msg) {
TRACE_LEAVE(sprintf("%s: chmod %O failed: %s", id->method, f, msg));
} else {
TRACE_LEAVE(sprintf("%s: Success", id->method));
}
|
8764c0 | 1998-05-01 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("Success");
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | if (id->method == "MKCOL") {
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(201, "Created");
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | }
|
f4b8bc | 2000-05-01 | Martin Nilsson | | return Roxen.http_string_answer("Ok");
|
8764c0 | 1998-05-01 | Henrik Grubbström (Grubba) | | } else {
|
9aea23 | 2005-10-19 | Henrik Grubbström (Grubba) | | privs = 0;
|
f81922 | 2004-05-08 | Henrik Grubbström (Grubba) | | SIMPLE_TRACE_LEAVE("%s: Failed (errcode:%d)", id->method, errcode);
|
8764c0 | 1998-05-01 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("Failure");
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | if (id->method == "MKCOL") {
|
0c8b5b | 2003-12-23 | Henrik Grubbström (Grubba) | | if (err_code ==
#if constant(system.ENOENT)
system.ENOENT
#elif constant(System.ENOENT)
System.ENOENT
#else
2
#endif
) {
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(409, "Missing intermediate.");
|
0c8b5b | 2003-12-23 | Henrik Grubbström (Grubba) | | } else {
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(507, "Failed.");
|
0c8b5b | 2003-12-23 | Henrik Grubbström (Grubba) | | }
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | }
|
8764c0 | 1998-05-01 | Henrik Grubbström (Grubba) | | return 0;
}
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | #endif /* 1 */
|
8764c0 | 1998-05-01 | Henrik Grubbström (Grubba) | | break;
|
b1fca0 | 1996-11-12 | Per Hedbor | | case "PUT":
|
ed540b | 2001-01-13 | Martin Nilsson | | if(!query("put"))
|
f6d62d | 1997-03-26 | Per Hedbor | | {
id->misc->error_code = 405;
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("PUT disallowed");
|
b1fca0 | 1996-11-12 | Per Hedbor | | return 0;
|
b04ec8 | 2000-01-31 | Per Hedbor | | }
|
f6d62d | 1997-03-26 | Per Hedbor | |
|
54b480 | 2000-03-07 | Martin Stjernholm | | if (FILTER_INTERNAL_FILE (f, id)) {
id->misc->error_code = 405;
TRACE_LEAVE("PUT of internal file is disallowed");
return 0;
}
|
f81922 | 2004-05-08 | Henrik Grubbström (Grubba) | | if (mapping(string:mixed) ret = write_access(oldf, 0, id)) {
|
699fa7 | 2004-05-06 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("PUT: Locked");
return ret;
}
|
b1fca0 | 1996-11-12 | Per Hedbor | | puts++;
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | |
|
ac69b5 | 1999-12-28 | Martin Nilsson | | QUOTA_WERR("Checking quota.\n");
|
1358d5 | 1999-05-06 | Henrik Grubbström (Grubba) | | if (id->misc->quota_obj && (id->misc->len > 0) &&
|
3f286a | 2000-08-23 | Per Hedbor | | !id->misc->quota_obj->check_quota(URI, id->misc->len)) {
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | errors++;
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | report_warning(LOCALE(47,"Creation of %O failed. Out of quota.\n"),f);
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("PUT: Out of quota.");
|
f53aae | 2004-05-13 | Martin Stjernholm | | return Roxen.http_status(507, "Out of disk quota.");
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | }
|
b04ec8 | 2000-01-31 | Per Hedbor | |
|
ed540b | 2001-01-13 | Martin Nilsson | | if (query("no_symlinks") && (contains_symlinks(path, oldf))) {
|
afb158 | 1997-07-06 | Henrik Grubbström (Grubba) | | errors++;
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | report_error(LOCALE(46,"Creation of %O failed. Permission denied.\n"),f);
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("PUT: Contains symlinks. Permission denied");
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(403, "Permission denied.");
|
afb158 | 1997-07-06 | Henrik Grubbström (Grubba) | | }
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | SETUID_TRACE("Saving file", 0);
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | rm(f);
mkdirhier(f);
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | |
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | if (id->misc->quota_obj) {
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | QUOTA_WERR("Checking if the file already existed.");
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | if (size > 0) {
|
ac69b5 | 1999-12-28 | Martin Nilsson | | QUOTA_WERR("Deallocating " + size + "bytes.");
|
3f286a | 2000-08-23 | Per Hedbor | | id->misc->quota_obj->deallocate(URI, size);
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | }
}
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | object to = open(f, "wct");
|
f53aae | 2004-05-13 | Martin Stjernholm | | int err = errno();
|
5e5fd6 | 2000-03-07 | Martin Stjernholm | |
TRACE_ENTER("PUT: Accepted", 0);
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | |
if (stat_cache) {
cache_set("stat_cache", f, 0);
}
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(!to)
|
f6d62d | 1997-03-26 | Per Hedbor | | {
|
859357 | 2005-08-25 | Henrik Grubbström (Grubba) | | privs = 0;
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("PUT: Open failed");
|
f53aae | 2004-05-13 | Martin Stjernholm | | return errno_to_status (err, 1, id);
|
f6d62d | 1997-03-26 | Per Hedbor | | }
|
016316 | 1999-04-21 | Henrik Grubbström (Grubba) | |
|
9aea23 | 2005-10-19 | Henrik Grubbström (Grubba) | | string msg = safe_chmod(f, 0666 & ~(id->misc->umask || 022));
|
859357 | 2005-08-25 | Henrik Grubbström (Grubba) | | privs = 0;
|
016316 | 1999-04-21 | Henrik Grubbström (Grubba) | |
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | putting[id->my_fd] = id->misc->len;
|
b1fca0 | 1996-11-12 | Per Hedbor | | if(id->data && strlen(id->data))
{
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | |
if (id->misc->len > 0) {
putting[id->my_fd] -= strlen(id->data);
}
int bytes = to->write( id->data );
if (id->misc->quota_obj) {
|
ac69b5 | 1999-12-28 | Martin Nilsson | | QUOTA_WERR("Allocating " + bytes + "bytes.");
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | if (!id->misc->quota_obj->allocate(f, bytes)) {
TRACE_LEAVE("PUT: A string");
TRACE_LEAVE("PUT: Out of quota");
|
f53aae | 2004-05-13 | Martin Stjernholm | | return Roxen.http_status(507, "Out of disk quota.");
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | }
}
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | | if(!putting[id->my_fd]) {
TRACE_LEAVE("PUT: Just a string");
TRACE_LEAVE("Put: Success");
|
0c8b5b | 2003-12-23 | Henrik Grubbström (Grubba) | | if (size < 0) {
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(201, "Created.");
|
0c8b5b | 2003-12-23 | Henrik Grubbström (Grubba) | | } else {
|
5c2778 | 2004-05-12 | Martin Stjernholm | |
|
0c8b5b | 2003-12-23 | Henrik Grubbström (Grubba) | | return Roxen.http_string_answer("Ok");
}
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | | }
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
a2f346 | 1997-06-12 | Henrik Grubbström (Grubba) | | if(id->clientprot == "HTTP/1.1") {
|
b1fca0 | 1996-11-12 | Per Hedbor | | id->my_fd->write("HTTP/1.1 100 Continue\r\n");
|
a2f346 | 1997-06-12 | Henrik Grubbström (Grubba) | | }
|
0c8b5b | 2003-12-23 | Henrik Grubbström (Grubba) | | id->my_fd->set_id( ({ to, id->my_fd, id, URI, size }) );
|
b1fca0 | 1996-11-12 | Per Hedbor | | id->my_fd->set_nonblocking(got_put_data, 0, done_with_put);
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("PUT: Pipe in progress");
TRACE_LEAVE("PUT: Success so far");
|
f4b8bc | 2000-05-01 | Martin Nilsson | | return Roxen.http_pipe_in_progress();
|
b1fca0 | 1996-11-12 | Per Hedbor | | break;
|
f53aae | 2004-05-13 | Martin Stjernholm | | case "CHMOD": {
|
b04ec8 | 2000-01-31 | Per Hedbor | |
|
1358d5 | 1999-05-06 | Henrik Grubbström (Grubba) | |
|
b04ec8 | 2000-01-31 | Per Hedbor | |
|
ed540b | 2001-01-13 | Martin Nilsson | | if(!query("put"))
|
6cec00 | 1998-05-14 | David Hedbor | | {
id->misc->error_code = 405;
TRACE_LEAVE("CHMOD disallowed (since PUT is disallowed)");
return 0;
|
b04ec8 | 2000-01-31 | Per Hedbor | | }
|
6cec00 | 1998-05-14 | David Hedbor | |
|
54b480 | 2000-03-07 | Martin Stjernholm | | if (FILTER_INTERNAL_FILE (f, id)) {
id->misc->error_code = 405;
TRACE_LEAVE("CHMOD of internal file is disallowed");
return 0;
}
|
f81922 | 2004-05-08 | Henrik Grubbström (Grubba) | | if (mapping(string:mixed) ret = write_access(oldf, 0, id)) {
|
534e29 | 2004-05-10 | Martin Stjernholm | | TRACE_LEAVE("CHMOD: Locked");
|
699fa7 | 2004-05-06 | Henrik Grubbström (Grubba) | | return ret;
}
|
b04ec8 | 2000-01-31 | Per Hedbor | |
|
4dea32 | 2001-12-21 | Henrik Grubbström (Grubba) | | SETUID_TRACE("CHMODing file", 0);
|
b04ec8 | 2000-01-31 | Per Hedbor | |
|
ed540b | 2001-01-13 | Martin Nilsson | | if (query("no_symlinks") && (contains_symlinks(path, oldf))) {
|
6cec00 | 1998-05-14 | David Hedbor | | privs = 0;
errors++;
TRACE_LEAVE("CHMOD: Contains symlinks. Permission denied");
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(403, "Permission denied.");
|
6cec00 | 1998-05-14 | David Hedbor | | }
|
9aea23 | 2005-10-19 | Henrik Grubbström (Grubba) | | string msg = safe_chmod(f, id->misc->mode & 0777);
|
f53aae | 2004-05-13 | Martin Stjernholm | | int err_code = errno();
|
5e5fd6 | 2000-03-07 | Martin Stjernholm | | privs = 0;
|
6cec00 | 1998-05-14 | David Hedbor | | chmods++;
TRACE_ENTER("CHMOD: Accepted", 0);
if (stat_cache) {
cache_set("stat_cache", f, 0);
}
|
b04ec8 | 2000-01-31 | Per Hedbor | |
|
9aea23 | 2005-10-19 | Henrik Grubbström (Grubba) | | if(msg)
|
6cec00 | 1998-05-14 | David Hedbor | | {
|
9aea23 | 2005-10-19 | Henrik Grubbström (Grubba) | | TRACE_LEAVE(sprintf("CHMOD: Failure: %s", msg));
|
f53aae | 2004-05-13 | Martin Stjernholm | | return errno_to_status (err_code, 0, id);
|
6cec00 | 1998-05-14 | David Hedbor | | }
TRACE_LEAVE("CHMOD: Success");
TRACE_LEAVE("Success");
|
f4b8bc | 2000-05-01 | Martin Nilsson | | return Roxen.http_string_answer("Ok");
|
f53aae | 2004-05-13 | Martin Stjernholm | | }
|
b04ec8 | 2000-01-31 | Per Hedbor | |
|
f53aae | 2004-05-13 | Martin Stjernholm | | case "MV": {
|
b04ec8 | 2000-01-31 | Per Hedbor | |
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | |
|
ed540b | 2001-01-13 | Martin Nilsson | | if(!query("put"))
|
dba2b5 | 1998-05-14 | David Hedbor | | {
id->misc->error_code = 405;
TRACE_LEAVE("MV disallowed (since PUT is disallowed)");
return 0;
|
b04ec8 | 2000-01-31 | Per Hedbor | | }
|
ed540b | 2001-01-13 | Martin Nilsson | | if(!query("delete") && size != -1)
|
dba2b5 | 1998-05-14 | David Hedbor | | {
id->misc->error_code = 405;
TRACE_LEAVE("MV disallowed (DELE disabled, can't overwrite file)");
return 0;
}
|
f37e47 | 1998-05-14 | Henrik Grubbström (Grubba) | | if(size < -1)
|
dba2b5 | 1998-05-14 | David Hedbor | | {
id->misc->error_code = 405;
TRACE_LEAVE("MV: Cannot overwrite directory");
return 0;
}
string movefrom;
if(!id->misc->move_from ||
|
f81922 | 2004-05-08 | Henrik Grubbström (Grubba) | | !has_prefix(id->misc->move_from, mountpoint) ||
|
dba2b5 | 1998-05-14 | David Hedbor | | !(movefrom = id->conf->real_file(id->misc->move_from, id))) {
id->misc->error_code = 405;
errors++;
TRACE_LEAVE("MV: No source file");
return 0;
}
|
54b480 | 2000-03-07 | Martin Stjernholm | |
|
f81922 | 2004-05-08 | Henrik Grubbström (Grubba) | | string relative_from = id->misc->move_from[sizeof(mountpoint)..];
|
54b480 | 2000-03-07 | Martin Stjernholm | | 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;
}
|
ed540b | 2001-01-13 | Martin Nilsson | | if (query("no_symlinks") &&
|
f37e47 | 1998-05-14 | Henrik Grubbström (Grubba) | | ((contains_symlinks(path, oldf)) ||
(contains_symlinks(path, id->misc->move_from)))) {
|
dba2b5 | 1998-05-14 | David Hedbor | | errors++;
TRACE_LEAVE("MV: Contains symlinks. Permission denied");
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(403, "Permission denied.");
|
dba2b5 | 1998-05-14 | David Hedbor | | }
|
f81922 | 2004-05-08 | Henrik Grubbström (Grubba) | |
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);
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | code = mv(movefrom, f);
|
f53aae | 2004-05-13 | Martin Stjernholm | | int err_code = errno();
|
5e5fd6 | 2000-03-07 | Martin Stjernholm | | privs = 0;
moves++;
|
dba2b5 | 1998-05-14 | David Hedbor | | TRACE_ENTER("MV: Accepted", 0);
if (stat_cache) {
cache_set("stat_cache", movefrom, 0);
cache_set("stat_cache", f, 0);
}
if(!code)
{
TRACE_LEAVE("MV: Move failed");
|
f53aae | 2004-05-13 | Martin Stjernholm | | return errno_to_status (err_code, 1, id);
|
dba2b5 | 1998-05-14 | David Hedbor | | }
TRACE_LEAVE("MV: Success");
|
f37e47 | 1998-05-14 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("Success");
|
f4b8bc | 2000-05-01 | Martin Nilsson | | return Roxen.http_string_answer("Ok");
|
f53aae | 2004-05-13 | Martin Stjernholm | | }
|
de14f2 | 1998-10-19 | Wim Bonis | |
|
f53aae | 2004-05-13 | Martin Stjernholm | | case "MOVE": {
|
699fa7 | 2004-05-06 | Henrik Grubbström (Grubba) | |
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | |
|
b04ec8 | 2000-01-31 | Per Hedbor | |
|
ed540b | 2001-01-13 | Martin Nilsson | | if(!query("put"))
|
de14f2 | 1998-10-19 | Wim Bonis | | {
id->misc->error_code = 405;
TRACE_LEAVE("MOVE disallowed (since PUT is disallowed)");
return 0;
|
b04ec8 | 2000-01-31 | Per Hedbor | | }
|
38c7f9 | 2003-02-25 | Henrik Grubbström (Grubba) | | if(size == -1)
|
de14f2 | 1998-10-19 | Wim Bonis | | {
id->misc->error_code = 404;
TRACE_LEAVE("MOVE failed (no such file)");
return 0;
}
|
78b603 | 2004-05-10 | Henrik Grubbström (Grubba) | | string new_uri = id->misc["new-uri"] || "";
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | if (new_uri == "") {
|
de14f2 | 1998-10-19 | Wim Bonis | | id->misc->error_code = 405;
errors++;
TRACE_LEAVE("MOVE: No dest file");
return 0;
}
|
3a26d1 | 2000-12-29 | Henrik Grubbström (Grubba) | |
|
f81922 | 2004-05-08 | Henrik Grubbström (Grubba) | | if (!has_prefix(new_uri, mountpoint)) {
|
de14f2 | 1998-10-19 | Wim Bonis | | id->misc->error_code = 405;
TRACE_LEAVE("MOVE: Dest file on other filesystem.");
return(0);
}
|
f81922 | 2004-05-08 | Henrik Grubbström (Grubba) | | new_uri = new_uri[sizeof(mountpoint)..];
string moveto = path + "/" + new_uri;
|
de14f2 | 1998-10-19 | Wim Bonis | |
|
a23fa5 | 2004-05-13 | Henrik Grubbström (Grubba) | |
if (has_suffix(moveto, "/")) {
moveto = moveto[..sizeof(moveto)-2];
}
|
54b480 | 2000-03-07 | Martin Stjernholm | | 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;
}
|
ed540b | 2001-01-13 | Martin Nilsson | | if (query("no_symlinks") &&
|
de14f2 | 1998-10-19 | Wim Bonis | | ((contains_symlinks(path, f)) ||
(contains_symlinks(path, moveto)))) {
privs = 0;
errors++;
TRACE_LEAVE("MOVE: Contains symlinks. Permission denied");
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(403, "Permission denied.");
|
de14f2 | 1998-10-19 | Wim Bonis | | }
|
f81922 | 2004-05-08 | Henrik Grubbström (Grubba) | | if (mapping(string:mixed) ret =
write_access(new_uri, 0, id) ||
write_access(oldf, 0, id)) {
TRACE_LEAVE("MOVE: Locked");
return ret;
}
|
78b603 | 2004-05-10 | Henrik Grubbström (Grubba) | | size = _file_size(moveto,id);
|
f81922 | 2004-05-08 | Henrik Grubbström (Grubba) | | SETUID_TRACE("Moving file", 0);
|
78b603 | 2004-05-10 | Henrik Grubbström (Grubba) | | if (size != -1) {
|
aaed92 | 2004-05-13 | Martin Stjernholm | | int(0..1) overwrite =
!id->request_headers->overwrite ||
id->request_headers->overwrite == "T";
if (!overwrite) {
|
78b603 | 2004-05-10 | Henrik Grubbström (Grubba) | | privs = 0;
TRACE_LEAVE("MOVE disallowed (overwrite header:F).");
return Roxen.http_status(412);
}
if(!query("delete"))
{
privs = 0;
id->misc->error_code = 405;
TRACE_LEAVE("MOVE disallowed (DELE disabled)");
return 0;
}
|
aaed92 | 2004-05-13 | Martin Stjernholm | | if (overwrite || (size > -1)) {
|
8dbd1b | 2004-05-10 | Henrik Grubbström (Grubba) | | mapping(string:mixed) res =
|
534e29 | 2004-05-10 | Martin Stjernholm | | recurse_delete_files(new_uri, id);
|
5c2778 | 2004-05-12 | Martin Stjernholm | | if (res && (!sizeof (res) || res->error >= 300)) {
|
78b603 | 2004-05-10 | Henrik Grubbström (Grubba) | | privs = 0;
TRACE_LEAVE("MOVE: Recursive delete failed.");
|
5c2778 | 2004-05-12 | Martin Stjernholm | | if (sizeof (res))
set_status_for_path (new_uri, res->error, res->rettext);
return ([]);
|
78b603 | 2004-05-10 | Henrik Grubbström (Grubba) | | }
} else {
privs = 0;
TRACE_LEAVE("MOVE: Cannot overwrite directory");
return Roxen.http_status(412);
}
}
|
c7ec63 | 2001-08-15 | Henrik Grubbström (Grubba) | | code = mv(f, decode_path(moveto));
|
f53aae | 2004-05-13 | Martin Stjernholm | | int err_code = errno();
|
5e5fd6 | 2000-03-07 | Martin Stjernholm | | privs = 0;
|
de14f2 | 1998-10-19 | Wim Bonis | | TRACE_ENTER("MOVE: Accepted", 0);
moves++;
if (stat_cache) {
cache_set("stat_cache", moveto, 0);
cache_set("stat_cache", f, 0);
}
if(!code)
{
|
204529 | 2004-05-14 | Martin Stjernholm | | SIMPLE_TRACE_LEAVE("MOVE: Move failed (%s)", strerror (err_code));
|
f53aae | 2004-05-13 | Martin Stjernholm | | return errno_to_status (err_code, 1, id);
|
de14f2 | 1998-10-19 | Wim Bonis | | }
TRACE_LEAVE("MOVE: Success");
TRACE_LEAVE("Success");
|
78b603 | 2004-05-10 | Henrik Grubbström (Grubba) | | if (size != -1) return Roxen.http_status(204);
return Roxen.http_status(201);
|
f53aae | 2004-05-13 | Martin Stjernholm | | }
|
b04ec8 | 2000-01-31 | Per Hedbor | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | case "DELETE":
|
1f11d5 | 2003-12-29 | Henrik Grubbström (Grubba) | | if (size==-1) {
id->misc->error_code = 404;
TRACE_LEAVE("DELETE: Not found");
return 0;
}
|
0c8b5b | 2003-12-23 | Henrik Grubbström (Grubba) | | if(!query("delete"))
|
f6d62d | 1997-03-26 | Per Hedbor | | {
id->misc->error_code = 405;
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("DELETE: Disabled");
|
b1fca0 | 1996-11-12 | Per Hedbor | | return 0;
|
f6d62d | 1997-03-26 | Per Hedbor | | }
|
54b480 | 2000-03-07 | Martin Stjernholm | |
if (FILTER_INTERNAL_FILE (f, id)) {
id->misc->error_code = 405;
TRACE_LEAVE("DELETE of internal file is disallowed");
return 0;
}
|
ed540b | 2001-01-13 | Martin Nilsson | | if (query("no_symlinks") && (contains_symlinks(path, oldf))) {
|
afb158 | 1997-07-06 | Henrik Grubbström (Grubba) | | errors++;
|
de9ca8 | 2000-11-27 | Per Hedbor | | report_error(LOCALE(48,"Deletion of %s failed. Permission denied.\n"),f);
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("DELETE: Contains symlinks");
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(403, "Permission denied.");
|
afb158 | 1997-07-06 | Henrik Grubbström (Grubba) | | }
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | if ((size < 0) &&
|
0c8b5b | 2003-12-23 | Henrik Grubbström (Grubba) | | (String.trim_whites(id->request_headers->depth||"infinity") !=
"infinity")) {
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | |
TRACE_LEAVE(sprintf("DELETE: Bad depth header: %O.",
id->request_headers->depth));
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(400, "Unsupported depth.");
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | }
|
f6d62d | 1997-03-26 | Per Hedbor | |
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | if (size < 0) {
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | mapping|int(0..1) res;
if (mappingp(res = write_access(combine_path(oldf, "../"), 1, id)) ||
(res && mappingp(res = write_access(oldf, 1, id)))) {
SIMPLE_TRACE_LEAVE("DELETE: Recursive write access denied.");
|
8dbd1b | 2004-05-10 | Henrik Grubbström (Grubba) | | return res;
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | }
|
5c2778 | 2004-05-12 | Martin Stjernholm | | #if 0
|
eb73ee | 2003-06-26 | Anders Johansson | | report_notice(LOCALE(64,"DELETING the directory %s.\n"), f);
|
5c2778 | 2004-05-12 | Martin Stjernholm | | #endif
|
f6d62d | 1997-03-26 | Per Hedbor | |
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | accesses++;
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | |
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | SETUID_TRACE("Deleting directory", 0);
|
39edd9 | 2004-05-05 | Martin Stjernholm | | int start_ms_size = id->multi_status_size();
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | recursive_rm(f, query_location() + oldf, res, id);
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | |
|
f53aae | 2004-05-13 | Martin Stjernholm | | if (!rm(f) && errno() != System.ENOENT) {
|
39edd9 | 2004-05-05 | Martin Stjernholm | | if (id->multi_status_size() > start_ms_size) {
|
f53aae | 2004-05-13 | Martin Stjernholm | | if (errno() != System.EEXIST
#if constant (System.ENOTEMPTY)
&& errno() != System.ENOTEMPTY
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | #endif
|
f53aae | 2004-05-13 | Martin Stjernholm | | )
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | {
|
f53aae | 2004-05-13 | Martin Stjernholm | | return errno_to_status (errno(), 0, id);
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | }
} else {
|
f53aae | 2004-05-13 | Martin Stjernholm | | return errno_to_status (errno(), 0, id);
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | }
|
f53aae | 2004-05-13 | Martin Stjernholm | | if (id->multi_status_size() > start_ms_size) {
TRACE_LEAVE("DELETE: Partial failure.");
return ([]);
}
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | }
} else {
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | mapping|int(0..1) res;
if ((res = write_access(combine_path(oldf, "../"), 0, id)) ||
(res = write_access(oldf, 0, id))) {
SIMPLE_TRACE_LEAVE("DELETE: Write access denied.");
|
8dbd1b | 2004-05-10 | Henrik Grubbström (Grubba) | | return res;
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | }
|
5c2778 | 2004-05-12 | Martin Stjernholm | | #if 0
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | report_notice(LOCALE(49,"DELETING the file %s.\n"),f);
|
5c2778 | 2004-05-12 | Martin Stjernholm | | #endif
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | |
accesses++;
if (stat_cache) {
cache_set("stat_cache", f, 0);
}
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | SETUID_TRACE("Deleting file", 0);
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | if(!rm(f))
{
privs = 0;
id->misc->error_code = 405;
TRACE_LEAVE("DELETE: Failed");
return 0;
}
|
64c51c | 1997-10-11 | Henrik Grubbström (Grubba) | | privs = 0;
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | deletes++;
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | |
|
a4d1ad | 2003-06-11 | Henrik Grubbström (Grubba) | | if (id->misc->quota_obj && (size > 0)) {
id->misc->quota_obj->deallocate(oldf, size);
}
|
2f8308 | 1999-05-05 | Henrik Grubbström (Grubba) | | }
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("DELETE: Success");
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(204,(f+" DELETED from the server"));
|
b1fca0 | 1996-11-12 | Per Hedbor | |
default:
|
1f11d5 | 2003-12-29 | Henrik Grubbström (Grubba) | | id->misc->error_code = 501;
|
0e1476 | 2004-05-10 | Henrik Grubbström (Grubba) | | SIMPLE_TRACE_LEAVE("%s: Not supported", id->method);
|
b1fca0 | 1996-11-12 | Per Hedbor | | return 0;
}
|
8afb50 | 1998-04-15 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("Not reached");
|
b1fca0 | 1996-11-12 | Per Hedbor | | return 0;
}
|
f35f47 | 2004-05-10 | Henrik Grubbström (Grubba) | | mapping copy_file(string source, string dest, PropertyBehavior behavior,
Overwrite overwrite, RequestID id)
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | {
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | SIMPLE_TRACE_ENTER(this, "COPY: Copy %O to %O.", source, dest);
Stat source_st = stat_file(source, id);
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | if (!source_st) {
TRACE_LEAVE("COPY: Source doesn't exist.");
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(404, "File not found.");
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | }
if (!query("put")) {
TRACE_LEAVE("COPY: Put not allowed.");
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(405, "Not allowed.");
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | }
|
328441 | 2004-05-13 | Henrik Grubbström (Grubba) | | mapping|int(0..1) res = write_access(dest, 0, id) ||
write_access(combine_path(dest, "../"), 0, id);
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | if (mappingp(res)) return res;
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | string dest_path = path + dest;
catch { dest_path = decode_path(dest_path); };
|
f53aae | 2004-05-13 | Martin Stjernholm | | dest_path = NORMALIZE_PATH (dest_path);
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | if (query("no_symlinks") && (contains_symlinks(path, dest_path))) {
errors++;
|
496d16 | 2004-05-14 | Anders Johansson | | report_error(LOCALE(57,"Copy to %O failed. Permission denied.\n"),
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | dest);
TRACE_LEAVE("COPY: Contains symlinks. Permission denied");
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(403, "Permission denied.");
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | }
Stat dest_st = stat_file(dest, id);
if (dest_st) {
|
f53aae | 2004-05-13 | Martin Stjernholm | | SIMPLE_TRACE_ENTER (this, "COPY: Destination exists");
|
f35f47 | 2004-05-10 | Henrik Grubbström (Grubba) | | switch(overwrite) {
case NEVER_OVERWRITE:
|
f53aae | 2004-05-13 | Martin Stjernholm | | TRACE_LEAVE("");
TRACE_LEAVE("");
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(412, "Destination already exists.");
|
f35f47 | 2004-05-10 | Henrik Grubbström (Grubba) | | case DO_OVERWRITE:
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | if (!query("delete")) {
TRACE_LEAVE("COPY: Deletion not allowed.");
|
f53aae | 2004-05-13 | Martin Stjernholm | | TRACE_LEAVE("");
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(405, "Not allowed.");
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | }
object privs;
SETUID_TRACE("Deleting destination", 0);
if (dest_st->isdir) {
|
f53aae | 2004-05-13 | Martin Stjernholm | | int start_ms_size = id->multi_status_size();
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | recursive_rm(dest_path, mountpoint + dest, 1, id);
|
f53aae | 2004-05-13 | Martin Stjernholm | |
werror ("dest_path %O\n", dest_path);
if (!rm(dest_path) && errno() != System.ENOENT) {
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | privs = 0;
|
f53aae | 2004-05-13 | Martin Stjernholm | | if (id->multi_status_size() > start_ms_size) {
if (errno() != System.EEXIST
#if constant (System.ENOTEMPTY)
&& errno() != System.ENOTEMPTY
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | #endif
|
f53aae | 2004-05-13 | Martin Stjernholm | | )
{
TRACE_LEAVE("");
return errno_to_status (errno(), 0, id);
}
} else {
TRACE_LEAVE("");
return errno_to_status (errno(), 0, id);
}
if (id->multi_status_size() > start_ms_size) {
privs = 0;
TRACE_LEAVE("COPY: Partial failure in destination directory delete.");
TRACE_LEAVE("");
return ([]);
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | }
}
|
f53aae | 2004-05-13 | Martin Stjernholm | | SIMPLE_TRACE_LEAVE("COPY: Delete ok.");
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | } else if (source_st->isdir) {
if (!rm(dest_path)) {
privs = 0;
|
f53aae | 2004-05-13 | Martin Stjernholm | | if (errno() != System.ENOENT)
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | {
|
f53aae | 2004-05-13 | Martin Stjernholm | | mapping(string:mixed) status = errno_to_status (errno(), 0, id);
if (!status) status = (["error": id->misc->error_code]);
id->set_status_for_path(mountpoint + dest,
status->error, status->rettext);
TRACE_LEAVE("");
return ([]);
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | }
|
f53aae | 2004-05-13 | Martin Stjernholm | | SIMPLE_TRACE_LEAVE("COPY: File deletion failed (destination disappeared).");
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | } else {
SIMPLE_TRACE_LEAVE("COPY: File deletion ok.");
}
} else {
SIMPLE_TRACE_LEAVE("COPY: No need to perform deletion.");
}
privs = 0;
|
f35f47 | 2004-05-10 | Henrik Grubbström (Grubba) | | break;
case MAYBE_OVERWRITE:
if ((source_st->isreg != dest_st->isreg) ||
(source_st->isdir != dest_st->isdir)) {
TRACE_LEAVE("COPY: Resource types for source and destination differ.");
|
f53aae | 2004-05-13 | Martin Stjernholm | | TRACE_LEAVE("");
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(412, "Destination and source are different resource types.");
|
f35f47 | 2004-05-10 | Henrik Grubbström (Grubba) | | } else if (source_st->isdir) {
TRACE_LEAVE("Already done (both are directories).");
|
f53aae | 2004-05-13 | Martin Stjernholm | | TRACE_LEAVE("");
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(204, "Destination already existed.");
|
f35f47 | 2004-05-10 | Henrik Grubbström (Grubba) | | }
break;
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | }
}
|
f53aae | 2004-05-13 | Martin Stjernholm | |
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | if (source_st->isdir) {
mkdirs++;
object privs;
SETUID_TRACE("Creating directory/collection", 0);
int code = mkdir(dest_path);
int err_code = errno();
if (code) {
|
9aea23 | 2005-10-19 | Henrik Grubbström (Grubba) | | string msg = safe_chmod(dest_path, 0777 & ~(id->misc->umask || 022));
privs = 0;
if (msg) {
TRACE_LEAVE(sprintf("Chmod %O failed: %s", dest_path, msg));
} else {
TRACE_LEAVE("Success");
}
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(dest_st?204:201, "Created");
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | } else {
|
f53aae | 2004-05-13 | Martin Stjernholm | | return errno_to_status (err_code, 1, id);
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | }
|
f81922 | 2004-05-08 | Henrik Grubbström (Grubba) | | } else {
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | string source_path = path + source;
catch { source_path = decode_path(source_path); };
|
f53aae | 2004-05-13 | Martin Stjernholm | | source_path = NORMALIZE_PATH (source_path);
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | if (query("no_symlinks") && (contains_symlinks(path, source_path))) {
errors++;
|
496d16 | 2004-05-14 | Anders Johansson | | report_error(LOCALE(57,"Copy to %O failed. Permission denied.\n"),
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | dest);
TRACE_LEAVE("COPY: Contains symlinks. Permission denied");
|
5c2778 | 2004-05-12 | Martin Stjernholm | | return Roxen.http_status(403, "Permission denied.");
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | }
puts++;
QUOTA_WERR("Checking quota.\n");
if (id->misc->quota_obj && (id->misc->len > 0) &&
!id->misc->quota_obj->check_quota(mountpoint + dest,
source_st->size)) {
errors++;
report_warning(LOCALE(47,"Creation of %O failed. Out of quota.\n"),
dest_path);
TRACE_LEAVE("PUT: Out of quota.");
|
f53aae | 2004-05-13 | Martin Stjernholm | | return Roxen.http_status(507, "Out of disk quota.");
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | }
object source_file = open(source_path, "r");
if (!source_file) {
TRACE_LEAVE("Failed to open source file.");
return Roxen.http_status(404);
}
|
a23fa5 | 2004-05-13 | Henrik Grubbström (Grubba) | |
|
1e41c9 | 2004-05-13 | Henrik Grubbström (Grubba) | | if (has_suffix(dest_path, "/")) {
dest_path = dest_path[..sizeof(dest_path)-2];
}
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | object privs;
|
786696 | 2004-05-10 | Henrik Grubbström (Grubba) | | SETUID_TRACE("COPY: Copying file.", 0);
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | object dest_file = open(dest_path, "cwt");
privs = 0;
if (!dest_file) {
|
f53aae | 2004-05-13 | Martin Stjernholm | | return errno_to_status (errno(), 1, id);
|
40cae5 | 2004-05-09 | Henrik Grubbström (Grubba) | | }
int len = source_st->size;
while (len > 0) {
string buf = source_file->read((len > 4096)?4096:len);
if (buf && sizeof(buf)) {
int sub_len;
len -= (sub_len = sizeof(buf));
while (sub_len > 0) {
int written = dest_file->write(buf);
if ((sub_len -= written) > 0) {
if (!written) {
SIMPLE_TRACE_LEAVE("Write failed with errno %d",
dest_file->errno());
dest_file->close();
source_file->close();
return Roxen.http_status(Protocols.HTTP.DAV_STORAGE_FULL);
}
buf = buf[written..];
}
}
} else {
break;
}
}
if (len > 0) {
SIMPLE_TRACE_LEAVE("Read failed with %d bytes left.", len);
} else {
SIMPLE_TRACE_LEAVE("Copy complete.");
}
dest_file->close();
source_file->close();
return Roxen.http_status(dest_st?Protocols.HTTP.HTTP_NO_CONTENT:
Protocols.HTTP.HTTP_CREATED);
|
068134 | 2004-04-20 | Henrik Grubbström (Grubba) | | }
}
|
b1fca0 | 1996-11-12 | Per Hedbor | | string query_name()
{
|
daf00c | 2001-11-26 | Chris Jantzen | | if (sizeof(path) > 20) {
|
6fbcab | 2002-07-01 | Anders Johansson | | return sprintf((string)LOCALE(63,"%s from %s...%s"),
|
daf00c | 2001-11-26 | Chris Jantzen | | mountpoint, path[..7], path[sizeof(path)-8..]);
}
|
06225a | 2001-05-16 | Martin Nilsson | | return sprintf((string)LOCALE(50,"%s from %s"), mountpoint, path);
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|