Compare commits

..

19 Commits

Author SHA1 Message Date
Massimo Melina
6ff458fb73
Merge pull request #41 from divinity76/patch-1
warning about Delphi 10.4 Community being incompatible
2025-01-22 22:25:18 +01:00
divinity76
0d71b9946a
warning about Delphi 10.4 Community being incompatible 2023-03-25 12:45:10 +01:00
Massimo Melina
140528bac8
Create README.md 2023-03-12 17:42:10 +01:00
Massimo Melina
29f6bac31c default speed limit 50MBps 2020-08-30 23:26:11 +02:00
Massimo Melina
e233f6d29a fix: search and archive recently broken 2020-08-23 13:45:47 +02:00
Massimo Melina
6e4dcf5b56 fix: avoid dupe files in archive in case of ?search=* 2020-08-04 21:16:37 +02:00
Massimo Melina
61f1a14be6 updated .lng 2020-08-02 18:31:17 +02:00
Massimo Melina
2d1187b6a3 tpl: moved archive button to "selection" sub-menu 2020-08-02 17:44:02 +02:00
Massimo Melina
ca7caab85d fix: account dialog recently broken 2020-08-02 17:43:13 +02:00
Massimo Melina
9e662960e1 usability: standard ok/cancel buttons for "ask" dialog 2020-08-02 13:10:38 +02:00
Massimo Melina
21349e5c04 experiental ?mode=thumb to append to jpg files 2020-08-01 20:46:46 +02:00
Massimo Melina
db2ad83c77 new tpl syntax [^section] will prepend to [section] 2020-08-01 20:46:07 +02:00
Massimo Melina
a47541286a fix: unicode support with {.exec|out.} 2020-07-27 23:29:23 +02:00
Massimo Melina
62c30c8de1 fix: a {.command.} resulting in an empty string could actually produce a false error 2020-07-27 23:27:52 +02:00
Massimo Melina
ad439fa65f fix: some headers were not customizable with {.add header.} 2020-07-27 12:17:49 +02:00
Massimo Melina
2d131f2c5f fix: malformed non-ascii post variables when not url-encoded 2020-07-27 11:37:18 +02:00
Massimo Melina
ba2df13122 removed jquery dependency from default tpl 2020-07-08 15:22:35 +02:00
Massimo Melina
da294807ca removed 'append macros log' option 2020-07-08 13:26:28 +02:00
Massimo Melina
6625f08419 Revert "apply 1 minute timeout to file listing"
This reverts commit d43983e9
2020-07-08 13:24:27 +02:00
11 changed files with 640 additions and 444 deletions

View File

