-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdocumin.php
More file actions
2075 lines (1797 loc) · 64.3 KB
/
Copy pathdocumin.php
File metadata and controls
2075 lines (1797 loc) · 64.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?php
/*
* documin - minimal document management system
* Copyright (C) 2014-2024 Jim Trainor
*
* This program is free 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. You should have received a
* copy of the GNU General Public License along with this program. If
* not, see <http://www.gnu.org/licenses/>.
*
* Documin was derived from the Encode Explorer file browser by Marek
* Rei (http://encode-explorer.siineiolekala.net). All images except
* file_cabinet were designed by Mark James (http://www.famfamfam.com)
* and distributed under the Creative Commons Attribution 3.0
* License. The file_cabinet image came from
* http://commons.wikimedia.org/wiki/File:Replacement_filing_cabinet.svg
* and is in the public domain.
*/
$_CONFIG = array();
$_ERROR = "";
$_START_TIME = microtime(TRUE);
/***************************************************************************
* Configuration
***************************************************************************/
// Document database file.
$_CONFIG['dbfile'] = 'documin.sqlite';
// Choose a language. (Only "en" for now.)
$_CONFIG['lang'] = "en";
// Will the files be opened in a new window? true/false
$_CONFIG['open_in_new_window'] = false;
// Will the page header be displayed? 0=no, 1=yes.
$_CONFIG['show_top'] = false;
//
// The page title
$_CONFIG['main_title'] = "documin";
// Display breadcrumbs (relative path of the location).
$_CONFIG['show_path'] = true;
// Display the file count, load time it took to load the page, etc.
$_CONFIG['show_info'] = true;
// The time format for the "last changed" column.
$_CONFIG['time_format'] = "d.m.y H:i:s";
// The timezone of the server. Any value that is suitable
// for use with data_default_timezone_set(value).
$_CONFIG['timezone'] = "America/New_York";
// Charset. Use the one that is suitable for you.
$_CONFIG['charset'] = "UTF-8";
// Regular expression to match files that should be hidden.
$_CONFIG['hidden_file_regex'] = "/^\\.|~$|index.php|documin.php|documin.sqlite/";
// Regular expression to match directories that should be hidden.
$_CONFIG['hidden_dir_regex'] = "";
// Enable/disaable file upload and creatiion new directories.
$_CONFIG['upload_enable'] = true;
// MIME type that are allowed to be uploaded.
// For example, to only allow uploading of common image types, you could use:
// $_CONFIG['upload_allow_type'] = array("image/png", "image/gif", "image/jpeg");
$_CONFIG['upload_allow_type'] = array();
// File extensions that are not allowed for uploading.
// For example: $_CONFIG['upload_reject_extension'] = array("php", "html", "htm");
$_CONFIG['upload_reject_extension'] = array("php");
// The starting directory. Normally no need to change this.
// Use only relative subdirectories!
// For example: $_CONFIG['starting_dir'] = "./mysubdir/";
$_CONFIG['starting_dir'] = ".";
// Location in the server. Usually this does not have to be set manually.
// Default: $_CONFIG['basedir'] = "";
$_CONFIG['basedir'] = "";
// Big files. If you have some very big files (>4GB), enable this for correct
// file size calculation.
// Default: $_CONFIG['large_files'] = false;
$_CONFIG['large_files'] = false;
// The file hash type.
// "md5int32" - decimal md5sum mod 2^31
// "md5int364" - decimal md5sum mod 2^63
// [any other value] - 128 bit hex md5sum (default)
$_CONFIG['hash_type'] = "md5int32";
// File mode for new uploads
$_CONFIG['file_mode'] = 0444;
// File operation undo time limit in seconds.
$_CONFIG['undo_time_limit_seconds'] = 600;
/***************************************************************************
* Translations
***************************************************************************/
$_TRANSLATIONS = array();
// English
$_TRANSLATIONS["en"] = array(
"file_name" => "File name",
"size" => "Size",
"last_changed" => "Last changed",
"upload" => "Upload",
"failed_upload" => "Failed to upload the file!",
"failed_move" => "Failed to move the file into the right directory!",
"make_directory" => "New dir",
"new_dir_failed" => "Failed to create directory",
"unable_to_read_dir" => "Unable to read directory",
"upload_not_allowed" => "The script configuration does not allow uploading in this directory.",
"upload_dir_not_writable" => "This directory does not have write permissions.",
"upload_type_not_allowed" => "This file type is not allowed for uploading.",
"failed_file_chmod" => "Failed to change the permissions of the uploaded file.",
"page_load_time" => "page load time %.0f ms",
"file_index_count" => "%d indexed",
"file_sum_size" => "%s managed",
"unable_to_remove_dir" => "Failed to remove directory",
"unable_to_remove_file" => "Failed to remove file",
"unable_to_remove_unrecognized_path" => "Failed to remove unrecognized file system entry."
);
// Arabic - اللغة العربية
$_TRANSLATIONS["ar"] = array(
"file_name" => "اسم الملف",
"size" => "حجم",
"last_changed" => "آخر تحديث",
"upload" => "رفع",
"failed_upload" => "فشلت عملية رفع الملف",
"failed_move" => "فشلت عملية نقل الملف الى المجلد بالجهة اليمنى",
"make_directory" => "مجلد جديد",
"new_dir_failed" => "فشل عمل مجلد جديد",
"unable_to_read_dir" => "المسار غير قابل للقراءة",
"upload_not_allowed" => "اعدادات البرنامج لا تسمح برفع الملفات الى هذا المسار",
"upload_dir_not_writable" => "هذا المسار لا يملك اذونات الكتابة",
"upload_type_not_allowed" => "غير مسموح بهذا النوع من الملفات",
"failed_file_chmod" => "فشلت عملية تعديل الاذونات للملف المرفوع",
"page_load_time" => "تم تحميل الصفحة خلال %.0f ميكروثانية",
"file_index_count" => "%d تمت الفهرسة لـ",
"file_sum_size" => "%s متحكم",
"unable_to_remove_dir" => "فشلت عملية حذف المجلد",
"unable_to_remove_file" => "فشلت عملية حذف الملف",
"unable_to_remove_unrecognized_path" => "فشلت عملية حذف المسار الغير معروف"
);
/***************************************************************************
* CSS Styles
***************************************************************************/
function css()
{
?>
<style type="text/css">
/* General styles */
BODY {
background-color:#FFFFFF;
font-family:Verdana;
font-size:small;
}
A {
color: #000000;
text-decoration: none;
}
A:hover {
text-decoration: underline;
}
#top_image {
width:100%;
background: url( "?img=file_cabinet" );
background-repeat: repeat-x;
background-position: center;
height: 128px;
align: center;
}
#top_title div {
width: 100%;
}
#top_title a {
display:block;
}
#top_title a span {
color:#68a9d2;
font-weight:bold;
font-size:large;
padding: 10;
display:block;
text-align:center;
}
div.subtitle{
width:80%;
margin: 0 auto;
color:#68a9d2;
text-align:center;
}
#frame {
border: 1px solid #CDD2D6;
text-align:left;
position: relative;
margin: 0 auto;
overflow:hidden;
}
#error {
max-width:50%;
background-color:#FFE4E1;
color:#000000;
padding:7pt;
position: relative;
margin: 10pt auto;
text-align:center;
border: 1px dotted #CDD2D6;
}
input {
border: 3px solid #CDD2D6;
}
.bar{
width:100%;
clear:both;
height:1px;
}
/* File list */
table.table {
width:100%;
border-collapse: collapse;
}
table.table td{
padding:3px;
}
table.table tr.row.two {
background-color:#fcfdfe;
}
table.table tr.row.one {
background-color:#f8f9fa;
}
table.table tr.row td.icon {
width:25px;
padding-top:3px;
padding-bottom:1px;
}
table.table tr.row td.size {
width: 100px;
text-align: right;
}
table.table tr.row td.changed {
width: 150px;
text-align: center;
}
table.table tr.row td.fileid {
font-family: monospace;
text-align: center;
}
table.table tr.header img {
vertical-align:bottom;
}
table img{
border:0;
}
/* Info area */
#info {
color:#000000;
max-width:680px;
position: relative;
margin: auto;
margin-top: 10px;
text-align:center;
font-family:Verdana;
font-size:x-small;
}
/* Upload area */
#upload {
margin: 0 auto;
margin-top:10px;
margin-bottom:10px;
max-width:680px;
}
#upload #newdir_container {
float:left;
}
#upload #upload_container {
float:right;
}
#upload input.upload_dirname {
width:140px;
border: 3px solid;
border-color: #CDD2D6;
margin: 5px 0 5px 0;
}
#upload input.dirname_submit {
}
#upload input.upload_file {
width:100%;
border: 3px solid;
border-color: #CDD2D6;
font-family:Verdana;
font-size:x-small;
padding: 3px;
margin: 5px 0 5px 0;
}
#upload input.upload_submit {
width:60px;
}
#droparea {
width: 100%;
height: 50px;
line-height: 50px;
margin-top: 10px;
margin-bottom: 10px;
text-align: center;
vertical-align: middle;
background-color: #CDD2D6;
padding: 5px;
}
#droparea[data-state="dragenter"] {
background-color: #33a532;
}
#undo {
font-family:Verdana;
font-size:x-small;
margin: 0 auto;
margin-top:10px;
max-width:680px;
text-align:center;
}
/* Breadcrumbs */
div.breadcrumbs {
display:block;
padding:1px 3px;
color:#9999999;
font-size:x-small;
}
div.breadcrumbs a{
display:inline-block;
color:#999999;
padding:2px 0;
font-size:small;
}
/* admin link */
div.adminlink {
float: right;
}
</style>
<?php
}
/***************************************************************************
* IMAGE CODES IN BASE64
* You can generate your own with a converter
* Like here: http://www.motobit.com/util/base64-decoder-encoder.asp
* Or here: http://www.greywyvern.com/code/php/binary2base64
* Or just use PHP base64_encode() function
***************************************************************************/
$_IMAGES = array();
$_IMAGES_CONTENT_TYPE = array();
$_IMAGES_CONTENT_TYPE_DEFAULT = "gif";
// thanks, http://commons.wikimedia.org/wiki/File:Golden_file_cabinet.png
$_IMAGES_CONTENT_TYPE["file_cabinet"] = "png";
$_IMAGES["file_cabinet"] =
"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";
$_IMAGES["arrow_down"] =
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0
U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAABbSURBVCjPY/jPgB8yDCkFB/7v+r/5/+r/
i/7P+N/3DYuC7V93/d//fydQ0Zz/9eexKFgtsejLiv8b/8/8X/WtUBGrGyZLdH6f8r/sW64cTkdW
SRS+zpQbgiEJAI4UCqdRg1A6AAAAAElFTkSuQmCC";
$_IMAGES["arrow_up"] =
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0
U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAABbSURBVCjPY/jPgB8yDDkFmyVWv14kh1PB
eoll31f/n/ytUw6rgtUSi76s+L/x/8z/Vd8KFbEomPt16f/1/1f+X/S/7X/qeSwK+v63/K/6X/g/
83/S/5hvQywkAdMGCdCoabZeAAAAAElFTkSuQmCC";
$_IMAGES["directory"] =
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0
U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGrSURBVDjLxZO7ihRBFIa/6u0ZW7GHBUV0
UQQTZzd3QdhMQxOfwMRXEANBMNQX0MzAzFAwEzHwARbNFDdwEd31Mj3X7a6uOr9BtzNjYjKBJ6ni
cP7v3KqcJFaxhBVtZUAK8OHlld2st7Xl3DJPVONP+zEUV4HqL5UDYHr5xvuQAjgl/Qs7TzvOOVAj
xjlC+ePSwe6DfbVegLVuT4r14eTr6zvA8xSAoBLzx6pvj4l+DZIezuVkG9fY2H7YRQIMZIBwycmz
H1/s3F8AapfIPNF3kQk7+kw9PWBy+IZOdg5Ug3mkAATy/t0usovzGeCUWTjCz0B+Sj0ekfdvkZ3a
bBv+U4GaCtJ1iEm6ANQJ6fEzrG/engcKw/wXQvEKxSEKQxRGKE7Izt+DSiwBJMUSm71rguMYhQKr
BygOIRStf4TiFFRBvbRGKiQLWP29yRSHKBTtfdBmHs0BUpgvtgF4yRFR+NUKi0XZcYjCeCG2smkz
LAHkbRBmP0/Uk26O5YnUActBp1GsAI+S5nRJJJal5K1aAMrq0d6Tm9uI6zjyf75dAe6tx/SsWeD/
/o2/Ab6IH3/h25pOAAAAAElFTkSuQmCC";
$_IMAGES["image"] =
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0
U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGWSURBVBgZpcE/a1NhGMbh3/OeN56cKq2D
p6AoCOKmk4uCn8DNycEOIojilr2TaBfRzVnESQR3Bz+FFDoWA2IjtkRqmpyc97k9qYl/IQV7XSaJ
w4g0VlZfP0m13dwepPbuiH85fyhyWCx4/ubxjU6kkdxWHt69VC6XpZlFBAhwJgwJJHAmRKorbj94
ewvoRBrbuykvT5R2/+lLTp05Tp45STmEJYJBMAjByILxYeM9jzr3GCczGpHGYAQhRM6fO8uFy1fJ
QoaUwCKYEcwwC4QQaGUBd36KTDmQ523axTGQmEcIEBORKQfG1ZDxcA/MkBxXwj1ggCQyS9TVAMmZ
iUxJ8Ln/kS+9PmOvcSW+jrao0mmMH5bzHfa+9UGBmciUBJ+2Fmh1h+yTQCXSkJkdCrpd8btIwwEJ
QnaEkOXMk7XaiF8CUxL/JdKQOwb0Ntc5SG9zHXQNd/ZFGsaEeLa2ChjzXQcqZiKNxSL0vR4unVww
MENMCATib0ZdV+QtE41I42geXt1Ze3dlMNZFdw6Ut6CIvKBhkjiM79Pyq1YUmtkKAAAAAElFTkSu
QmCC";
$_IMAGES["textdocument"] =
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0
U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIdSURBVDjLjZO7a5RREMV/9/F9yaLBzQY3
CC7EpBGxU2O0EBG0sxHBUitTWYitYCsiiJL0NvlfgoWSRpGA4IMsm43ZXchmv8e9MxZZN1GD5MCB
W8yce4aZY1QVAGPMaWAacPwfm8A3VRUAVJWhyIUsy7plWcYQgh7GLMt0aWnpNTADWFX9Q2C+LMu4
s7Oj/X5/xF6vp51OR1utloYQtNls6vLy8kjE3Huz9qPIQjcUg/GZenVOokIEiSBBCKUSQ+TFwwa1
Wo2iKBARVlZW3iwuLr7izssPnwZ50DLIoWz9zPT+s/fabrf/GQmY97GIIXGWp28/08si5+oV1jcG
TCSO6nHH2pddYqmkaUq320VECCFQr9cBsBIVBbJcSdXQmK7Q6Qsnq54sj2gBplS896RpSpIkjI2N
jVZitdh7jAOSK6trXcpC2GjlfP1esHD+GDYozjm893jvSZJkXyAWe+ssc6W5G9naLqkaw/pGxBrl
1tVpJCrWWpxzI6GRgOQKCv2BYHPl5uUatROeSsVy7eIkU9UUiYoxBgDnHNbagw4U6yAWwpmphNvX
T6HAhAZuLNRx1iDDWzHG/L6ZEbyJVLa2c54/PgsKgyzw5MHcqKC9nROK/aaDvwN4KYS7j959DHk2
PtuYnBUBFUEVVBQRgzX7I/wNM7RmgEshhFXAcDSI9/6KHQZKAYkxDgA5SnOMcReI5kCcG8M42yM6
iMDmL261eaOOnqrOAAAAAElFTkSuQmCC";
$_IMAGES["spreadsheet"] =
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0
U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIpSURBVDjLjZNPSFRRFMZ/9707o0SOOshM
0x/JFtUmisKBooVEEUThsgi3KS0CN0G2lagWEYkSUdsRWgSFG9sVFAW1EIwQqRZiiDOZY804b967
954249hUpB98y/PjO5zzKREBQCm1E0gDPv9XHpgTEQeAiFCDHAmCoBhFkTXGyL8cBIGMjo7eA3YD
nog0ALJRFNlSqSTlcrnulZUVWV5elsXFRTHGyMLCgoyNjdUhanCyV9ayOSeIdTgnOCtY43DWYY3j
9ulxkskkYRjinCOXy40MDAzcZXCyVzZS38MeKRQKf60EZPXSXInL9y+wLZMkCMs0RR28mJ2grSWJ
Eo+lH9/IpNPE43GKxSLOOYwxpFIpAPTWjiaOtZ+gLdFKlJlD8u00xWP8lO/M5+e5efEB18b70Vqj
lMJai++vH8qLqoa+nn4+fJmiNNPCvMzQnIjzZuo1V88Ns3/HAcKKwfd9tNZorYnFYuuAMLDMfJ3m
+fQznr7L0Vk9zGpLmezB4zx++YggqhAFEZ7n4ft+HVQHVMoB5++cJNWaRrQwMjHM9qCLTFcnJJq5
9WSIMLAopQDwfR/P8+oAbaqWK2eGSGxpxVrDnvQ+3s++4tPnj4SewYscUdUgIiilcM41/uXZG9kN
z9h9aa+EYdjg+hnDwHDq+iGsaXwcZ6XhsdZW+FOqFk0B3caYt4Bic3Ja66NerVACOGttBXCbGbbW
rgJW/VbnXbU6e5tMYIH8L54Xq0cq018+AAAAAElFTkSuQmCC";
$_IMAGES["unknown"] =
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0
U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAC4SURBVCjPdZFbDsIgEEWnrsMm7oGGfZro
hxvU+Iq1TyjU60Bf1pac4Yc5YS4ZAtGWBMk/drQBOVwJlZrWYkLhsB8UV9K0BUrPGy9cWbng2CtE
EUmLGppPjRwpbixUKHBiZRS0p+ZGhvs4irNEvWD8heHpbsyDXznPhYFOyTjJc13olIqzZCHBouE0
FRMUjA+s1gTjaRgVFpqRwC8mfoXPPEVPS7LbRaJL2y7bOifRCTEli3U7BMWgLzKlW/CuebZPAAAA
AElFTkSuQmCC";
$_IMAGES["pdf"] =
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0
U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHhSURBVDjLjZPLSxtRFIfVZRdWi0oFBf+B
rhRx5dKVYKG4tLhRqlgXPmIVJQiC60JCCZYqFHQh7rrQlUK7aVUUfCBRG5RkJpNkkswrM5NEf73n
6gxpHujAB/fOvefjnHM5VQCqCPa1MNoZnU/Qxqhx4woE7ZZlpXO53F0+n0c52Dl8Pt/nQkmhoJOC
dUWBsvQJ2u4ODMOAwvapVAqSJHGJKIrw+/2uxAmuJgFdMDUVincSxvEBTNOEpmlIp9OIxWJckMlk
oOs6AoHAg6RYYNs2kp4RqOvfuIACVFVFPB4vKYn3pFjAykDSOwVta52vqW6nlEQiwTMRBKGygIh9
GEDCMwZH6EgoE+qHLMuVBdbfKwjv3yE6Ogjz/PQ/CZVDPSFRRYE4/RHy1y8wry8RGWGSqyC/nM1m
eX9IQpQV2JKIUH8vrEgYmeAFwuPDCHa9QehtD26HBhCZnYC8ucGzKSsIL8wgsjiH1PYPxL+vQvm5
B/3sBMLyIm7GhhCe90BaWykV/Gp+VR9oqPVe9vfBTsruM1HtBKVPmFIUNusBrV3B4ev6bsbyXlPd
kbr/u+StHUkxruBPY+0KY8f38oWX/byvNAdluHNLeOxDB+uyQQfPCWZ3NT69BYJWkjxjnB1o9Fv/
ASQ5s+ABz8i2AAAAAElFTkSuQmCC";
$_IMAGES["webpage"] =
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0
U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJwSURBVDjLjZPdT1JhHMetvyO3/gfLKy+6
8bLV2qIAq7UyG6IrdRPL5hs2U5FR0MJIAqZlh7BVViI1kkyyiPkCyUtztQYTYbwJE8W+Pc8pjofK
1dk+OxfP+X3O83srAVBCIc8eQhmh/B/sJezm4niCsvX19cTm5uZWPp/H3yDnUKvVKr6ELyinwWtr
a8hkMhzJZBLxeBwrKyusJBwOQ6PRcJJC8K4DJ/dXM04DOswNqNOLybsRo9N6LCy7kUgkEIlEWEE2
mwX9iVar/Smhglqd8IREKwya3qhg809gPLgI/XsrOp/IcXVMhqnFSayurv6RElsT6ZCoov5u1fzU
VwvcKRdefVuEKRCA3OFHv2MOxtlBdFuaMf/ZhWg0yt4kFAoVCZS3Hd1gkpOwRt9h0LOES3YvamzP
cdF7A6rlPrSbpbhP0kmlUmw9YrHYtoDku2T6pEZ/2ICXEQ8kTz+g2TkNceAKKv2nIHachn6qBx1M
I5t/Op1mRXzBd31AiRafBp1vZyEcceGCzQ6p24yjEzocGT6LUacS0iExcrkcK6Fsp6AXLRnmFOjy
PMIZixPHmAAOGxZQec2OQyo7zpm6cNN6GZ2kK1RAofPAr8GA4oUMrdNNkIw/wPFhDwSjX3Dwlg0C
Qy96HreiTlcFZsaAjY0NNvh3QUXtHeHcoKMNA7NjqLd8xHmzDzXDRvRO1KHtngTyhzL4SHeooAAn
KMxBtUYQbGWa0Dc+AsWzSVy3qkjeItLCFsz4XoNMaRFFAm4SyTXbmQa2YHQSGacR/pAXO+zGFif4
JdlHCpShBzstEz+YfJtmt5cnKKWS/1jnAnT1S38AGTynUFUTzJcAAAAASUVORK5CYII=";
$_IMAGES["txt"] =
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0
U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADoSURBVBgZBcExblNBGAbA2ceegTRBuIKO
giihSZNTcC5LUHAihNJR0kGKCDcYJY6D3/77MdOinTvzAgCw8ysThIvn/VojIyMjIyPP+bS1sUQI
V2s95pBDDvmbP/mdkft83tpYguZq5Jh/OeaYh+yzy8hTHvNlaxNNczm+la9OTlar1UdA/+C2A4tr
RCnD3jS8BB1obq2Gk6GU6QbQAS4BUaYSQAf4bhhKKTFdAzrAOwAxEUAH+KEM01SY3gM6wBsEAQB0
gJ+maZoC3gI6iPYaAIBJsiRmHU0AALOeFC3aK2cWAACUXe7+AwO0lc9eTHYTAAAAAElFTkSuQmCC";
$_IMAGES["doc"] = $_IMAGES["textdocument"];
$_IMAGES["docx"] = $_IMAGES["textdocument"];
$_IMAGES["odt"] = $_IMAGES["textdocument"];
$_IMAGES["xls"] = $_IMAGES["spreadsheet"];
$_IMAGES["xlsx"] = $_IMAGES["spreadsheet"];
$_IMAGES["htm"] = $_IMAGES["webpage"];
$_IMAGES["html"] = $_IMAGES["webpage"];
$_IMAGES["jpg"] = $_IMAGES["image"];
$_IMAGES["jpeg"] = $_IMAGES["image"];
$_IMAGES["png"] = $_IMAGES["image"];
/***************************************************************************
* PHP code
***************************************************************************/
// thanks: stackoverflow
function getScriptUrlWithoutQuery()
{
$uri = $_SERVER['REQUEST_URI'];
if (strpos($uri, "?") !== false) {
$uriSplit = explode("?", $uri);
$uri = $uriSplit[0];
}
if (isset($_SERVER['HTTPS'])) {
$protocol = ($_SERVER['HTTPS'] && $_SERVER['HTTPS'] != "off") ? "https" : "http";
} else {
$protocol = 'http';
}
return $protocol . "://" . $_SERVER['HTTP_HOST'] . $uri;
}
function getScriptUrlWithQuery()
{
return getScriptUrlWithoutQuery() . "?" . $_SERVER['QUERY_STRING'];
}
function getScriptRootDir() {
$parts = explode("/", $_SERVER['SCRIPT_NAME']);
return $parts[sizeof($parts)-2];
}
// thanks http://www.php.net/manual/en/ref.bc.php
function bchexdec($hex)
{
if (strlen($hex) == 1) {
return hexdec($hex);
} else {
$remain = substr($hex, 0, -1);
$last = substr($hex, -1);
return bcadd(bcmul(16, bchexdec($remain)), hexdec($last));
}
}
function documin_file_hash($filePath)
{
$hashType = Documin::getConfig("hash_type");
$md5sum = md5_file($filePath);
if ($hashType == "md5int32") {
return bcmod(bchexdec($md5sum), strval(pow(2,31)));
}
else if ($hashType == "md5int64") {
return bcmod(bchexdec($md5sum), strval(pow(2,63)));
}
else {
return $md5sum;
}
}
//
// The class that displays images (icons).
//
class ImageServer
{
//
// Checks if an image is requested and displays one if needed
//
public static function handleImageRequest()
{
global $_IMAGES;
if (isset($_GET['img'])) {
if (strlen($_GET['img']) > 0) {
$mtime = gmdate('r', filemtime($_SERVER['SCRIPT_FILENAME']));
$etag = md5($mtime . $_SERVER['SCRIPT_FILENAME']);
if ((isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $_SERVER['HTTP_IF_MODIFIED_SINCE'] == $mtime) ||
(isset($_SERVER['HTTP_IF_NONE_MATCH']) && str_replace('"', '', stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])) == $etag)) {
header('HTTP/1.1 304 Not Modified');
return true;
} else {
$contentType = $_IMAGES_CONTENT_TYPE_DEFAULT;
if (isset($_IMAGES[$_GET['img']]) && isset($_IMAGES_CONTENT_TYPE[$_GET['img']])) {
$contentType = $_IMAGES_CONTENT_TYPE[$_GET['img']];
}
header('ETag: "' . $etag . '"');
header('Last-Modified: ' . $mtime);
header('Content-type: image/' . $contentType);
if (isset($_IMAGES[$_GET['img']]))
print base64_decode($_IMAGES[$_GET['img']]);
else
print base64_decode($_IMAGES["unknown"]);
}
}
return true;
}
return false;
}
}
//
// Database utility class.
//
class Database
{
const SQL_CREATE_DATABASE = "
CREATE TABLE IF NOT EXISTS history (id INTEGER PRIMARY KEY ASC, path TEXT, op TEXT, undone BOOLEAN, timestamp INTEGER);
CREATE TABLE IF NOT EXISTS file (id TEXT, size INTEGER, path TEXT);
CREATE INDEX IF NOT EXISTS file_id_idx ON file(id);
CREATE UNIQUE INDEX IF NOT EXISTS file_path_idx ON file(path);
";
const SQL_INSERT_HISTORY = "INSERT INTO history (path, op, undone, timestamp) VALUES (?, ?, 0, strftime('%s'))";
// select last file upload operation if it is not more than undo_time_limit_seconds minutes old
const SQL_SELECT_LAST_HISTORY = "SELECT id FROM (SELECT id, op, timestamp FROM history WHERE undone=0 ORDER BY id DESC LIMIT 1) WHERE op='uploadfile' AND strftime('%s') - timestamp < CAST(? AS INTEGER)";
const SQL_SELECT_PATH_HISTORY = "SELECT path FROM history WHERE id=?";
const SQL_SELECT_DELTAT_HISTORY = "SELECT strftime('%s') - timestamp FROM history WHERE id=?";
const SQL_UPDATE_HISTORY_UNDONE = "UPDATE history SET undone=1 WHERE id=?";
const SQL_INSERT_FILE = "INSERT INTO file VALUES (?, ?, ?)";
const SQL_SELECT_FILE = "SELECT path FROM file WHERE id=? LIMIT 100";
const SQL_SELECT_PATH = "SELECT id FROM file WHERE path=?";
const SQL_DELETE_FILE_BY_PATH = "DELETE FROM file WHERE path=?";
const SQL_COUNT_FILES = "SELECT count(id) FROM file";
const SQL_SUM_SIZE_FILES = "SELECT sum(size) FROM file";
public static function handleRemoveRequest()
{
if (isset($_GET['do_remove_database'])) {
$dbfilename = Documin::getConfig('dbfile');
if (unlink($dbfilename)) {
print("successfully removed $dbfilename");
} else {
print("failed to remove $dbfilename");
}
return true;
}
return false;
}
private $db = null;
private $insertFileStmnt = null;
private $selectFileStmnt = null;
private $selectPathStmnt = null;
private $insertHistoryStmnt = null;
public function __construct()
{
$this->db = new PDO("sqlite:" . Documin::getConfig('dbfile'));
$this->db->exec(self::SQL_CREATE_DATABASE);
}
public function addFileRecord($id, $size, $path)
{
if ($this->insertFileStmnt == null) {
$this->insertFileStmnt = $this->db->prepare(self::SQL_INSERT_FILE);
}
$this->insertFileStmnt->execute(array($id, $size, $path));
}
public function getFileId($path)
{
if ($this->selectPathStmnt == null) {
$this->selectPathStmnt = $this->db->prepare(self::SQL_SELECT_PATH);
}
$this->selectPathStmnt->execute(array(
$path
));
$all = $this->selectPathStmnt->fetchAll(PDO::FETCH_COLUMN, 0);
if (count($all) == 0) {
return null;
} else {
assert(count($all) == 1);
return $all[0];
}
}
public function getFilePaths($id)
{
if ($this->selectFileStmnt == null) {
$this->selectFileStmnt = $this->db->prepare(self::SQL_SELECT_FILE);
}
$this->selectFileStmnt->execute(array($id));
return $this->selectFileStmnt->fetchAll(PDO::FETCH_COLUMN, 0);
}
public function getFileCount() {
return $this->db->query(self::SQL_COUNT_FILES)->fetchColumn();
}
public function getSumSize() {
return $this->db->query(self::SQL_SUM_SIZE_FILES)->fetchColumn();
}
public function addUploadHistory($uploadFilePath)
{
if ($this->insertHistoryStmnt == null) {
$this->insertHistoryStmnt = $this->db->prepare(self::SQL_INSERT_HISTORY);
}
$this->insertHistoryStmnt->execute(array($uploadFilePath, "uploadfile"));
}
private function fetchAllFirstResult($stmnt) {
$all = $stmnt->fetchAll(PDO::FETCH_COLUMN, 0);
if (count($all) == 0) {
return null;
} else {
assert(count($all) == 1);
return $all[0];
}
}
public function getLastUploadForUndoIfExists() {
$stmnt = $this->db->prepare( self::SQL_SELECT_LAST_HISTORY );
$stmnt->execute(array(Documin::getConfig('undo_time_limit_seconds')));
return $this->fetchAllFirstResult($stmnt);
}
public function getHistoryPathById($id) {
$stmnt = $this->db->prepare(self::SQL_SELECT_PATH_HISTORY);
$stmnt->execute(array($id));
return $this->fetchAllFirstResult($stmnt);
}
public function getUndoTimeRemaining($id) {
$stmnt = $this->db->prepare(self::SQL_SELECT_DELTAT_HISTORY);
$stmnt->execute(array($id));
$time = $this->fetchAllFirstResult($stmnt);
return Documin::getConfig('undo_time_limit_seconds') - $time;
}
public function deleteFileByPath($path) {
$stmnt = $this->db->prepare(self::SQL_DELETE_FILE_BY_PATH);
$stmnt->execute(array($path));
}
public function undoHistoryById($id) {
$stmnt = $this->db->prepare(self::SQL_UPDATE_HISTORY_UNDONE);
$stmnt->execute(array($id));
}
}
//
// File upload and new directory create.
//
class FileManager
{
var $database;
public static function handleFileRequest() {
$location = new Location();
$fm = new FileManager();
$fm->run($location);
}
function __construct() {
$this->database = new Database();
}
function newFolder($location, $dirname)
{
if (strlen($dirname) > 0) {
$forbidden = array(
".",
"/",
"\\"
);
for ($i = 0; $i < count($forbidden); $i++) {
$dirname = str_replace($forbidden[$i], "", $dirname);
}
if (!$location->uploadAllowed()) {
// The system configuration does not allow uploading here
Documin::setErrorString("upload_not_allowed");
return;
}
if (!$location->isWritable()) {
// The target directory is not writable
Documin::setErrorString("upload_dir_not_writable");
return;
}
$newDirPath = $location->getDir(true, false, false, 0) . $dirname;
if (!mkdir($newDirPath)) {
// Error creating a new directory
Documin::setErrorString("new_dir_failed");
return;
}
// Add a history record for this operation.
$this->database->addUploadHistory($newDirPath);
}
}
function uploadFile($location, $userfile)
{
$name = basename($userfile['name']);
$upload_dir = $location->getFullPath();
$upload_file = $upload_dir . $name;
if (function_exists("finfo_open") && function_exists("finfo_file"))
$mime_type = File::getFileMime($userfile['tmp_name']);
else
$mime_type = $userfile['type'];
$extension = File::getFileExtension($userfile['name']);
if (!$location->uploadAllowed()) {
Documin::setErrorString("upload_not_allowed");
} else if (!$location->isWritable()) {
Documin::setErrorString("upload_dir_not_writable");
} else if (!is_uploaded_file($userfile['tmp_name'])) {
Documin::setErrorString("failed_upload");
} else if (is_array(Documin::getConfig("upload_allow_type")) && count(Documin::getConfig("upload_allow_type")) > 0 && !in_array($mime_type, Documin::getConfig("upload_allow_type"))) {
Documin::setErrorString("upload_type_not_allowed");