93b5822001-05-09Stephen R. van den Berg // This is a roxen module which provides file upload and write capabilities. // Copyright (c) 2001, Stephen R. van den Berg, The Netherlands. // <srb@cuci.nl> // // This module is open source software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as published // by the Free Software Foundation; either version 2, or (at your option) any // later version. // #define _ok id->misc->defines[" _ok"]
70d4e52001-10-30Stephen R. van den Berg constant cvs_version =
04bf522001-12-03Anders Johansson  "$Id: writefile.pike,v 1.12 2001/12/03 13:03:17 anders Exp $";
93b5822001-05-09Stephen R. van den Berg constant thread_safe = 1; #include <module.h> #include <config.h> inherit "module"; // ---------------- Module registration stuff ---------------- constant module_type = MODULE_TAG; constant module_name = "Writefile"; constant module_doc = "This module provides the writefile RXML tags.<br>" "<p>Copyright &copy; 2001, by " "<a href='mailto:srb@cuci.nl'>Stephen R. van den Berg</a>, " "The Netherlands.</p>" "<p>This module is open source software; you can redistribute it and/or " "modify it under the terms of the GNU General Public License as published " "by the Free Software Foundation; either version 2, or (at your option) any " "later version.</p>"; void create() {
3bb8522001-10-30Stephen R. van den Berg  set_module_creator("Stephen R. van den Berg <srb@cuci.nl>");
93b5822001-05-09Stephen R. van den Berg  defvar ("onlysubdirs", 1, "Within tree only", TYPE_FLAG, "Setting this will force all specified chroots and filenames to be " "relative to the directory this tag is located in. " "It functions as an enforced dynamic chroot to constrain users in " "e.g. a user filesystem." ); }
70d4e52001-10-30Stephen R. van den Berg static string lastfile; string status() { return sprintf("Last file written: %s",lastfile||"NONE"); }
93b5822001-05-09Stephen R. van den Berg #define IS(arg) ((arg) && sizeof(arg)) // ------------------- Containers ---------------- class TagWritefile { inherit RXML.Tag; constant name = "writefile";
1b2d742001-10-08Anders Johansson  constant flags = RXML.FLAG_DONT_RECOVER;
93b5822001-05-09Stephen R. van den Berg  mapping(string:RXML.Type) req_arg_types = ([ "filename" : RXML.t_text(RXML.PEnt) ]); mapping(string:RXML.Type) opt_arg_types = ([ "from" : RXML.t_text(RXML.PEnt), "chroot" : RXML.t_text(RXML.PEnt), "append" : RXML.t_text(RXML.PEnt), "mkdirhier" : RXML.t_text(RXML.PEnt), "remove" : RXML.t_text(RXML.PEnt), "moveto" : RXML.t_text(RXML.PEnt), "max-size" : RXML.t_text(RXML.PEnt), "max-height" : RXML.t_text(RXML.PEnt), "max-width" : RXML.t_text(RXML.PEnt), "min-height" : RXML.t_text(RXML.PEnt), "min-width" : RXML.t_text(RXML.PEnt), "accept-type" : RXML.t_text(RXML.PEnt) ]); class Frame { inherit RXML.Frame; array do_return(RequestID id) { CACHE(0); _ok = 1; if(!sizeof(args->filename)) { _ok = 0; return 0; }
da5c2c2001-11-26Martin Stjernholm 
93b5822001-05-09Stephen R. van den Berg  string filename,rootpath,path,schroot=args->chroot||"";
da5c2c2001-11-26Martin Stjernholm  path = id->conf->real_file(id->not_query||"/", id); if (!path) parse_error ("There is no file system for %O that supports this tag " "(i.e. implements real_file).\n", id->not_query || "/"); path=dirname(path)+"/"; if (QUERY(onlysubdirs)) rootpath = path; else { rootpath = id->conf->real_file("/",id); if (!rootpath) parse_error ("There is no file system for / that supports this tag " "(i.e. implements real_file).\n"); }
93b5822001-05-09Stephen R. van den Berg  filename=((schroot+args->filename)[0]=='/'?rootpath:path)+ Stdio.append_path(schroot, args->filename); if(args->remove) { if(!rm(filename)) _ok = 0; } else if(IS(args->moveto)) { if(!mv(filename,((schroot+args->moveto)[0]=='/'?rootpath:path)+ Stdio.append_path(schroot, args->moveto))) _ok = 0; } else { string towrite; if(args->from) { towrite=RXML.user_get_var(args->from, "form"); if(!towrite || IS(args["max-size"]) && sizeof(towrite)>(int)args["max-size"]) { _ok = 0; return 0; } } else towrite=content; object privs;
17013c2001-05-16Per Hedbor  ;{ Stat st;
93b5822001-05-09Stephen R. van den Berg  string diro,dirn; int domkdir=0; for(dirn=filename; diro=dirn, diro!=(dirn=dirname(dirn)) && !(st = file_stat(dirn)); domkdir=1); if(st) {
70d4e52001-10-30Stephen R. van den Berg  privs = Privs("Writefile", st->uid, st->gid);
93b5822001-05-09Stephen R. van den Berg  if(domkdir && args->mkdirhier) Stdio.mkdirhier(dirname(filename)); } } _ok = 0; object file=Stdio.File();
70d4e52001-10-30Stephen R. van den Berg  if(file->open(lastfile=filename, args->append?"wrca":"wrct")) {
93b5822001-05-09Stephen R. van den Berg  _ok = 1; file->write(towrite); object dims; if (IS(args["min-height"])|| IS(args["max-height"])|| IS(args["min-width"]) || IS(args["max-width"])) { file->seek(0); dims = Dims.dims(); array xy = dims->get(file); if(xy && (IS(args["min-height"])&& xy[1] < (int)args["min-height"]|| IS(args["max-height"])&& xy[1] > (int)args["max-height"]|| IS(args["min-width"]) && xy[0] < (int)args["min-width"]|| IS(args["max-width"]) && xy[0] > (int)args["max-width"])) _ok = 0; } if (_ok && args["accept-type"]) { file->seek(0); array(string) types = args["accept-type"]/","; _ok = 0; catch { if (!dims) { dims = Dims.dims(); dims->f = file; } if (0<=search(types, "jpeg") && dims->get_JPEG() || 0<=search(types, "png") && (file->seek(0),dims->get_PNG()) || 0<=search(types, "gif") && (file->seek(0),dims->get_GIF())) _ok = 1; }; } file->close(); } privs = 0; } return 0; } } } // --------------------- Documentation ----------------------- TAGDOCUMENTATION; #ifdef manual constant tagdoc=([
ce8fb02001-09-21Johan Sundström "writefile":#"<desc type='cont'><p><short>
93b5822001-05-09Stephen R. van den Berg  Writes uploaded or direct content to a file.</short> You can either use an upload form or write the container content directly into a file. The ownership of any newly created file is determined by the directory it is placed into.</p> <p>Additional functionality includes removal or renaming of already existing files. This container tag will set the truth value depending on success or failure of the requested operation.</p> </desc>
ce8fb02001-09-21Johan Sundström <attr name='filename' value='string'>
93b5822001-05-09Stephen R. van den Berg  <p>Specifies the virtual filename to be created or operated on (relative to the current directory, or to the root of the virtual filesystem).</p> </attr>
ce8fb02001-09-21Johan Sundström <attr name='chroot' value='string'>
93b5822001-05-09Stephen R. van den Berg  <p>Specifies the virtual root directory (sandbox) all file operations are contained under.</p> </attr>
ce8fb02001-09-21Johan Sundström <attr name='from' value='string'>
adb3c22001-10-05Sara Karlsson <p>Specifies the type=file form field variable which uploaded the file to be written. If this attribute is omitted, the container content is what will be written instead. Given the example
04bf522001-12-03Anders Johansson  below, the parameter <i>from=wrapupafile</i> should be
3bb8522001-10-30Stephen R. van den Berg  specified.</p>
51b9362001-08-25Martin Nilsson 
ce8fb02001-09-21Johan Sundström <ex-box><form method='post'
adb3c22001-10-05Sara Karlsson  enctype='multipart/form-data'>
7dfc6a2001-07-20Johan Sundström  <input type='file' name='wrapupafile' />
adb3c22001-10-05Sara Karlsson  <input type='submit' value='Upload file' />
93b5822001-05-09Stephen R. van den Berg </form> File uploaded:
adb3c22001-10-05Sara Karlsson  <insert scope='form' variable='wrapupafile.filename'/>
ce8fb02001-09-21Johan Sundström </ex-box>
93b5822001-05-09Stephen R. van den Berg </attr>
ce8fb02001-09-21Johan Sundström <attr name='append'>
93b5822001-05-09Stephen R. van den Berg  <p>Append to the file instead of replacing it.</p> </attr>
ce8fb02001-09-21Johan Sundström <attr name='mkdirhier'>
93b5822001-05-09Stephen R. van den Berg  <p>Create the directory hierarchy needed to store the file if needed.</p> </attr>
ce8fb02001-09-21Johan Sundström <attr name='remove'>
93b5822001-05-09Stephen R. van den Berg  <p>Causes the specified filename or directory to be removed.</p> </attr>
ce8fb02001-09-21Johan Sundström <attr name='moveto' value='string'>
93b5822001-05-09Stephen R. van den Berg  <p>Causes the specified filename to be moved to this new location.</p> </attr>
ce8fb02001-09-21Johan Sundström <attr name='max-size' value='integer'>
93b5822001-05-09Stephen R. van den Berg  <p>Specifies the maximum upload file size in bytes which is accepted.</p> </attr>
ce8fb02001-09-21Johan Sundström <attr name='max-height' value='integer'>
93b5822001-05-09Stephen R. van den Berg  <p>The maximum imageheight in pixels which is accepted.</p> </attr>
ce8fb02001-09-21Johan Sundström <attr name='max-width' value='integer'>
93b5822001-05-09Stephen R. van den Berg  <p>The maximum imagewidth in pixels which is accepted.</p> </attr>
ce8fb02001-09-21Johan Sundström <attr name='min-height' value='integer'>
93b5822001-05-09Stephen R. van den Berg  <p>The minimum imageheight in pixels which is accepted.</p> </attr>
ce8fb02001-09-21Johan Sundström <attr name='min-width' value='integer'>
93b5822001-05-09Stephen R. van den Berg  <p>The minimum imagewidth in pixels which is accepted.</p> </attr>
ce8fb02001-09-21Johan Sundström <attr name='accept-type' value='string'>
93b5822001-05-09Stephen R. van den Berg  <p>Comma separated list of file types which are accepted, currently supported types are jpeg, png and gif; the check is performed on the file content, not on the file extension.</p> </attr>" , //---------------------------------------------------------------------- ]); #endif