@ -1,3 +1,9 @@
# Obsolete
This is the repository of the old HFS.
I'm working on HFS 3 on another repository. Check it out!
https://github.com/rejetto/hfs
## Introduction ## Introduction
You can use HFS (HTTP File Server) to send and receive files. You can use HFS (HTTP File Server) to send and receive files.
It's different from classic file sharing because it uses web technology. It's different from classic file sharing because it uses web technology.
@ -9,6 +15,10 @@ The virtual file system will allow you to easily share even one single file.
Initially developed in 2002 with Delphi 6, now with Delphi 10.3.3 (Community Edition). Initially developed in 2002 with Delphi 6, now with Delphi 10.3.3 (Community Edition).
Icons are generated at http://fontello.com/ . Use fontello.json for further modifications. Icons are generated at http://fontello.com/ . Use fontello.json for further modifications.
For the default template we are targeting compatibility with Chrome 49 as it's the latest version running on Windows XP.
Warning: Delphi Community Edition 10.4 removed support for command-line compilation, and is thus unable to compile JEDI Code Library, and is thus unable to compile HFS2, ref [Community Edition no longer includes the command-line compilers](https://blogs.embarcadero.com/delphi-cbuilder-community-editions-now-available-in-version-10-4-2/#comment-1339) - meaning the last version of Community Edition cabale of compiling HFS2 is Delphi 10.3.x
## Libs used ## Libs used
- [ICS v8.64](http://www.overbyte.be) by François PIETTE - [ICS v8.64](http://www.overbyte.be) by François PIETTE
- [TRegExpr v0.952b](https://github.com/andgineer/TRegExpr/releases) by Andrey V. Sorokin - [TRegExpr v0.952b](https://github.com/andgineer/TRegExpr/releases) by Andrey V. Sorokin

View File

@ -99,6 +99,7 @@ type
constructor create; constructor create;
destructor Destroy; override; destructor Destroy; override;
function addFile(src:string; dst:string=''; data:Tobject=NIL):boolean; virtual; function addFile(src:string; dst:string=''; data:Tobject=NIL):boolean; virtual;
function contains(src:string):boolean;
function count():integer; function count():integer;
procedure reset(); virtual; procedure reset(); virtual;
property totalSize:int64 read getTotal; property totalSize:int64 read getTotal;
@ -524,6 +525,16 @@ if cachedTotal < 0 then calculate();
result:=cachedTotal; result:=cachedTotal;
end; // getTotal end; // getTotal
function TarchiveStream.contains(src:string):boolean;
var
i: integer;
begin
for i:=0 to Length(flist)-1 do
if flist[i].src = src then
exit(TRUE);
result:=FALSE;
end;
function TarchiveStream.addFile(src:string; dst:string=''; data:Tobject=NIL):boolean; function TarchiveStream.addFile(src:string; dst:string=''; data:Tobject=NIL):boolean;
function getMtime(fh:Thandle):int64; function getMtime(fh:Thandle):int64;
@ -1127,7 +1138,7 @@ var
ss: TStringDynArray; ss: TStringDynArray;
s, si: string; s, si: string;
till: pchar; till: pchar;
append: boolean; append, prepend, add: boolean;
sect, from: PtplSection; sect, from: PtplSection;
begin begin
till:=pred(bos); till:=pred(bos);
@ -1143,8 +1154,10 @@ var
if not parseFlagsAndAcceptSection(ss) then if not parseFlagsAndAcceptSection(ss) then
exit; exit;
append:=ansiStartsStr('+', cur_section); prepend:=startsStr('^', cur_section);
if append then append:=startsStr('+', cur_section);
add:=prepend or append;
if add then
delete(cur_section,1,1); delete(cur_section,1,1);
// there may be several section names separated by = // there may be several section names separated by =
@ -1160,16 +1173,19 @@ var
from:=NIL; from:=NIL;
if sect = NIL then // not found if sect = NIL then // not found
begin begin
if append then if add then
from:=getSection(s); from:=getSection(s);
sect:=newSection(s); sect:=newSection(s);
end end
else else
if append then if add then
from:=sect; from:=sect;
if from<>NIL then if from<>NIL then
begin // inherit from it begin // inherit from it
sect.txt:=from.txt+base.txt; if append then
sect.txt:=from.txt+base.txt
else
sect.txt:=base.txt+CRLF+from.txt;
sect.nolog:=from.nolog or base.nolog; sect.nolog:=from.nolog or base.nolog;
sect.public:=from.public or base.public; sect.public:=from.public or base.public;
sect.noList:=from.noList or base.noList; sect.noList:=from.noList or base.noList;

File diff suppressed because it is too large Load Diff

View File

@ -206,9 +206,10 @@
</Platforms> </Platforms>
<ModelSupport>False</ModelSupport> <ModelSupport>False</ModelSupport>
<Deployment Version="3"> <Deployment Version="3">
<DeployFile LocalName="hfs.exe" Configuration="Release" Class="ProjectOutput"> <DeployFile LocalName="hfs.dpr" Configuration="Release" Class="ProjectFile">
<Platform Name="Win32"> <Platform Name="Win32">
<RemoteName>hfs.exe</RemoteName> <RemoteDir>.\</RemoteDir>
<Enabled>false</Enabled>
<Overwrite>true</Overwrite> <Overwrite>true</Overwrite>
</Platform> </Platform>
</DeployFile> </DeployFile>
@ -218,16 +219,15 @@
<Overwrite>true</Overwrite> <Overwrite>true</Overwrite>
</Platform> </Platform>
</DeployFile> </DeployFile>
<DeployFile LocalName="hfs.dpr" Configuration="Debug" Class="ProjectFile"> <DeployFile LocalName="hfs.exe" Configuration="Release" Class="ProjectOutput">
<Platform Name="Win32"> <Platform Name="Win32">
<RemoteDir>.\</RemoteDir> <RemoteName>hfs.exe</RemoteName>
<Overwrite>true</Overwrite> <Overwrite>true</Overwrite>
</Platform> </Platform>
</DeployFile> </DeployFile>
<DeployFile LocalName="hfs.dpr" Configuration="Release" Class="ProjectFile"> <DeployFile LocalName="hfs.dpr" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32"> <Platform Name="Win32">
<RemoteDir>.\</RemoteDir> <RemoteDir>.\</RemoteDir>
<Enabled>false</Enabled>
<Overwrite>true</Overwrite> <Overwrite>true</Overwrite>
</Platform> </Platform>
</DeployFile> </DeployFile>

View File

@ -1,5 +1,5 @@
; Kryvich's Delphi Localizer Language File. ; Kryvich's Delphi Localizer Language File.
; Generated by K.D.L. Scanner, 28/06/2020 20:30:07 ; Generated by K.D.L. Scanner, 02/08/2020 18:30:32
Humanize=1 Humanize=1
HumanizedCR=\^ HumanizedCR=\^
@ -282,7 +282,6 @@ menu.Debug1.dumpTrafficChk.Caption=Dump traffic
menu.Debug1.Showcustomizedoptions1.Caption=Show customized options... menu.Debug1.Showcustomizedoptions1.Caption=Show customized options...
menu.Debug1.highSpeedChk.Caption=Experimental high speed handling menu.Debug1.highSpeedChk.Caption=Experimental high speed handling
menu.Debug1.macrosLogChk.Caption=Enable macros.log menu.Debug1.macrosLogChk.Caption=Enable macros.log
menu.Debug1.Appendmacroslog1.Caption=Append macros.log
menu.Debug1.Runscript1.Caption=Run script... menu.Debug1.Runscript1.Caption=Run script...
menu.Debug1.showMemUsageChk.Caption=Show memory usage menu.Debug1.showMemUsageChk.Caption=Show memory usage
menu.Debug1.noContentdispositionChk.Caption=No Content-disposition menu.Debug1.noContentdispositionChk.Caption=No Content-disposition

View File

@ -104,7 +104,7 @@ type
); );
body: ansistring; // specifies reply body according to bodyMode body: ansistring; // specifies reply body according to bodyMode
bodyFile: string; bodyFile: string;
bodyStream: Tstream; // note: the stream is automatically freed bodyStream: Tstream; // note: the stream is automatically freed
firstByte, lastByte: int64; // body interval for partial replies (206) firstByte, lastByte: int64; // body interval for partial replies (206)
realm, // this will appear in the authentication dialog realm, // this will appear in the authentication dialog
reason, // customized reason phrase reason, // customized reason phrase
@ -423,7 +423,7 @@ begin
repeat repeat
result:=posEx(ss, s, ofs); result:=posEx(ss, s, ofs);
if result = 0 then exit; if result = 0 then exit;
repeat repeat
qpos:=posEx(quote, s, ofs); qpos:=posEx(quote, s, ofs);
if qpos = 0 then exit; // there's no quoting, our result will fit if qpos = 0 then exit; // there's no quoting, our result will fit
@ -1599,7 +1599,7 @@ end; // initInputStream
function ThttpConn.sendNextChunk(max:integer=MAXINT):integer; function ThttpConn.sendNextChunk(max:integer=MAXINT):integer;
var var
n: int64; n, toSend: int64;
buf: ansistring; buf: ansistring;
begin begin
result:=0; result:=0;
@ -1611,7 +1611,8 @@ if (n = 0) or (bytesSentLastItem = 0) then n:=max;
if n > MAXIMUM_CHUNK_SIZE then n:=MAXIMUM_CHUNK_SIZE; if n > MAXIMUM_CHUNK_SIZE then n:=MAXIMUM_CHUNK_SIZE;
if n < MINIMUM_CHUNK_SIZE then n:=MINIMUM_CHUNK_SIZE; if n < MINIMUM_CHUNK_SIZE then n:=MINIMUM_CHUNK_SIZE;
if n > max then n:=max; if n > max then n:=max;
if n > bytesToSend then n:=bytesToSend; toSend:=bytesToSend;
if n > toSend then n:=toSend;
if n = 0 then exit; if n = 0 then exit;
setLength(buf, n); setLength(buf, n);
n:=stream.read(buf[1], n); n:=stream.read(buf[1], n);

View File

@ -2963,10 +2963,6 @@ object mainFrm: TmainFrm
AutoCheck = True AutoCheck = True
Caption = 'Enable macros.log' Caption = 'Enable macros.log'
end end
object Appendmacroslog1: TMenuItem
AutoCheck = True
Caption = 'Append macros.log'
end
object Runscript1: TMenuItem object Runscript1: TMenuItem
Caption = 'Run script...' Caption = 'Run script...'
OnClick = Runscript1Click OnClick = Runscript1Click

View File

@ -35,8 +35,8 @@ uses
HSlib, traylib, monoLib, progFrmLib, classesLib; HSlib, traylib, monoLib, progFrmLib, classesLib;
const const
VERSION = '2.4.0 RC6'; VERSION = '2.4.0 RC8';
VERSION_BUILD = '318'; VERSION_BUILD = '320';
VERSION_STABLE = {$IFDEF STABLE } TRUE {$ELSE} FALSE {$ENDIF}; VERSION_STABLE = {$IFDEF STABLE } TRUE {$ELSE} FALSE {$ENDIF};
CURRENT_VFS_FORMAT :integer = 1; CURRENT_VFS_FORMAT :integer = 1;
CRLF = #13#10; CRLF = #13#10;
@ -671,7 +671,6 @@ type
Speedlimitforsingleaddress1: TMenuItem; Speedlimitforsingleaddress1: TMenuItem;
macrosLogChk: TMenuItem; macrosLogChk: TMenuItem;
Debug1: TMenuItem; Debug1: TMenuItem;
Appendmacroslog1: TMenuItem;
preventStandbyChk: TMenuItem; preventStandbyChk: TMenuItem;
titlePnl: TPanel; titlePnl: TPanel;
HTMLtemplate1: TMenuItem; HTMLtemplate1: TMenuItem;
@ -1383,7 +1382,6 @@ type
constructor TfileListing.create(); constructor TfileListing.create();
begin begin
dir:=NIL; dir:=NIL;
timeout:=Now()+1/MINUTES;
end; // create end; // create
destructor TfileListing.destroy; destructor TfileListing.destroy;
@ -1666,7 +1664,7 @@ this would let us have "=" inside the names, but names cannot be assigned
repeat repeat
application.ProcessMessages(); application.ProcessMessages();
cd.lastActivityTime:=now(); cd.lastActivityTime:=now();
if cd.lastActivityTime > timeout then if (timeout > 0) and (cd.lastActivityTime > timeout) then
break; break;
// we don't list these entries // we don't list these entries
if (sr.name = '.') or (sr.name = '..') if (sr.name = '.') or (sr.name = '..')
@ -3625,13 +3623,11 @@ begin
result:=''; result:='';
if (folder = NIL) or not folder.isFolder() then exit; if (folder = NIL) or not folder.isFolder() then exit;
if macrosLogChk.checked and not appendmacroslog1.checked then
resetLog();
diffTpl:=Ttpl.create(); diffTpl:=Ttpl.create();
folder.lock(); folder.lock();
try try
buildTime:=now(); buildTime:=now();
cd.conn.addHeader('Cache-Control: no-cache, no-store, must-revalidate, max-age=-1'); cd.conn.setHeaderIfNone('Cache-Control: no-cache, no-store, must-revalidate, max-age=-1');
recur:=shouldRecur(cd); recur:=shouldRecur(cd);
baseurl:=protoColon()+getSafeHost(cd)+folder.url(TRUE); baseurl:=protoColon()+getSafeHost(cd)+folder.url(TRUE);
@ -4010,9 +4006,9 @@ if result then
conn.reply.mode:=HRM_NOT_MODIFIED; conn.reply.mode:=HRM_NOT_MODIFIED;
exit; exit;
end; end;
conn.addHeader('ETag: '+UTF8encode(etag)); conn.setHeaderIfNone('ETag: '+UTF8encode(etag));
if ts > '' then if ts > '' then
conn.addHeader('Last-Modified: '+UTF8encode(ts)); conn.setHeaderIfNone('Last-Modified: '+UTF8encode(ts));
end; // notModified end; // notModified
function notModified(conn:ThttpConn; f:string):boolean; overload; function notModified(conn:ThttpConn; f:string):boolean; overload;
@ -4944,7 +4940,7 @@ var
var s:ansistring; var s:ansistring;
begin begin
s:=ansistring(HSlib.encodeURL(data.lastFN)); s:=ansistring(HSlib.encodeURL(data.lastFN));
conn.addHeader( ansistring('Content-Disposition: '+if_(attach, 'attachment; ') conn.setHeaderIfNone( ansistring('Content-Disposition: '+if_(attach, 'attachment; ')
+'filename*=UTF-8'''''+s+'; filename='+s)); +'filename*=UTF-8'''''+s+'; filename='+s));
end; end;
@ -5028,6 +5024,12 @@ var
tar: TtarStream; tar: TtarStream;
nofolders, selection, itsAsearch: boolean; nofolders, selection, itsAsearch: boolean;
procedure addToTar(src,dst:string);
begin
if not selection or not tar.contains(src) then
tar.addFile(src, dst);
end;
procedure addFolder(f:Tfile; ignoreConnFilters:boolean=FALSE); procedure addFolder(f:Tfile; ignoreConnFilters:boolean=FALSE);
var var
i, ofs: integer; i, ofs: integer;
@ -5040,6 +5042,7 @@ var
listing:=TfileListing.create(); listing:=TfileListing.create();
try try
listing.ignoreConnFilter:=ignoreConnFilters; listing.ignoreConnFilter:=ignoreConnFilters;
listing.timeout:= now()+1/MINUTES;
listing.fromFolder( f, data, shouldRecur(data)); listing.fromFolder( f, data, shouldRecur(data));
fIsTemp:=f.isTemp(); fIsTemp:=f.isTemp();
ofs:=length(f.resource)-length(f.name)+1; ofs:=length(f.resource)-length(f.name)+1;
@ -5061,7 +5064,7 @@ var
else else
s:=fi.pathTill(f.parent); // we want the path to include also f, so stop at f.parent s:=fi.pathTill(f.parent); // we want the path to include also f, so stop at f.parent
tar.addFile(fi.resource, s); addToTar(fi.resource, s);
end end
finally listing.free end; finally listing.free end;
end; // addFolder end; // addFolder
@ -5096,7 +5099,7 @@ var
t:=substr(s, lastDelimiter('\/', s)+1) t:=substr(s, lastDelimiter('\/', s)+1)
else else
t:=s; t:=s;
tar.addFile(ft.resource, t); addToTar(ft.resource, t);
finally freeIfTemp(ft) end; finally freeIfTemp(ft) end;
end; end;
end; // addSelection end; // addSelection
@ -5342,6 +5345,29 @@ var
runEventScript('login') runEventScript('login')
end; //urlAuth end; //urlAuth
function thumb():Boolean;
var
b: rawbytestring;
s, e: integer;
begin
if mode <> 'thumb' then
exit(FALSE);
result:=TRUE;
b:=loadFile(f.resource, 0, 96*KILO);
s:= pos(rawbytestring(#$FF#$D8#$FF), b, 2);
if s > 0 then
e:=pos(rawbytestring(#$FF#$D9), b, s);
if (s=0) or (e=0) then
begin
data.conn.reply.mode:=HRM_NOT_FOUND;
exit;
end;
conn.reply.contentType:='image/jpeg';
conn.reply.mode:=HRM_REPLY;
conn.reply.bodyMode:=RBM_STRING;
conn.reply.body:=Copy(b, s, e-s+2);
end;
var var
b: boolean; b: boolean;
s: string; s: string;
@ -5701,6 +5727,9 @@ var
if notModified(conn, f) then // calling notModified before limitsExceededOnDownload makes possible for [download] to manipualate headers set here if notModified(conn, f) then // calling notModified before limitsExceededOnDownload makes possible for [download] to manipualate headers set here
exit; exit;
if thumb() then
Exit;
data.countAsDownload:=f.shouldCountAsDownload(); data.countAsDownload:=f.shouldCountAsDownload();
if data.countAsDownload and limitsExceededOnDownload() then if data.countAsDownload and limitsExceededOnDownload() then
exit; exit;
@ -5985,7 +6014,7 @@ case event of
refreshConn(data); refreshConn(data);
end; end;
HE_POST_VAR: data.postVars.add(conn.post.varname+'='+conn.post.data); HE_POST_VAR: data.postVars.add(conn.post.varname+'='+UTF8toString(conn.post.data));
HE_POST_VARS: HE_POST_VARS:
if conn.post.mode = PM_URLENCODED then if conn.post.mode = PM_URLENCODED then
urlToStrings(conn.post.data, data.postVars); urlToStrings(conn.post.data, data.postVars);
@ -8089,10 +8118,10 @@ var
if userSocketBuffer > 0 then if userSocketBuffer > 0 then
data.conn.sndBuf:=userSocketBuffer data.conn.sndBuf:=userSocketBuffer
else else if highSpeedChk.checked then
begin begin
size:=minmax(8192, MEGA, round(data.averageSpeed)); size:=minmax(8192, MEGA, round(data.averageSpeed));
if highSpeedChk.checked and (safeDiv(0.0+size, data.conn.sndbuf, 2) > 2) then if safeDiv(0.0+size, data.conn.sndbuf, 2) > 2 then
data.conn.sndBuf:=size; data.conn.sndBuf:=size;
end; end;
end; end;
@ -11871,7 +11900,6 @@ if menu.items.find(logmenu.items.caption) = NIL then
SwitchON1.imageIndex:=if_(srv.active, 11, 4); SwitchON1.imageIndex:=if_(srv.active, 11, 4);
SwitchON1.caption:=if_(srv.active, S_OFF, S_ON); SwitchON1.caption:=if_(srv.active, S_OFF, S_ON);
Appendmacroslog1.Enabled:=macrosLogChk.checked;
stopSpidersChk.Enabled:=not fileExistsByURL('/robots.txt'); stopSpidersChk.Enabled:=not fileExistsByURL('/robots.txt');
Showbandwidthgraph1.visible:=not graphBox.visible; Showbandwidthgraph1.visible:=not graphBox.visible;
if bakShellMenuText='' then if bakShellMenuText='' then
@ -12096,7 +12124,7 @@ tray:=TmyTrayicon.create(self);
DragAcceptFiles(handle, true); DragAcceptFiles(handle, true);
caption:=format('HFS ~ HTTP File Server %s', [VERSION]); caption:=format('HFS ~ HTTP File Server %s', [VERSION]);
application.Title:=format('HFS %s', [VERSION]); application.Title:=format('HFS %s', [VERSION]);
setSpeedLimit(-1); setSpeedLimit(50000);
setSpeedLimitIP(-1); setSpeedLimitIP(-1);
setGraphRate(10); setGraphRate(10);
setMaxConnections(0); setMaxConnections(0);

View File

@ -161,16 +161,18 @@ var
procedure deprecatedMacro(what:string=''; instead:string=''); procedure deprecatedMacro(what:string=''; instead:string='');
begin mainfrm.add2log('WARNING, deprecated macro: '+first(what, name)+nonEmptyConcat(' - Use instead: ',instead), NIL, clRed) end; begin mainfrm.add2log('WARNING, deprecated macro: '+first(what, name)+nonEmptyConcat(' - Use instead: ',instead), NIL, clRed) end;
procedure unsatisfied(b:boolean=TRUE);
begin
if b then
macroError('cannot be used here')
end;
function satisfied(p:pointer):boolean; function satisfied(p:pointer):boolean;
begin begin
result:=assigned(p); result:=assigned(p);
if not result then unsatisfied(not result);
macroError('cannot be used here');
end; end;
procedure unsatisfied(b:boolean=TRUE);
begin if b then macroError('cannot be used here') end;
function parEx(idx:integer; name:string=''; doTrim:boolean=TRUE):string; overload; function parEx(idx:integer; name:string=''; doTrim:boolean=TRUE):string; overload;
var var
i: integer; i: integer;
@ -262,9 +264,9 @@ var
result:=staticVars; result:=staticVars;
delete(varname,1,length(G_VAR_PREFIX)); delete(varname,1,length(G_VAR_PREFIX));
end end
else if satisfied(md.cd) then else if assigned(md.cd) then
result:=md.cd.vars result:=md.cd.vars
else if satisfied(md.tempVars) then else if assigned(md.tempVars) then
result:=md.tempVars result:=md.tempVars
else else
raise Exception.create('no namespace available'); raise Exception.create('no namespace available');
@ -293,7 +295,7 @@ var
if not satisfied(space) then exit; if not satisfied(space) then exit;
i:=space.indexOfName(varname); i:=space.indexOfName(varname);
if i < 0 then if i < 0 then
if value = '' then exit // all is good the way it is if value = '' then exit(TRUE) // all is good the way it is
else i:=space.add(varname+'='+value) else i:=space.add(varname+'='+value)
else else
if value > '' then // in case of empty value, there's no need to assign, because we are going to delete it (after we cleared the bound object) if value > '' then // in case of empty value, there's no need to assign, because we are going to delete it (after we cleared the bound object)

View File

@ -29,12 +29,13 @@ document: {.if|var}
document: {.exec|out|timeout|exitcode.} document: {.exec|out|timeout|exitcode.}
document: [+section] document: [+section]
document: {.set item|diff template.} document: {.set item|diff template.}
document: {.add header|overwrite=0.}
document: {.calc| ][ } document: {.calc| ][ }
document: single line diff templates (file path) document: single line diff templates (file path)
document: {.disconnection reason|if=XXX.} document: {.disconnection reason|if=XXX.}
document: %url% document: %url%
document: commands returning white space: add folder, save, set account, exec, mkdir, chdir, delete, rename, move copy, set document: commands returning white space: add folder, save, set account, exec, mkdir, chdir, delete, rename, move copy, set
document: base64, base64decode, dir, disk free, filetime, file changed, load tpl, sha256, for line document: pipe, base64, base64decode, dir, disk free, filetime, file changed, load tpl, sha256, for line
document {.convert|macros|dec|hex.} document {.convert|macros|dec|hex.}
document: new event [login] document: new event [login]
+ event to filter logging http://www.rejetto.com/forum/index.php/topic,9784.0.html + event to filter logging http://www.rejetto.com/forum/index.php/topic,9784.0.html
@ -92,12 +93,12 @@ document: new event [login]
+ an updated hint on virtual folders, to explain how to get upload working + an updated hint on virtual folders, to explain how to get upload working
- requesting a non-existant file inside an unauthorized folder, apache replies 401, hfs 404. try to comply. - requesting a non-existant file inside an unauthorized folder, apache replies 401, hfs 404. try to comply.
+ make %list% available in every page + make %list% available in every page
+ support for ALT+F4 with option "Minimize to tray clicking the close button" www.rejetto.com/forum/?topic=6351 + support for ALT+F4 with option "Minimize to tray clicking the close button" www.rejetto.com/forum/?topic=6351
+ replace and delete icons http://www.rejetto.com/forum/index.php?topic=6317.msg1038157#msg1038157 + replace and delete icons http://www.rejetto.com/forum/index.php?topic=6317.msg1038157#msg1038157
? currently the delete permission is only inside a folder. you can't mark a file or delete the marked folder. is this ok? ? currently the delete permission is only inside a folder. you can't mark a file or delete the marked folder. is this ok?
+ when a link is protected (no access for this user) it may be displayed as a link to the %item-name%, then 401, and if login is successful provide a redirection + when a link is protected (no access for this user) it may be displayed as a link to the %item-name%, then 401, and if login is successful provide a redirection
+ change folder/link/generic-file icons (via GUI, without editing the template) + change folder/link/generic-file icons (via GUI, without editing the template)
+ a way to get bigger icons (client side) + a way to get bigger icons (client side)
+ be able to produce rss http://www.rejetto.com/forum/index.php?topic=5846.msg1035481#msg1035481 + be able to produce rss http://www.rejetto.com/forum/index.php?topic=5846.msg1035481#msg1035481
* better warning message http://www.rejetto.com/forum/index.php?topic=5795.msg1034406#msg1034406 * better warning message http://www.rejetto.com/forum/index.php?topic=5795.msg1034406#msg1034406
? on the fly files compression www.rejetto.com/forum/?topic=5492 ? on the fly files compression www.rejetto.com/forum/?topic=5492
@ -105,7 +106,7 @@ document: new event [login]
? auto-removing folders www.rejetto.com/forum/?topic=3149 ? auto-removing folders www.rejetto.com/forum/?topic=3149
+ last-access-time for files www.rejetto.com/forum/?topic=5266 + last-access-time for files www.rejetto.com/forum/?topic=5266
+ expiration time for account www.rejetto.com/forum/?topic=5409 + expiration time for account www.rejetto.com/forum/?topic=5409
+ warn the user if there's no useful IP address http://www.rejetto.com/forum/index.php?topic=3193.msg1031371#msg1031371 + warn the user if there's no useful IP address http://www.rejetto.com/forum/index.php?topic=3193.msg1031371#msg1031371
+ GUI suggestions www.rejetto.com/forum/?topic=5334 + GUI suggestions www.rejetto.com/forum/?topic=5334
+ {.cookie.} http://www.rejetto.com/forum/index.php?topic=5349.0 + {.cookie.} http://www.rejetto.com/forum/index.php?topic=5349.0
+ restrict access to -> ip mask www.rejetto.com/forum/?topic=5244 + restrict access to -> ip mask www.rejetto.com/forum/?topic=5244
@ -126,37 +127,37 @@ document: new event [login]
+ per-folder no-limit + per-folder no-limit
+ windows auth (NLTM? seems to be available in ICS) www.rejetto.com/forum/?topic=3762 + windows auth (NLTM? seems to be available in ICS) www.rejetto.com/forum/?topic=3762
+ more stats www.rejetto.com/forum/?topic=4968 + more stats www.rejetto.com/forum/?topic=4968
+ to disable single ban rules + to disable single ban rules
+ ban by hostname + ban by hostname
+ edit comments for real folders www.rejetto.com/forum/?topic=4667 + edit comments for real folders www.rejetto.com/forum/?topic=4667
+ a way to pass ini commands through the command line + a way to pass ini commands through the command line
+ create folders via command line www.rejetto.com/forum/?topic=3955 + create folders via command line www.rejetto.com/forum/?topic=3955
? support mp3ToIon www.rejetto.com/forum/?topic=4600 ? support mp3ToIon www.rejetto.com/forum/?topic=4600
+ download only for <account-list> + download only for <account-list>
+ account: see all transfers in ~progress http://www.rejetto.com/forum/index.php/topic,9325.msg1053416/topicseen.html#msg1053416 + account: see all transfers in ~progress http://www.rejetto.com/forum/index.php/topic,9325.msg1053416/topicseen.html#msg1053416
+ limit account to a host mask + limit account to a host mask
+ tray icons for uploads + tray icons for uploads
+ MAC filter + MAC filter
+ if robots.txt does not exist, an option "don't be listed on search engines" + if robots.txt does not exist, an option "don't be listed on search engines"
+ menu -> limits -> temporarily disable all limits + menu -> limits -> temporarily disable all limits
+ menu -> limits -> max speed for each address + menu -> limits -> max speed for each address
+ option to display counter for folders as number of accesses instead of total access to files in it + option to display counter for folders as number of accesses instead of total access to files in it
+ autodisabling accounts www.rejetto.com/forum/?topic=5379 + autodisabling accounts www.rejetto.com/forum/?topic=5379
+ on update, propose a link to the "what's new" page + on update, propose a link to the "what's new" page
+ add special folder (expert mode): let you specify a special folder, like documents, or manually enter a path (useful for relative paths), or GUID + add special folder (expert mode): let you specify a special folder, like documents, or manually enter a path (useful for relative paths), or GUID
+ logs rotation (hfs always append) + logs rotation (hfs always append)
+ double address bar, one for LAN and one for the Internet + double address bar, one for LAN and one for the Internet
+ per user diff-tpl (apply both folder and user diff-tpl.s, and let the user decide priority, default:user,folder) + per user diff-tpl (apply both folder and user diff-tpl.s, and let the user decide priority, default:user,folder)
+ "Folder image mask", a file mask indicating the external file that should be used as icon (~img_folder) + "Folder image mask", a file mask indicating the external file that should be used as icon (~img_folder)
+ to be able to add icons from multi-icon files (like shell32.dll) + to be able to add icons from multi-icon files (like shell32.dll)
+ installer (saving to registry, and making ini-file the new default, don't ask for shell menu) + installer (saving to registry, and making ini-file the new default, don't ask for shell menu)
+ support unicode filenames (FindFirstFileW. Cannot be done because widgets don't support unicode) + support unicode filenames (FindFirstFileW. Cannot be done because widgets don't support unicode)
* show "(home)" instead of "/" in VFS * show "(home)" instead of "/" in VFS
+ show updateinfo notice also in autocheck + show updateinfo notice also in autocheck
+ top 10 downloaded files + top 10 downloaded files
+ after the self test fails, and a router problem is detected, prompt a wizard for portforwad.com (extract routers list) + after the self test fails, and a router problem is detected, prompt a wizard for portforwad.com (extract routers list)
+ export vfs map as txt/html + export vfs map as txt/html
+ specific message for each disabled account + specific message for each disabled account
+ search for files including meta information (id3 tag) www.rejetto.com/forum/?topic=5312 + search for files including meta information (id3 tag) www.rejetto.com/forum/?topic=5312
+ multiupload using flash + multiupload using flash
? support shortcut to folders in real-folders ? support shortcut to folders in real-folders
@ -184,7 +185,7 @@ document: new event [login]
* stop using /~commands and move all of them in the standard ?name=value form * stop using /~commands and move all of them in the standard ?name=value form
VER 3 VER 3
+ new kind of folder (no more real/virtual folders) + new kind of folder (no more real/virtual folders)
VER 3.5 VER 3.5
+ search for files + search for files

View File

@ -2220,7 +2220,7 @@ const
var var
sa : TSecurityAttributes; sa : TSecurityAttributes;
ReadPipe,WritePipe : THandle; ReadPipe,WritePipe : THandle;
start : TStartUpInfoA; start : TStartUpInfoW;
ProcessInfo : TProcessInformation; ProcessInfo : TProcessInformation;
Buffer : Pansichar; Buffer : Pansichar;
TotalBytesRead, TotalBytesRead,
@ -2251,7 +2251,7 @@ else
timeout:=now()+timeout/SECONDS; timeout:=now()+timeout/SECONDS;
// Create a Console Child Process with redirected input and output // Create a Console Child Process with redirected input and output
try try
if CreateProcessA(nil, PansiChar(ansistring(DosApp)), @sa, @sa, true, CREATE_NO_WINDOW or NORMAL_PRIORITY_CLASS, nil, nil, start, ProcessInfo) then if CreateProcess(nil, PChar(dosApp), @sa, @sa, true, CREATE_NO_WINDOW or NORMAL_PRIORITY_CLASS, nil, nil, start, ProcessInfo) then
repeat repeat
result:=TRUE; result:=TRUE;
// wait for end of child process // wait for end of child process
@ -2261,16 +2261,22 @@ try
// so that the pipe is not blocked by an overflow. New information // so that the pipe is not blocked by an overflow. New information
// can be written from the console app to the pipe only if there is // can be written from the console app to the pipe only if there is
// enough buffer space. // enough buffer space.
if not PeekNamedPipe(ReadPipe, @Buffer[TotalBytesRead], ReadBuffer, if not PeekNamedPipe(ReadPipe, @Buffer[TotalBytesRead], ReadBuffer, @BytesRead, @TotalBytesAvail, @BytesLeftThisMessage )
@BytesRead, @TotalBytesAvail, @BytesLeftThisMessage ) then or (BytesRead > 0) and not ReadFile(ReadPipe, Buffer[TotalBytesRead], BytesRead, BytesRead, nil ) then
break break;
else if BytesRead > 0 then
ReadFile(ReadPipe, Buffer[TotalBytesRead], BytesRead, BytesRead, nil );
inc(TotalBytesRead, BytesRead); inc(TotalBytesRead, BytesRead);
until (Apprunning <> WAIT_TIMEOUT) or (now() >= timeout); until (Apprunning <> WAIT_TIMEOUT) or (now() >= timeout);
Buffer[TotalBytesRead]:= #0; if IsTextUnicode(Buffer, TotalBytesRead, NIL) then
OemToCharA(PansiChar(Buffer),Buffer); begin
output:=string(ansistrings.strPas(Buffer)); Pchar(@Buffer[TotalBytesRead])^:= #0;
output:=pchar(Buffer)
end
else
begin
Buffer[TotalBytesRead]:= #0;
OemToCharA(Buffer,Buffer);
output:=string(ansistrings.strPas(Buffer));
end;
finally finally
GetExitCodeProcess(ProcessInfo.hProcess, exitcode); GetExitCodeProcess(ProcessInfo.hProcess, exitcode);
TerminateProcess(ProcessInfo.hProcess, 0); TerminateProcess(ProcessInfo.hProcess, 0);