1: <?php
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: define( 'ARCHIVE_ZIP_READ_BLOCK_SIZE', 2048 );
32:
33:
34: define( 'ARCHIVE_ZIP_SEPARATOR', ',' );
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45: define( 'ARCHIVE_ZIP_TEMPORARY_DIR', '' );
46:
47:
48: define( 'ARCHIVE_ZIP_ERR_NO_ERROR', 0 );
49: define( 'ARCHIVE_ZIP_ERR_WRITE_OPEN_FAIL', -1 );
50: define( 'ARCHIVE_ZIP_ERR_READ_OPEN_FAIL', -2 );
51: define( 'ARCHIVE_ZIP_ERR_INVALID_PARAMETER', -3 );
52: define( 'ARCHIVE_ZIP_ERR_MISSING_FILE', -4 );
53: define( 'ARCHIVE_ZIP_ERR_FILENAME_TOO_LONG', -5 );
54: define( 'ARCHIVE_ZIP_ERR_INVALID_ZIP', -6 );
55: define( 'ARCHIVE_ZIP_ERR_BAD_EXTRACTED_FILE', -7 );
56: define( 'ARCHIVE_ZIP_ERR_DIR_CREATE_FAIL', -8 );
57: define( 'ARCHIVE_ZIP_ERR_BAD_EXTENSION', -9 );
58: define( 'ARCHIVE_ZIP_ERR_BAD_FORMAT', -10 );
59: define( 'ARCHIVE_ZIP_ERR_DELETE_FILE_FAIL', -11 );
60: define( 'ARCHIVE_ZIP_ERR_RENAME_FILE_FAIL', -12 );
61: define( 'ARCHIVE_ZIP_ERR_BAD_CHECKSUM', -13 );
62: define( 'ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
63: define( 'ARCHIVE_ZIP_ERR_MISSING_OPTION_VALUE', -15 );
64: define( 'ARCHIVE_ZIP_ERR_INVALID_PARAM_VALUE', -16 );
65:
66:
67: define( 'ARCHIVE_ZIP_WARN_NO_WARNING', 0 );
68: define( 'ARCHIVE_ZIP_WARN_FILE_EXIST', 1 );
69:
70:
71: define( 'ARCHIVE_ZIP_PARAM_PATH', 'path' );
72: define( 'ARCHIVE_ZIP_PARAM_ADD_PATH', 'add_path' );
73: define( 'ARCHIVE_ZIP_PARAM_REMOVE_PATH', 'remove_path' );
74: define( 'ARCHIVE_ZIP_PARAM_REMOVE_ALL_PATH', 'remove_all_path' );
75: define( 'ARCHIVE_ZIP_PARAM_SET_CHMOD', 'set_chmod' );
76: define( 'ARCHIVE_ZIP_PARAM_EXTRACT_AS_STRING', 'extract_as_string' );
77: define( 'ARCHIVE_ZIP_PARAM_NO_COMPRESSION', 'no_compression' );
78: define( 'ARCHIVE_ZIP_PARAM_BY_NAME', 'by_name' );
79: define( 'ARCHIVE_ZIP_PARAM_BY_INDEX', 'by_index' );
80: define( 'ARCHIVE_ZIP_PARAM_BY_EREG', 'by_ereg' );
81: define( 'ARCHIVE_ZIP_PARAM_BY_PREG', 'by_preg' );
82:
83: define( 'ARCHIVE_ZIP_PARAM_PRE_EXTRACT', 'callback_pre_extract' );
84: define( 'ARCHIVE_ZIP_PARAM_POST_EXTRACT', 'callback_post_extract' );
85: define( 'ARCHIVE_ZIP_PARAM_PRE_ADD', 'callback_pre_add' );
86: define( 'ARCHIVE_ZIP_PARAM_POST_ADD', 'callback_post_add' );
87:
88:
89:
90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101:
102: class Archive_Zip
103: {
104: 105: 106: 107: 108:
109: var $_zipname='';
110:
111: 112: 113: 114: 115:
116: var $_zip_fd=0;
117:
118: 119: 120:
121: var $_error_code=1;
122:
123: 124: 125:
126: var $_error_string='';
127:
128:
129: 130: 131: 132: 133: 134: 135: 136:
137: function Archive_Zip($p_zipname)
138: {
139:
140:
141: 142: 143:
144: if (!extension_loaded('zlib')) {
145: die("The extension 'zlib' couldn't be found.\n".
146: "Please make sure your version of PHP was built ".
147: "with 'zlib' support.\n");
148: return false;
149: }
150:
151:
152: $this->_zipname = $p_zipname;
153: $this->_zip_fd = 0;
154:
155: return;
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: function create($p_filelist, $p_params=0)
183: {
184: $this->_errorReset();
185:
186:
187: if ($p_params === 0) {
188: $p_params = array();
189: }
190: if ($this->_check_parameters($p_params,
191: array('no_compression' => false,
192: 'add_path' => "",
193: 'remove_path' => "",
194: 'remove_all_path' => false)) != 1) {
195: return 0;
196: }
197:
198:
199: $p_result_list = array();
200: if (is_array($p_filelist)) {
201: $v_result = $this->_create($p_filelist, $p_result_list, $p_params);
202: }
203:
204:
205: else if (is_string($p_filelist)) {
206:
207: $v_list = explode(ARCHIVE_ZIP_SEPARATOR, $p_filelist);
208:
209: $v_result = $this->_create($v_list, $p_result_list, $p_params);
210: }
211:
212:
213: else {
214: $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER,
215: 'Invalid variable type p_filelist');
216: $v_result = ARCHIVE_ZIP_ERR_INVALID_PARAMETER;
217: }
218:
219: if ($v_result != 1) {
220: return 0;
221: }
222:
223: return $p_result_list;
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: function add($p_filelist, $p_params=0)
254: {
255: $this->_errorReset();
256:
257:
258: if ($p_params === 0) {
259: $p_params = array();
260: }
261: if ($this->_check_parameters($p_params,
262: array ('no_compression' => false,
263: 'add_path' => '',
264: 'remove_path' => '',
265: 'remove_all_path' => false,
266: 'callback_pre_add' => '',
267: 'callback_post_add' => '')) != 1) {
268: return 0;
269: }
270:
271:
272: $p_result_list = array();
273: if (is_array($p_filelist)) {
274:
275: $v_result = $this->_add($p_filelist, $p_result_list, $p_params);
276: }
277:
278:
279: else if (is_string($p_filelist)) {
280:
281: $v_list = explode(ARCHIVE_ZIP_SEPARATOR, $p_filelist);
282:
283:
284: $v_result = $this->_add($v_list, $p_result_list, $p_params);
285: }
286:
287:
288: else {
289: $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER,
290: "add() : Invalid variable type p_filelist");
291: $v_result = ARCHIVE_ZIP_ERR_INVALID_PARAMETER;
292: }
293:
294: if ($v_result != 1) {
295: return 0;
296: }
297:
298:
299: return $p_result_list;
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: function listContent()
348: {
349: $this->_errorReset();
350:
351:
352: if (!$this->_checkFormat()) {
353: return(0);
354: }
355:
356: $v_list = array();
357: if ($this->_list($v_list) != 1) {
358: unset($v_list);
359: return(0);
360: }
361:
362: return $v_list;
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: function extract($p_params=0)
405: {
406:
407: $this->_errorReset();
408:
409:
410: if (!$this->_checkFormat()) {
411: return(0);
412: }
413:
414:
415: if ($p_params === 0) {
416: $p_params = array();
417: }
418: if ($this->_check_parameters($p_params,
419: array ('extract_as_string' => false,
420: 'add_path' => '',
421: 'remove_path' => '',
422: 'remove_all_path' => false,
423: 'callback_pre_extract' => '',
424: 'callback_post_extract' => '',
425: 'set_chmod' => 0,
426: 'by_name' => '',
427: 'by_index' => '',
428: 'by_ereg' => '',
429: 'by_preg' => '') ) != 1) {
430: return 0;
431: }
432:
433:
434: $v_list = array();
435: if ($this->_extractByRule($v_list, $p_params) != 1) {
436: unset($v_list);
437: return(0);
438: }
439:
440: return $v_list;
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: function delete($p_params)
468: {
469: $this->_errorReset();
470:
471:
472: if (!$this->_checkFormat()) {
473: return(0);
474: }
475:
476:
477: if ($this->_check_parameters($p_params,
478: array ('by_name' => '',
479: 'by_index' => '',
480: 'by_ereg' => '',
481: 'by_preg' => '') ) != 1) {
482: return 0;
483: }
484:
485:
486: if ( ($p_params['by_name'] == '')
487: && ($p_params['by_index'] == '')
488: && ($p_params['by_ereg'] == '')
489: && ($p_params['by_preg'] == '')) {
490: $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER,
491: 'At least one filtering rule must'
492: .' be set as parameter');
493: return 0;
494: }
495:
496:
497: $v_list = array();
498: if ($this->_deleteByRule($v_list, $p_params) != 1) {
499: unset($v_list);
500: return(0);
501: }
502:
503: return $v_list;
504: }
505:
506:
507:
508: 509: 510: 511: 512: 513: 514: 515: 516: 517: 518:
519: function properties()
520: {
521: $this->_errorReset();
522:
523:
524: if (!$this->_checkFormat()) {
525: return(0);
526: }
527:
528:
529: $v_prop = array();
530: $v_prop['comment'] = '';
531: $v_prop['nb'] = 0;
532: $v_prop['status'] = 'not_exist';
533:
534:
535: if (@is_file($this->_zipname)) {
536:
537: if (($this->_zip_fd = @fopen($this->_zipname, 'rb')) == 0) {
538: $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL,
539: 'Unable to open archive \''.$this->_zipname
540: .'\' in binary read mode');
541: return 0;
542: }
543:
544:
545: $v_central_dir = array();
546: if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) {
547: return 0;
548: }
549:
550: $this->_closeFd();
551:
552:
553: $v_prop['comment'] = $v_central_dir['comment'];
554: $v_prop['nb'] = $v_central_dir['entries'];
555: $v_prop['status'] = 'ok';
556: }
557:
558: return $v_prop;
559: }
560:
561:
562:
563:
564: 565: 566: 567: 568: 569: 570: 571: 572: 573:
574: function duplicate($p_archive)
575: {
576: $this->_errorReset();
577:
578:
579: if ( (is_object($p_archive))
580: && (strtolower(get_class($p_archive)) == 'archive_zip')) {
581: $v_result = $this->_duplicate($p_archive->_zipname);
582: }
583:
584:
585: else if (is_string($p_archive)) {
586:
587:
588: if (!is_file($p_archive)) {
589: $this->_errorLog(ARCHIVE_ZIP_ERR_MISSING_FILE,
590: "No file with filename '".$p_archive."'");
591: $v_result = ARCHIVE_ZIP_ERR_MISSING_FILE;
592: }
593: else {
594: $v_result = $this->_duplicate($p_archive);
595: }
596: }
597:
598:
599: else {
600: $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER,
601: "Invalid variable type p_archive_to_add");
602: $v_result = ARCHIVE_ZIP_ERR_INVALID_PARAMETER;
603: }
604:
605: return $v_result;
606: }
607:
608:
609:
610: 611: 612: 613: 614: 615: 616: 617: 618: 619: 620:
621: function merge($p_archive_to_add)
622: {
623: $v_result = 1;
624: $this->_errorReset();
625:
626:
627: if (!$this->_checkFormat()) {
628: return(0);
629: }
630:
631:
632: if ( (is_object($p_archive_to_add))
633: && (strtolower(get_class($p_archive_to_add)) == 'archive_zip')) {
634: $v_result = $this->_merge($p_archive_to_add);
635: }
636:
637:
638: else if (is_string($p_archive_to_add)) {
639:
640: $v_object_archive = new Archive_Zip($p_archive_to_add);
641:
642:
643: $v_result = $this->_merge($v_object_archive);
644: }
645:
646:
647: else {
648: $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER,
649: "Invalid variable type p_archive_to_add");
650: $v_result = ARCHIVE_ZIP_ERR_INVALID_PARAMETER;
651: }
652:
653: return $v_result;
654: }
655:
656:
657:
658: 659: 660: 661: 662: 663:
664: function errorCode()
665: {
666: return($this->_error_code);
667: }
668:
669:
670:
671: 672: 673: 674: 675: 676: 677:
678: function errorName($p_with_code=false)
679: {
680: $v_const_list = get_defined_constants();
681:
682:
683: for (reset($v_const_list);
684: list($v_key, $v_value) = each($v_const_list);) {
685: if (substr($v_key, 0, strlen('ARCHIVE_ZIP_ERR_'))
686: =='ARCHIVE_ZIP_ERR_') {
687: $v_error_list[$v_key] = $v_value;
688: }
689: }
690:
691:
692: $v_key=array_search($this->_error_code, $v_error_list, true);
693: if ($v_key!=false) {
694: $v_value = $v_key;
695: }
696: else {
697: $v_value = 'NoName';
698: }
699:
700: if ($p_with_code) {
701: return($v_value.' ('.$this->_error_code.')');
702: }
703: else {
704: return($v_value);
705: }
706: }
707:
708:
709:
710: 711: 712: 713: 714: 715: 716: 717: 718: 719:
720: function errorInfo($p_full=false)
721: {
722: if ($p_full) {
723: return($this->errorName(true)." : ".$this->_error_string);
724: }
725: else {
726: return($this->_error_string." [code ".$this->_error_code."]");
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: function _checkFormat($p_level=0)
760: {
761: $v_result = true;
762:
763:
764: $this->_errorReset();
765:
766:
767: if (!is_file($this->_zipname)) {
768:
769: $this->_errorLog(ARCHIVE_ZIP_ERR_MISSING_FILE,
770: "Missing archive file '".$this->_zipname."'");
771: return(false);
772: }
773:
774:
775: if (!is_readable($this->_zipname)) {
776:
777: $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL,
778: "Unable to read archive '".$this->_zipname."'");
779: return(false);
780: }
781:
782:
783:
784:
785:
786:
787:
788:
789:
790:
791:
792: return $v_result;
793: }
794:
795:
796:
797:
798:
799:
800:
801:
802: 803: 804: 805: 806: 807:
808: function _create($p_list, &$p_result_list, &$p_params)
809: {
810: $v_result=1;
811: $v_list_detail = array();
812:
813: $p_add_dir = $p_params['add_path'];
814: $p_remove_dir = $p_params['remove_path'];
815: $p_remove_all_dir = $p_params['remove_all_path'];
816:
817:
818: if (($v_result = $this->_openFd('wb')) != 1)
819: {
820:
821: return $v_result;
822: }
823:
824:
825: $v_result = $this->_addList($p_list, $p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_params);
826:
827:
828: $this->_closeFd();
829:
830:
831: return $v_result;
832: }
833:
834:
835:
836:
837:
838:
839:
840:
841: 842: 843: 844: 845: 846:
847: function _add($p_list, &$p_result_list, &$p_params)
848: {
849: $v_result=1;
850: $v_list_detail = array();
851:
852: $p_add_dir = $p_params['add_path'];
853: $p_remove_dir = $p_params['remove_path'];
854: $p_remove_all_dir = $p_params['remove_all_path'];
855:
856:
857: if ((!is_file($this->_zipname)) || (filesize($this->_zipname) == 0)) {
858: $v_result = $this->_create($p_list, $p_result_list, $p_params);
859: return $v_result;
860: }
861:
862:
863: if (($v_result=$this->_openFd('rb')) != 1) {
864: return $v_result;
865: }
866:
867:
868: $v_central_dir = array();
869: if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1)
870: {
871: $this->_closeFd();
872: return $v_result;
873: }
874:
875:
876: @rewind($this->_zip_fd);
877:
878:
879: $v_zip_temp_name = ARCHIVE_ZIP_TEMPORARY_DIR.uniqid('archive_zip-').'.tmp';
880:
881:
882: if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
883: {
884: $this->_closeFd();
885:
886: $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL,
887: 'Unable to open temporary file \''
888: .$v_zip_temp_name.'\' in binary write mode');
889: return Archive_Zip::errorCode();
890: }
891:
892:
893:
894:
895: $v_size = $v_central_dir['offset'];
896: while ($v_size != 0)
897: {
898: $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
899: ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
900: $v_buffer = fread($this->_zip_fd, $v_read_size);
901: @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
902: $v_size -= $v_read_size;
903: }
904:
905:
906:
907:
908: $v_swap = $this->_zip_fd;
909: $this->_zip_fd = $v_zip_temp_fd;
910: $v_zip_temp_fd = $v_swap;
911:
912:
913: $v_header_list = array();
914: if (($v_result = $this->_addFileList($p_list, $v_header_list,
915: $p_add_dir, $p_remove_dir,
916: $p_remove_all_dir, $p_params)) != 1)
917: {
918: fclose($v_zip_temp_fd);
919: $this->_closeFd();
920: @unlink($v_zip_temp_name);
921:
922:
923: return $v_result;
924: }
925:
926:
927: $v_offset = @ftell($this->_zip_fd);
928:
929:
930: $v_size = $v_central_dir['size'];
931: while ($v_size != 0)
932: {
933: $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
934: ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
935: $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
936: @fwrite($this->_zip_fd, $v_buffer, $v_read_size);
937: $v_size -= $v_read_size;
938: }
939:
940:
941: for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
942: {
943:
944: if ($v_header_list[$i]['status'] == 'ok') {
945: if (($v_result=$this->_writeCentralFileHeader($v_header_list[$i]))!=1) {
946: fclose($v_zip_temp_fd);
947: $this->_closeFd();
948: @unlink($v_zip_temp_name);
949:
950:
951: return $v_result;
952: }
953: $v_count++;
954: }
955:
956:
957: $this->_convertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
958: }
959:
960:
961: $v_comment = '';
962:
963:
964: $v_size = @ftell($this->_zip_fd)-$v_offset;
965:
966:
967: if (($v_result = $this->_writeCentralHeader($v_count
968: +$v_central_dir['entries'],
969: $v_size, $v_offset,
970: $v_comment)) != 1) {
971:
972: unset($v_header_list);
973:
974:
975: return $v_result;
976: }
977:
978:
979: $v_swap = $this->_zip_fd;
980: $this->_zip_fd = $v_zip_temp_fd;
981: $v_zip_temp_fd = $v_swap;
982:
983:
984: $this->_closeFd();
985:
986:
987: @fclose($v_zip_temp_fd);
988:
989:
990:
991: @unlink($this->_zipname);
992:
993:
994:
995:
996: $this->_tool_Rename($v_zip_temp_name, $this->_zipname);
997:
998:
999: return $v_result;
1000: }
1001:
1002:
1003:
1004:
1005:
1006:
1007:
1008: 1009: 1010: 1011: 1012: 1013:
1014: function _openFd($p_mode)
1015: {
1016: $v_result=1;
1017:
1018:
1019: if ($this->_zip_fd != 0)
1020: {
1021: $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL,
1022: 'Zip file \''.$this->_zipname.'\' already open');
1023: return Archive_Zip::errorCode();
1024: }
1025:
1026:
1027: if (($this->_zip_fd = @fopen($this->_zipname, $p_mode)) == 0)
1028: {
1029: $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL,
1030: 'Unable to open archive \''.$this->_zipname
1031: .'\' in '.$p_mode.' mode');
1032: return Archive_Zip::errorCode();
1033: }
1034:
1035:
1036: return $v_result;
1037: }
1038:
1039:
1040:
1041:
1042:
1043:
1044:
1045: 1046: 1047: 1048: 1049: 1050:
1051: function _closeFd()
1052: {
1053: $v_result=1;
1054:
1055: if ($this->_zip_fd != 0)
1056: @fclose($this->_zip_fd);
1057: $this->_zip_fd = 0;
1058:
1059:
1060: return $v_result;
1061: }
1062:
1063:
1064:
1065:
1066:
1067:
1068:
1069:
1070:
1071:
1072:
1073:
1074:
1075:
1076:
1077: 1078: 1079: 1080: 1081: 1082:
1083: function _addList($p_list, &$p_result_list,
1084: $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_params)
1085: {
1086: $v_result=1;
1087:
1088:
1089: $v_header_list = array();
1090: if (($v_result = $this->_addFileList($p_list, $v_header_list,
1091: $p_add_dir, $p_remove_dir,
1092: $p_remove_all_dir, $p_params)) != 1) {
1093: return $v_result;
1094: }
1095:
1096:
1097: $v_offset = @ftell($this->_zip_fd);
1098:
1099:
1100: for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
1101: {
1102:
1103: if ($v_header_list[$i]['status'] == 'ok') {
1104: if (($v_result = $this->_writeCentralFileHeader($v_header_list[$i])) != 1) {
1105: return $v_result;
1106: }
1107: $v_count++;
1108: }
1109:
1110:
1111: $this->_convertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
1112: }
1113:
1114:
1115: $v_comment = '';
1116:
1117:
1118: $v_size = @ftell($this->_zip_fd)-$v_offset;
1119:
1120:
1121: if (($v_result = $this->_writeCentralHeader($v_count, $v_size, $v_offset,
1122: $v_comment)) != 1)
1123: {
1124:
1125: unset($v_header_list);
1126:
1127:
1128: return $v_result;
1129: }
1130:
1131:
1132: return $v_result;
1133: }
1134:
1135:
1136:
1137:
1138:
1139:
1140:
1141:
1142:
1143:
1144:
1145:
1146:
1147:
1148:
1149: 1150: 1151: 1152: 1153: 1154:
1155: function _addFileList($p_list, &$p_result_list,
1156: $p_add_dir, $p_remove_dir, $p_remove_all_dir,
1157: &$p_params)
1158: {
1159: $v_result=1;
1160: $v_header = array();
1161:
1162:
1163: $v_nb = sizeof($p_result_list);
1164:
1165:
1166: for ($j=0; ($j<count($p_list)) && ($v_result==1); $j++)
1167: {
1168:
1169: $p_filename = $this->_tool_TranslateWinPath($p_list[$j], false);
1170:
1171:
1172: if ($p_filename == "")
1173: {
1174: continue;
1175: }
1176:
1177:
1178: if (!file_exists($p_filename))
1179: {
1180: $this->_errorLog(ARCHIVE_ZIP_ERR_MISSING_FILE,
1181: "File '$p_filename' does not exists");
1182: return Archive_Zip::errorCode();
1183: }
1184:
1185:
1186: if ((is_file($p_filename)) || ((is_dir($p_filename)) && !$p_remove_all_dir)) {
1187:
1188: if (($v_result = $this->_addFile($p_filename, $v_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_params)) != 1)
1189: {
1190:
1191: return $v_result;
1192: }
1193:
1194:
1195: $p_result_list[$v_nb++] = $v_header;
1196: }
1197:
1198:
1199: if (is_dir($p_filename))
1200: {
1201:
1202:
1203: if ($p_filename != ".")
1204: $v_path = $p_filename."/";
1205: else
1206: $v_path = "";
1207:
1208:
1209: $p_hdir = opendir($p_filename);
1210: $p_hitem = readdir($p_hdir);
1211: $p_hitem = readdir($p_hdir);
1212: while ($p_hitem = readdir($p_hdir))
1213: {
1214:
1215:
1216: if (is_file($v_path.$p_hitem))
1217: {
1218:
1219:
1220: if (($v_result = $this->_addFile($v_path.$p_hitem, $v_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_params)) != 1)
1221: {
1222:
1223: return $v_result;
1224: }
1225:
1226:
1227: $p_result_list[$v_nb++] = $v_header;
1228: }
1229:
1230:
1231: else
1232: {
1233:
1234:
1235: $p_temp_list[0] = $v_path.$p_hitem;
1236: $v_result = $this->_addFileList($p_temp_list, $p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_params);
1237:
1238:
1239: $v_nb = sizeof($p_result_list);
1240: }
1241: }
1242:
1243:
1244: unset($p_temp_list);
1245: unset($p_hdir);
1246: unset($p_hitem);
1247: }
1248: }
1249:
1250: return $v_result;
1251: }
1252:
1253:
1254:
1255:
1256:
1257:
1258:
1259:
1260: 1261: 1262: 1263: 1264: 1265:
1266: function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_params)
1267: {
1268: $v_result=1;
1269:
1270: if ($p_filename == "")
1271: {
1272:
1273: $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
1274:
1275:
1276: return Archive_Zip::errorCode();
1277: }
1278:
1279:
1280: $v_stored_filename = $p_filename;
1281:
1282:
1283: if ($p_remove_all_dir) {
1284: $v_stored_filename = basename($p_filename);
1285: }
1286:
1287: else if ($p_remove_dir != "")
1288: {
1289: if (substr($p_remove_dir, -1) != '/')
1290: $p_remove_dir .= "/";
1291:
1292: if ((substr($p_filename, 0, 2) == "./") || (substr($p_remove_dir, 0, 2) == "./"))
1293: {
1294: if ((substr($p_filename, 0, 2) == "./") && (substr($p_remove_dir, 0, 2) != "./"))
1295: $p_remove_dir = "./".$p_remove_dir;
1296: if ((substr($p_filename, 0, 2) != "./") && (substr($p_remove_dir, 0, 2) == "./"))
1297: $p_remove_dir = substr($p_remove_dir, 2);
1298: }
1299:
1300: $v_compare = $this->_tool_PathInclusion($p_remove_dir, $p_filename);
1301: if ($v_compare > 0)
1302:
1303: {
1304:
1305: if ($v_compare == 2) {
1306: $v_stored_filename = "";
1307: }
1308: else {
1309: $v_stored_filename = substr($p_filename, strlen($p_remove_dir));
1310: }
1311: }
1312: }
1313:
1314: if ($p_add_dir != "")
1315: {
1316: if (substr($p_add_dir, -1) == "/")
1317: $v_stored_filename = $p_add_dir.$v_stored_filename;
1318: else
1319: $v_stored_filename = $p_add_dir."/".$v_stored_filename;
1320: }
1321:
1322:
1323: $v_stored_filename = $this->_tool_PathReduction($v_stored_filename);
1324:
1325:
1326: 1327: 1328: 1329: 1330: 1331: 1332: 1333: 1334: 1335: 1336:
1337:
1338:
1339: clearstatcache();
1340: $p_header['version'] = 20;
1341: $p_header['version_extracted'] = 10;
1342: $p_header['flag'] = 0;
1343: $p_header['compression'] = 0;
1344: $p_header['mtime'] = filemtime($p_filename);
1345: $p_header['crc'] = 0;
1346: $p_header['compressed_size'] = 0;
1347: $p_header['size'] = filesize($p_filename);
1348: $p_header['filename_len'] = strlen($p_filename);
1349: $p_header['extra_len'] = 0;
1350: $p_header['comment_len'] = 0;
1351: $p_header['disk'] = 0;
1352: $p_header['internal'] = 0;
1353: $p_header['external'] = (is_file($p_filename)?0xFE49FFE0:0x41FF0010);
1354: $p_header['offset'] = 0;
1355: $p_header['filename'] = $p_filename;
1356: $p_header['stored_filename'] = $v_stored_filename;
1357: $p_header['extra'] = '';
1358: $p_header['comment'] = '';
1359: $p_header['status'] = 'ok';
1360: $p_header['index'] = -1;
1361:
1362:
1363: if ( (isset($p_params[ARCHIVE_ZIP_PARAM_PRE_ADD]))
1364: && ($p_params[ARCHIVE_ZIP_PARAM_PRE_ADD] != '')) {
1365:
1366:
1367: $v_local_header = array();
1368: $this->_convertHeader2FileInfo($p_header, $v_local_header);
1369:
1370:
1371:
1372:
1373: eval('$v_result = '.$p_params[ARCHIVE_ZIP_PARAM_PRE_ADD].'(ARCHIVE_ZIP_PARAM_PRE_ADD, $v_local_header);');
1374: if ($v_result == 0) {
1375:
1376: $p_header['status'] = "skipped";
1377: $v_result = 1;
1378: }
1379:
1380:
1381:
1382: if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
1383: $p_header['stored_filename'] = $this->_tool_PathReduction($v_local_header['stored_filename']);
1384: }
1385: }
1386:
1387:
1388: if ($p_header['stored_filename'] == "") {
1389: $p_header['status'] = "filtered";
1390: }
1391:
1392:
1393: if (strlen($p_header['stored_filename']) > 0xFF) {
1394: $p_header['status'] = 'filename_too_long';
1395: }
1396:
1397:
1398: if ($p_header['status'] == 'ok') {
1399:
1400:
1401: if (is_file($p_filename))
1402: {
1403:
1404: if (($v_file = @fopen($p_filename, "rb")) == 0) {
1405: $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
1406: return Archive_Zip::errorCode();
1407: }
1408:
1409: if ($p_params['no_compression']) {
1410:
1411: $v_content_compressed = @fread($v_file, $p_header['size']);
1412:
1413:
1414: $p_header['crc'] = crc32($v_content_compressed);
1415: }
1416: else {
1417:
1418: $v_content = @fread($v_file, $p_header['size']);
1419:
1420:
1421: $p_header['crc'] = crc32($v_content);
1422:
1423:
1424: $v_content_compressed = gzdeflate($v_content);
1425: }
1426:
1427:
1428: $p_header['compressed_size'] = strlen($v_content_compressed);
1429: $p_header['compression'] = 8;
1430:
1431:
1432: if (($v_result = $this->_writeFileHeader($p_header)) != 1) {
1433: @fclose($v_file);
1434: return $v_result;
1435: }
1436:
1437:
1438: $v_binary_data = pack('a'.$p_header['compressed_size'], $v_content_compressed);
1439: @fwrite($this->_zip_fd, $v_binary_data, $p_header['compressed_size']);
1440:
1441:
1442: @fclose($v_file);
1443: }
1444:
1445:
1446: else
1447: {
1448:
1449: $p_header['filename'] .= '/';
1450: $p_header['filename_len']++;
1451: $p_header['size'] = 0;
1452: $p_header['external'] = 0x41FF0010;
1453:
1454:
1455: if (($v_result = $this->_writeFileHeader($p_header)) != 1)
1456: {
1457: return $v_result;
1458: }
1459: }
1460: }
1461:
1462:
1463: if ( (isset($p_params[ARCHIVE_ZIP_PARAM_POST_ADD]))
1464: && ($p_params[ARCHIVE_ZIP_PARAM_POST_ADD] != '')) {
1465:
1466:
1467: $v_local_header = array();
1468: $this->_convertHeader2FileInfo($p_header, $v_local_header);
1469:
1470:
1471:
1472:
1473: eval('$v_result = '.$p_params[ARCHIVE_ZIP_PARAM_POST_ADD].'(ARCHIVE_ZIP_PARAM_POST_ADD, $v_local_header);');
1474: if ($v_result == 0) {
1475:
1476: $v_result = 1;
1477: }
1478:
1479:
1480:
1481: }
1482:
1483:
1484: return $v_result;
1485: }
1486:
1487:
1488:
1489:
1490:
1491:
1492:
1493:
1494: 1495: 1496: 1497: 1498: 1499:
1500: function _writeFileHeader(&$p_header)
1501: {
1502: $v_result=1;
1503:
1504:
1505:
1506:
1507:
1508:
1509: $p_header['offset'] = ftell($this->_zip_fd);
1510:
1511:
1512: $v_date = getdate($p_header['mtime']);
1513: $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
1514: $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
1515:
1516:
1517: $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, $p_header['version'], $p_header['flag'],
1518: $p_header['compression'], $v_mtime, $v_mdate,
1519: $p_header['crc'], $p_header['compressed_size'], $p_header['size'],
1520: strlen($p_header['stored_filename']), $p_header['extra_len']);
1521:
1522:
1523: fputs($this->_zip_fd, $v_binary_data, 30);
1524:
1525:
1526: if (strlen($p_header['stored_filename']) != 0)
1527: {
1528: fputs($this->_zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
1529: }
1530: if ($p_header['extra_len'] != 0)
1531: {
1532: fputs($this->_zip_fd, $p_header['extra'], $p_header['extra_len']);
1533: }
1534:
1535:
1536: return $v_result;
1537: }
1538:
1539:
1540:
1541:
1542:
1543:
1544:
1545:
1546: 1547: 1548: 1549: 1550: 1551:
1552: function _writeCentralFileHeader(&$p_header)
1553: {
1554: $v_result=1;
1555:
1556:
1557:
1558:
1559:
1560:
1561: $v_date = getdate($p_header['mtime']);
1562: $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
1563: $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
1564:
1565:
1566: $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, $p_header['version'], $p_header['version_extracted'],
1567: $p_header['flag'], $p_header['compression'], $v_mtime, $v_mdate, $p_header['crc'],
1568: $p_header['compressed_size'], $p_header['size'],
1569: strlen($p_header['stored_filename']), $p_header['extra_len'], $p_header['comment_len'],
1570: $p_header['disk'], $p_header['internal'], $p_header['external'], $p_header['offset']);
1571:
1572:
1573: fputs($this->_zip_fd, $v_binary_data, 46);
1574:
1575:
1576: if (strlen($p_header['stored_filename']) != 0)
1577: {
1578: fputs($this->_zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
1579: }
1580: if ($p_header['extra_len'] != 0)
1581: {
1582: fputs($this->_zip_fd, $p_header['extra'], $p_header['extra_len']);
1583: }
1584: if ($p_header['comment_len'] != 0)
1585: {
1586: fputs($this->_zip_fd, $p_header['comment'], $p_header['comment_len']);
1587: }
1588:
1589:
1590: return $v_result;
1591: }
1592:
1593:
1594:
1595:
1596:
1597:
1598:
1599:
1600: 1601: 1602: 1603: 1604: 1605:
1606: function _writeCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
1607: {
1608: $v_result=1;
1609:
1610:
1611: $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, $p_nb_entries, $p_size, $p_offset, strlen($p_comment));
1612:
1613:
1614: fputs($this->_zip_fd, $v_binary_data, 22);
1615:
1616:
1617: if (strlen($p_comment) != 0)
1618: {
1619: fputs($this->_zip_fd, $p_comment, strlen($p_comment));
1620: }
1621:
1622:
1623: return $v_result;
1624: }
1625:
1626:
1627:
1628:
1629:
1630:
1631:
1632:
1633: 1634: 1635: 1636: 1637: 1638:
1639: function _list(&$p_list)
1640: {
1641: $v_result=1;
1642:
1643:
1644: if (($this->_zip_fd = @fopen($this->_zipname, 'rb')) == 0)
1645: {
1646:
1647: $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->_zipname.'\' in binary read mode');
1648:
1649:
1650: return Archive_Zip::errorCode();
1651: }
1652:
1653:
1654: $v_central_dir = array();
1655: if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1)
1656: {
1657: return $v_result;
1658: }
1659:
1660:
1661: @rewind($this->_zip_fd);
1662: if (@fseek($this->_zip_fd, $v_central_dir['offset']))
1663: {
1664:
1665: $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
1666:
1667:
1668: return Archive_Zip::errorCode();
1669: }
1670:
1671:
1672: for ($i=0; $i<$v_central_dir['entries']; $i++)
1673: {
1674:
1675: if (($v_result = $this->_readCentralFileHeader($v_header)) != 1)
1676: {
1677: return $v_result;
1678: }
1679: $v_header['index'] = $i;
1680:
1681:
1682: $this->_convertHeader2FileInfo($v_header, $p_list[$i]);
1683: unset($v_header);
1684: }
1685:
1686:
1687: $this->_closeFd();
1688:
1689:
1690: return $v_result;
1691: }
1692:
1693:
1694:
1695:
1696:
1697:
1698:
1699:
1700:
1701:
1702:
1703:
1704:
1705:
1706:
1707:
1708:
1709:
1710:
1711:
1712: 1713: 1714: 1715: 1716: 1717:
1718: function _convertHeader2FileInfo($p_header, &$p_info)
1719: {
1720: $v_result=1;
1721:
1722:
1723: $p_info['filename'] = $p_header['filename'];
1724: $p_info['stored_filename'] = $p_header['stored_filename'];
1725: $p_info['size'] = $p_header['size'];
1726: $p_info['compressed_size'] = $p_header['compressed_size'];
1727: $p_info['mtime'] = $p_header['mtime'];
1728: $p_info['comment'] = $p_header['comment'];
1729: $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
1730: $p_info['index'] = $p_header['index'];
1731: $p_info['status'] = $p_header['status'];
1732:
1733:
1734: return $v_result;
1735: }
1736:
1737:
1738:
1739:
1740:
1741:
1742:
1743:
1744:
1745:
1746:
1747:
1748:
1749:
1750:
1751:
1752:
1753:
1754: 1755: 1756: 1757: 1758: 1759:
1760: function _extractByRule(&$p_file_list, &$p_params)
1761: {
1762: $v_result=1;
1763:
1764: $p_path = $p_params['add_path'];
1765: $p_remove_path = $p_params['remove_path'];
1766: $p_remove_all_path = $p_params['remove_all_path'];
1767:
1768:
1769: if (($p_path == "")
1770: || ((substr($p_path, 0, 1) != "/")
1771: && (substr($p_path, 0, 3) != "../") && (substr($p_path,1,2)!=":/")))
1772: $p_path = "./".$p_path;
1773:
1774:
1775: if (($p_path != "./") && ($p_path != "/")) {
1776:
1777: while (substr($p_path, -1) == "/") {
1778: $p_path = substr($p_path, 0, strlen($p_path)-1);
1779: }
1780: }
1781:
1782:
1783: if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) {
1784: $p_remove_path .= '/';
1785: }
1786: $p_remove_path_size = strlen($p_remove_path);
1787:
1788:
1789: if (($v_result = $this->_openFd('rb')) != 1)
1790: {
1791: return $v_result;
1792: }
1793:
1794:
1795: $v_central_dir = array();
1796: if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1)
1797: {
1798:
1799: $this->_closeFd();
1800:
1801: return $v_result;
1802: }
1803:
1804:
1805: $v_pos_entry = $v_central_dir['offset'];
1806:
1807:
1808: $j_start = 0;
1809: for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) {
1810:
1811: @rewind($this->_zip_fd);
1812: if (@fseek($this->_zip_fd, $v_pos_entry)) {
1813: $this->_closeFd();
1814:
1815: $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP,
1816: 'Invalid archive size');
1817:
1818: return Archive_Zip::errorCode();
1819: }
1820:
1821:
1822: $v_header = array();
1823: if (($v_result = $this->_readCentralFileHeader($v_header)) != 1) {
1824: $this->_closeFd();
1825:
1826: return $v_result;
1827: }
1828:
1829:
1830: $v_header['index'] = $i;
1831:
1832:
1833: $v_pos_entry = ftell($this->_zip_fd);
1834:
1835:
1836: $v_extract = false;
1837:
1838:
1839: if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_NAME]))
1840: && ($p_params[ARCHIVE_ZIP_PARAM_BY_NAME] != 0)) {
1841:
1842:
1843: for ($j=0;
1844: ($j<sizeof($p_params[ARCHIVE_ZIP_PARAM_BY_NAME]))
1845: && (!$v_extract);
1846: $j++) {
1847:
1848:
1849: if (substr($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j], -1) == "/") {
1850:
1851:
1852: if ( (strlen($v_header['stored_filename']) > strlen($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j]))
1853: && (substr($v_header['stored_filename'], 0, strlen($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) {
1854: $v_extract = true;
1855: }
1856: }
1857:
1858: elseif ($v_header['stored_filename'] == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j]) {
1859: $v_extract = true;
1860: }
1861: }
1862: }
1863:
1864:
1865: else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_EREG]))
1866: && ($p_params[ARCHIVE_ZIP_PARAM_BY_EREG] != "")) {
1867:
1868: if (ereg($p_params[ARCHIVE_ZIP_PARAM_BY_EREG], $v_header['stored_filename'])) {
1869: $v_extract = true;
1870: }
1871: }
1872:
1873:
1874: else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_PREG]))
1875: && ($p_params[ARCHIVE_ZIP_PARAM_BY_PREG] != "")) {
1876:
1877: if (preg_match($p_params[ARCHIVE_ZIP_PARAM_BY_PREG], $v_header['stored_filename'])) {
1878: $v_extract = true;
1879: }
1880: }
1881:
1882:
1883: else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX]))
1884: && ($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX] != 0)) {
1885:
1886:
1887: for ($j=$j_start; ($j<sizeof($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX])) && (!$v_extract); $j++) {
1888:
1889: if (($i>=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['start']) && ($i<=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['end'])) {
1890: $v_extract = true;
1891: }
1892: if ($i>=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['end']) {
1893: $j_start = $j+1;
1894: }
1895:
1896: if ($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['start']>$i) {
1897: break;
1898: }
1899: }
1900: }
1901:
1902:
1903: else {
1904: $v_extract = true;
1905: }
1906:
1907:
1908:
1909: if ($v_extract)
1910: {
1911:
1912:
1913: @rewind($this->_zip_fd);
1914: if (@fseek($this->_zip_fd, $v_header['offset']))
1915: {
1916:
1917: $this->_closeFd();
1918:
1919:
1920: $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
1921:
1922:
1923: return Archive_Zip::errorCode();
1924: }
1925:
1926:
1927: if ($p_params[ARCHIVE_ZIP_PARAM_EXTRACT_AS_STRING]) {
1928:
1929:
1930: if (($v_result = $this->_extractFileAsString($v_header, $v_string)) != 1)
1931: {
1932:
1933: $this->_closeFd();
1934:
1935: return $v_result;
1936: }
1937:
1938:
1939: if (($v_result = $this->_convertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
1940: {
1941:
1942: $this->_closeFd();
1943:
1944: return $v_result;
1945: }
1946:
1947:
1948: $p_file_list[$v_nb_extracted]['content'] = $v_string;
1949:
1950:
1951: $v_nb_extracted++;
1952: }
1953: else {
1954:
1955: if (($v_result = $this->_extractFile($v_header, $p_path, $p_remove_path, $p_remove_all_path, $p_params)) != 1)
1956: {
1957:
1958: $this->_closeFd();
1959:
1960: return $v_result;
1961: }
1962:
1963:
1964: if (($v_result = $this->_convertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
1965: {
1966:
1967: $this->_closeFd();
1968:
1969: return $v_result;
1970: }
1971: }
1972: }
1973: }
1974:
1975:
1976: $this->_closeFd();
1977:
1978:
1979: return $v_result;
1980: }
1981:
1982:
1983:
1984:
1985:
1986:
1987:
1988:
1989: 1990: 1991: 1992: 1993: 1994:
1995: function _extractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_params)
1996: {
1997: $v_result=1;
1998:
1999:
2000: if (($v_result = $this->_readFileHeader($v_header)) != 1)
2001: {
2002:
2003: return $v_result;
2004: }
2005:
2006:
2007:
2008:
2009:
2010:
2011: if ($p_remove_all_path == true) {
2012:
2013: $p_entry['filename'] = basename($p_entry['filename']);
2014: }
2015:
2016:
2017: else if ($p_remove_path != "")
2018: {
2019:
2020: if ($this->_tool_PathInclusion($p_remove_path, $p_entry['filename']) == 2)
2021: {
2022:
2023:
2024: $p_entry['status'] = "filtered";
2025:
2026:
2027: return $v_result;
2028: }
2029:
2030: $p_remove_path_size = strlen($p_remove_path);
2031: if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
2032: {
2033:
2034:
2035: $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
2036:
2037: }
2038: }
2039:
2040:
2041: if ($p_path != '')
2042: {
2043: $p_entry['filename'] = $p_path."/".$p_entry['filename'];
2044: }
2045:
2046:
2047: if ( (isset($p_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT]))
2048: && ($p_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT] != '')) {
2049:
2050:
2051: $v_local_header = array();
2052: $this->_convertHeader2FileInfo($p_entry, $v_local_header);
2053:
2054:
2055:
2056:
2057: eval('$v_result = '.$p_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT].'(ARCHIVE_ZIP_PARAM_PRE_EXTRACT, $v_local_header);');
2058: if ($v_result == 0) {
2059:
2060: $p_entry['status'] = "skipped";
2061: $v_result = 1;
2062: }
2063:
2064:
2065:
2066: $p_entry['filename'] = $v_local_header['filename'];
2067: }
2068:
2069:
2070:
2071:
2072: if ($p_entry['status'] == 'ok') {
2073:
2074:
2075: if (file_exists($p_entry['filename']))
2076: {
2077:
2078:
2079: if (is_dir($p_entry['filename']))
2080: {
2081:
2082:
2083: $p_entry['status'] = "already_a_directory";
2084:
2085:
2086:
2087: }
2088:
2089: else if (!is_writeable($p_entry['filename']))
2090: {
2091:
2092:
2093: $p_entry['status'] = "write_protected";
2094:
2095:
2096:
2097: }
2098:
2099:
2100: else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
2101: {
2102:
2103:
2104: $p_entry['status'] = "newer_exist";
2105:
2106:
2107:
2108: }
2109: }
2110:
2111:
2112: else {
2113: if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
2114: $v_dir_to_check = $p_entry['filename'];
2115: else if (!strstr($p_entry['filename'], "/"))
2116: $v_dir_to_check = "";
2117: else
2118: $v_dir_to_check = dirname($p_entry['filename']);
2119:
2120: if (($v_result = $this->_dirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
2121:
2122:
2123: $p_entry['status'] = "path_creation_fail";
2124:
2125:
2126:
2127: $v_result = 1;
2128: }
2129: }
2130: }
2131:
2132:
2133: if ($p_entry['status'] == 'ok') {
2134:
2135:
2136: if (!(($p_entry['external']&0x00000010)==0x00000010))
2137: {
2138:
2139:
2140: if ($p_entry['compressed_size'] == $p_entry['size'])
2141: {
2142:
2143:
2144: if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
2145: {
2146:
2147:
2148: $p_entry['status'] = "write_error";
2149:
2150:
2151: return $v_result;
2152: }
2153:
2154:
2155:
2156: $v_size = $p_entry['compressed_size'];
2157: while ($v_size != 0)
2158: {
2159: $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
2160: $v_buffer = fread($this->_zip_fd, $v_read_size);
2161: $v_binary_data = pack('a'.$v_read_size, $v_buffer);
2162: @fwrite($v_dest_file, $v_binary_data, $v_read_size);
2163: $v_size -= $v_read_size;
2164: }
2165:
2166:
2167: fclose($v_dest_file);
2168:
2169:
2170: touch($p_entry['filename'], $p_entry['mtime']);
2171: }
2172: else
2173: {
2174:
2175:
2176:
2177: if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
2178:
2179:
2180: $p_entry['status'] = "write_error";
2181:
2182: return $v_result;
2183: }
2184:
2185:
2186:
2187: $v_buffer = @fread($this->_zip_fd, $p_entry['compressed_size']);
2188:
2189:
2190: $v_file_content = gzinflate($v_buffer);
2191: unset($v_buffer);
2192:
2193:
2194: @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
2195: unset($v_file_content);
2196:
2197:
2198: @fclose($v_dest_file);
2199:
2200:
2201: touch($p_entry['filename'], $p_entry['mtime']);
2202: }
2203:
2204:
2205: if ( (isset($p_params[ARCHIVE_ZIP_PARAM_SET_CHMOD]))
2206: && ($p_params[ARCHIVE_ZIP_PARAM_SET_CHMOD] != 0)) {
2207:
2208:
2209: chmod($p_entry['filename'], $p_params[ARCHIVE_ZIP_PARAM_SET_CHMOD]);
2210: }
2211:
2212: }
2213: }
2214:
2215:
2216: if ( (isset($p_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT]))
2217: && ($p_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT] != '')) {
2218:
2219:
2220: $v_local_header = array();
2221: $this->_convertHeader2FileInfo($p_entry, $v_local_header);
2222:
2223:
2224:
2225:
2226: eval('$v_result = '.$p_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT].'(ARCHIVE_ZIP_PARAM_POST_EXTRACT, $v_local_header);');
2227: }
2228:
2229:
2230: return $v_result;
2231: }
2232:
2233:
2234:
2235:
2236:
2237:
2238:
2239:
2240: 2241: 2242: 2243: 2244: 2245:
2246: function _extractFileAsString(&$p_entry, &$p_string)
2247: {
2248: $v_result=1;
2249:
2250:
2251: $v_header = array();
2252: if (($v_result = $this->_readFileHeader($v_header)) != 1)
2253: {
2254:
2255: return $v_result;
2256: }
2257:
2258:
2259:
2260:
2261:
2262:
2263:
2264:
2265: if (!(($p_entry['external']&0x00000010)==0x00000010))
2266: {
2267:
2268: if ($p_entry['compressed_size'] == $p_entry['size'])
2269: {
2270:
2271:
2272:
2273: $p_string = fread($this->_zip_fd, $p_entry['compressed_size']);
2274: }
2275: else
2276: {
2277:
2278:
2279:
2280: $v_data = fread($this->_zip_fd, $p_entry['compressed_size']);
2281:
2282:
2283: $p_string = gzinflate($v_data);
2284: }
2285:
2286:
2287: }
2288: else {
2289:
2290: }
2291:
2292:
2293: return $v_result;
2294: }
2295:
2296:
2297:
2298:
2299:
2300:
2301:
2302:
2303: 2304: 2305: 2306: 2307: 2308:
2309: function _readFileHeader(&$p_header)
2310: {
2311: $v_result=1;
2312:
2313:
2314: $v_binary_data = @fread($this->_zip_fd, 4);
2315: $v_data = unpack('Vid', $v_binary_data);
2316:
2317:
2318: if ($v_data['id'] != 0x04034b50)
2319: {
2320:
2321:
2322: $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
2323:
2324:
2325: return Archive_Zip::errorCode();
2326: }
2327:
2328:
2329: $v_binary_data = fread($this->_zip_fd, 26);
2330:
2331:
2332: if (strlen($v_binary_data) != 26)
2333: {
2334: $p_header['filename'] = "";
2335: $p_header['status'] = "invalid_header";
2336:
2337:
2338: $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
2339:
2340:
2341: return Archive_Zip::errorCode();
2342: }
2343:
2344:
2345: $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
2346:
2347:
2348: $p_header['filename'] = fread($this->_zip_fd, $v_data['filename_len']);
2349:
2350:
2351: if ($v_data['extra_len'] != 0) {
2352: $p_header['extra'] = fread($this->_zip_fd, $v_data['extra_len']);
2353: }
2354: else {
2355: $p_header['extra'] = '';
2356: }
2357:
2358:
2359: $p_header['compression'] = $v_data['compression'];
2360: $p_header['size'] = $v_data['size'];
2361: $p_header['compressed_size'] = $v_data['compressed_size'];
2362: $p_header['crc'] = $v_data['crc'];
2363: $p_header['flag'] = $v_data['flag'];
2364:
2365:
2366: $p_header['mdate'] = $v_data['mdate'];
2367: $p_header['mtime'] = $v_data['mtime'];
2368: if ($p_header['mdate'] && $p_header['mtime'])
2369: {
2370:
2371: $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
2372: $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
2373: $v_seconde = ($p_header['mtime'] & 0x001F)*2;
2374:
2375:
2376: $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
2377: $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
2378: $v_day = $p_header['mdate'] & 0x001F;
2379:
2380:
2381: $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
2382:
2383: }
2384: else
2385: {
2386: $p_header['mtime'] = time();
2387: }
2388:
2389:
2390:
2391:
2392:
2393:
2394:
2395:
2396: $p_header['stored_filename'] = $p_header['filename'];
2397:
2398:
2399: $p_header['status'] = "ok";
2400:
2401:
2402: return $v_result;
2403: }
2404:
2405:
2406:
2407:
2408:
2409:
2410:
2411:
2412: 2413: 2414: 2415: 2416: 2417:
2418: function _readCentralFileHeader(&$p_header)
2419: {
2420: $v_result=1;
2421:
2422:
2423: $v_binary_data = @fread($this->_zip_fd, 4);
2424: $v_data = unpack('Vid', $v_binary_data);
2425:
2426:
2427: if ($v_data['id'] != 0x02014b50)
2428: {
2429:
2430:
2431: $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
2432:
2433:
2434: return Archive_Zip::errorCode();
2435: }
2436:
2437:
2438: $v_binary_data = fread($this->_zip_fd, 42);
2439:
2440:
2441: if (strlen($v_binary_data) != 42)
2442: {
2443: $p_header['filename'] = "";
2444: $p_header['status'] = "invalid_header";
2445:
2446:
2447: $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
2448:
2449:
2450: return Archive_Zip::errorCode();
2451: }
2452:
2453:
2454: $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);
2455:
2456:
2457: if ($p_header['filename_len'] != 0)
2458: $p_header['filename'] = fread($this->_zip_fd, $p_header['filename_len']);
2459: else
2460: $p_header['filename'] = '';
2461:
2462:
2463: if ($p_header['extra_len'] != 0)
2464: $p_header['extra'] = fread($this->_zip_fd, $p_header['extra_len']);
2465: else
2466: $p_header['extra'] = '';
2467:
2468:
2469: if ($p_header['comment_len'] != 0)
2470: $p_header['comment'] = fread($this->_zip_fd, $p_header['comment_len']);
2471: else
2472: $p_header['comment'] = '';
2473:
2474:
2475:
2476:
2477: if ($p_header['mdate'] && $p_header['mtime'])
2478: {
2479:
2480: $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
2481: $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
2482: $v_seconde = ($p_header['mtime'] & 0x001F)*2;
2483:
2484:
2485: $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
2486: $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
2487: $v_day = $p_header['mdate'] & 0x001F;
2488:
2489:
2490: $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
2491:
2492: }
2493: else
2494: {
2495: $p_header['mtime'] = time();
2496: }
2497:
2498:
2499: $p_header['stored_filename'] = $p_header['filename'];
2500:
2501:
2502: $p_header['status'] = 'ok';
2503:
2504:
2505: if (substr($p_header['filename'], -1) == '/')
2506: {
2507: $p_header['external'] = 0x41FF0010;
2508: }
2509:
2510:
2511:
2512: return $v_result;
2513: }
2514:
2515:
2516:
2517:
2518:
2519:
2520:
2521:
2522: 2523: 2524: 2525: 2526: 2527:
2528: function _readEndCentralDir(&$p_central_dir)
2529: {
2530: $v_result=1;
2531:
2532:
2533: $v_size = filesize($this->_zipname);
2534: @fseek($this->_zip_fd, $v_size);
2535: if (@ftell($this->_zip_fd) != $v_size) {
2536: $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
2537: 'Unable to go to the end of the archive \''
2538: .$this->_zipname.'\'');
2539: return Archive_Zip::errorCode();
2540: }
2541:
2542:
2543:
2544:
2545: $v_found = 0;
2546: if ($v_size > 26) {
2547: @fseek($this->_zip_fd, $v_size-22);
2548: if (($v_pos = @ftell($this->_zip_fd)) != ($v_size-22)) {
2549: $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
2550: 'Unable to seek back to the middle of the archive \''
2551: .$this->_zipname.'\'');
2552: return Archive_Zip::errorCode();
2553: }
2554:
2555:
2556: $v_binary_data = @fread($this->_zip_fd, 4);
2557: $v_data = unpack('Vid', $v_binary_data);
2558:
2559:
2560: if ($v_data['id'] == 0x06054b50) {
2561: $v_found = 1;
2562: }
2563:
2564: $v_pos = ftell($this->_zip_fd);
2565: }
2566:
2567:
2568: if (!$v_found) {
2569: $v_maximum_size = 65557;
2570: if ($v_maximum_size > $v_size)
2571: $v_maximum_size = $v_size;
2572: @fseek($this->_zip_fd, $v_size-$v_maximum_size);
2573: if (@ftell($this->_zip_fd) != ($v_size-$v_maximum_size)) {
2574: $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
2575: 'Unable to seek back to the middle of the archive \''
2576: .$this->_zipname.'\'');
2577: return Archive_Zip::errorCode();
2578: }
2579:
2580:
2581: $v_pos = ftell($this->_zip_fd);
2582: $v_bytes = 0x00000000;
2583: while ($v_pos < $v_size) {
2584:
2585: $v_byte = @fread($this->_zip_fd, 1);
2586:
2587:
2588: $v_bytes = ($v_bytes << 8) | Ord($v_byte);
2589:
2590:
2591: if ($v_bytes == 0x504b0506) {
2592: $v_pos++;
2593: break;
2594: }
2595:
2596: $v_pos++;
2597: }
2598:
2599:
2600: if ($v_pos == $v_size) {
2601: $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
2602: "Unable to find End of Central Dir Record signature");
2603: return Archive_Zip::errorCode();
2604: }
2605: }
2606:
2607:
2608: $v_binary_data = fread($this->_zip_fd, 18);
2609:
2610:
2611: if (strlen($v_binary_data) != 18) {
2612: $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
2613: "Invalid End of Central Dir Record size : "
2614: .strlen($v_binary_data));
2615: return Archive_Zip::errorCode();
2616: }
2617:
2618:
2619: $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
2620:
2621:
2622: if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
2623: $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
2624: "Fail to find the right signature");
2625: return Archive_Zip::errorCode();
2626: }
2627:
2628:
2629: if ($v_data['comment_size'] != 0)
2630: $p_central_dir['comment'] = fread($this->_zip_fd, $v_data['comment_size']);
2631: else
2632: $p_central_dir['comment'] = '';
2633:
2634: $p_central_dir['entries'] = $v_data['entries'];
2635: $p_central_dir['disk_entries'] = $v_data['disk_entries'];
2636: $p_central_dir['offset'] = $v_data['offset'];
2637: $p_central_dir['size'] = $v_data['size'];
2638: $p_central_dir['disk'] = $v_data['disk'];
2639: $p_central_dir['disk_start'] = $v_data['disk_start'];
2640:
2641:
2642: return $v_result;
2643: }
2644:
2645:
2646:
2647:
2648:
2649:
2650:
2651:
2652: 2653: 2654: 2655: 2656: 2657:
2658: function _deleteByRule(&$p_result_list, &$p_params)
2659: {
2660: $v_result=1;
2661: $v_list_detail = array();
2662:
2663:
2664: if (($v_result=$this->_openFd('rb')) != 1)
2665: {
2666:
2667: return $v_result;
2668: }
2669:
2670:
2671: $v_central_dir = array();
2672: if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1)
2673: {
2674: $this->_closeFd();
2675: return $v_result;
2676: }
2677:
2678:
2679: @rewind($this->_zip_fd);
2680:
2681:
2682:
2683: $v_pos_entry = $v_central_dir['offset'];
2684: @rewind($this->_zip_fd);
2685: if (@fseek($this->_zip_fd, $v_pos_entry)) {
2686:
2687: $this->_closeFd();
2688:
2689: $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP,
2690: 'Invalid archive size');
2691: return Archive_Zip::errorCode();
2692: }
2693:
2694:
2695: $v_header_list = array();
2696: $j_start = 0;
2697: for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) {
2698:
2699:
2700: $v_header_list[$v_nb_extracted] = array();
2701: $v_result
2702: = $this->_readCentralFileHeader($v_header_list[$v_nb_extracted]);
2703: if ($v_result != 1) {
2704:
2705: $this->_closeFd();
2706:
2707: return $v_result;
2708: }
2709:
2710:
2711: $v_header_list[$v_nb_extracted]['index'] = $i;
2712:
2713:
2714: $v_found = false;
2715:
2716:
2717: if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_NAME]))
2718: && ($p_params[ARCHIVE_ZIP_PARAM_BY_NAME] != 0)) {
2719:
2720:
2721: for ($j=0;
2722: ($j<sizeof($p_params[ARCHIVE_ZIP_PARAM_BY_NAME]))
2723: && (!$v_found);
2724: $j++) {
2725:
2726:
2727: if (substr($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j], -1) == "/") {
2728:
2729:
2730: if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j]))
2731: && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) {
2732: $v_found = true;
2733: }
2734: elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010)
2735: && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) {
2736: $v_found = true;
2737: }
2738: }
2739:
2740: elseif ($v_header_list[$v_nb_extracted]['stored_filename']
2741: == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j]) {
2742: $v_found = true;
2743: }
2744: }
2745: }
2746:
2747:
2748: else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_EREG]))
2749: && ($p_params[ARCHIVE_ZIP_PARAM_BY_EREG] != "")) {
2750:
2751: if (ereg($p_params[ARCHIVE_ZIP_PARAM_BY_EREG],
2752: $v_header_list[$v_nb_extracted]['stored_filename'])) {
2753: $v_found = true;
2754: }
2755: }
2756:
2757:
2758: else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_PREG]))
2759: && ($p_params[ARCHIVE_ZIP_PARAM_BY_PREG] != "")) {
2760:
2761: if (preg_match($p_params[ARCHIVE_ZIP_PARAM_BY_PREG],
2762: $v_header_list[$v_nb_extracted]['stored_filename'])) {
2763: $v_found = true;
2764: }
2765: }
2766:
2767:
2768: else if ( (isset($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX]))
2769: && ($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX] != 0)) {
2770:
2771:
2772: for ($j=$j_start;
2773: ($j<sizeof($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX]))
2774: && (!$v_found);
2775: $j++) {
2776:
2777: if ( ($i>=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['start'])
2778: && ($i<=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['end'])) {
2779: $v_found = true;
2780: }
2781: if ($i>=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['end']) {
2782: $j_start = $j+1;
2783: }
2784:
2785: if ($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['start']>$i) {
2786: break;
2787: }
2788: }
2789: }
2790:
2791:
2792: if ($v_found) {
2793: unset($v_header_list[$v_nb_extracted]);
2794: }
2795: else {
2796: $v_nb_extracted++;
2797: }
2798: }
2799:
2800:
2801: if ($v_nb_extracted > 0) {
2802:
2803:
2804: $v_zip_temp_name = ARCHIVE_ZIP_TEMPORARY_DIR.uniqid('archive_zip-')
2805: .'.tmp';
2806:
2807:
2808: $v_temp_zip = new Archive_Zip($v_zip_temp_name);
2809:
2810:
2811: if (($v_result = $v_temp_zip->_openFd('wb')) != 1) {
2812: $this->_closeFd();
2813:
2814:
2815: return $v_result;
2816: }
2817:
2818:
2819: for ($i=0; $i<sizeof($v_header_list); $i++) {
2820:
2821:
2822: @rewind($this->_zip_fd);
2823: if (@fseek($this->_zip_fd, $v_header_list[$i]['offset'])) {
2824:
2825: $this->_closeFd();
2826: $v_temp_zip->_closeFd();
2827: @unlink($v_zip_temp_name);
2828:
2829: $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP,
2830: 'Invalid archive size');
2831: return Archive_Zip::errorCode();
2832: }
2833:
2834:
2835: if (($v_result = $this->_readFileHeader($v_header_list[$i])) != 1) {
2836:
2837: $this->_closeFd();
2838: $v_temp_zip->_closeFd();
2839: @unlink($v_zip_temp_name);
2840:
2841: return $v_result;
2842: }
2843:
2844:
2845: $v_result = $v_temp_zip->_writeFileHeader($v_header_list[$i]);
2846: if ($v_result != 1) {
2847:
2848: $this->_closeFd();
2849: $v_temp_zip->_closeFd();
2850: @unlink($v_zip_temp_name);
2851:
2852: return $v_result;
2853: }
2854:
2855:
2856: $v_result = $this->_tool_CopyBlock($this->_zip_fd,
2857: $v_temp_zip->_zip_fd,
2858: $v_header_list[$i]['compressed_size']);
2859: if ($v_result != 1) {
2860:
2861: $this->_closeFd();
2862: $v_temp_zip->_closeFd();
2863: @unlink($v_zip_temp_name);
2864:
2865: return $v_result;
2866: }
2867: }
2868:
2869:
2870: $v_offset = @ftell($v_temp_zip->_zip_fd);
2871:
2872:
2873: for ($i=0; $i<sizeof($v_header_list); $i++) {
2874:
2875: $v_result=$v_temp_zip->_writeCentralFileHeader($v_header_list[$i]);
2876: if ($v_result != 1) {
2877:
2878: $v_temp_zip->_closeFd();
2879: $this->_closeFd();
2880: @unlink($v_zip_temp_name);
2881:
2882: return $v_result;
2883: }
2884:
2885:
2886: $v_temp_zip->_convertHeader2FileInfo($v_header_list[$i],
2887: $p_result_list[$i]);
2888: }
2889:
2890:
2891:
2892: $v_comment = '';
2893:
2894:
2895: $v_size = @ftell($v_temp_zip->_zip_fd)-$v_offset;
2896:
2897:
2898: $v_result = $v_temp_zip->_writeCentralHeader(sizeof($v_header_list),
2899: $v_size, $v_offset,
2900: $v_comment);
2901: if ($v_result != 1) {
2902:
2903: unset($v_header_list);
2904: $v_temp_zip->_closeFd();
2905: $this->_closeFd();
2906: @unlink($v_zip_temp_name);
2907:
2908: return $v_result;
2909: }
2910:
2911:
2912: $v_temp_zip->_closeFd();
2913: $this->_closeFd();
2914:
2915:
2916:
2917: @unlink($this->_zipname);
2918:
2919:
2920:
2921:
2922: $this->_tool_Rename($v_zip_temp_name, $this->_zipname);
2923:
2924:
2925: unset($v_temp_zip);
2926: }
2927:
2928:
2929: return $v_result;
2930: }
2931:
2932:
2933:
2934:
2935:
2936:
2937:
2938:
2939:
2940:
2941:
2942:
2943:
2944: 2945: 2946: 2947: 2948: 2949: 2950:
2951: function _dirCheck($p_dir, $p_is_dir=false)
2952: {
2953: $v_result = 1;
2954:
2955:
2956: if (($p_is_dir) && (substr($p_dir, -1)=='/')) {
2957: $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
2958: }
2959:
2960:
2961: if ((is_dir($p_dir)) || ($p_dir == "")) {
2962: return 1;
2963: }
2964:
2965:
2966: $p_parent_dir = dirname($p_dir);
2967:
2968:
2969: if ($p_parent_dir != $p_dir) {
2970:
2971: if ($p_parent_dir != "") {
2972: if (($v_result = $this->_dirCheck($p_parent_dir)) != 1) {
2973: return $v_result;
2974: }
2975: }
2976: }
2977:
2978:
2979: if (!@mkdir($p_dir, 0777)) {
2980: $this->_errorLog(ARCHIVE_ZIP_ERR_DIR_CREATE_FAIL,
2981: "Unable to create directory '$p_dir'");
2982: return Archive_Zip::errorCode();
2983: }
2984:
2985:
2986: return $v_result;
2987: }
2988:
2989:
2990:
2991:
2992:
2993:
2994:
2995:
2996:
2997: 2998: 2999: 3000: 3001: 3002:
3003: function _merge(&$p_archive_to_add)
3004: {
3005: $v_result=1;
3006:
3007:
3008: if (!is_file($p_archive_to_add->_zipname)) {
3009:
3010: return 1;
3011: }
3012:
3013:
3014: if (!is_file($this->_zipname)) {
3015:
3016: $v_result = $this->_duplicate($p_archive_to_add->_zipname);
3017:
3018: return $v_result;
3019: }
3020:
3021:
3022: if (($v_result=$this->_openFd('rb')) != 1) {
3023: return $v_result;
3024: }
3025:
3026:
3027: $v_central_dir = array();
3028: if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) {
3029: $this->_closeFd();
3030: return $v_result;
3031: }
3032:
3033:
3034: @rewind($this->_zip_fd);
3035:
3036:
3037: if (($v_result=$p_archive_to_add->_openFd('rb')) != 1) {
3038: $this->_closeFd();
3039: return $v_result;
3040: }
3041:
3042:
3043: $v_central_dir_to_add = array();
3044: $v_result = $p_archive_to_add->_readEndCentralDir($v_central_dir_to_add);
3045: if ($v_result != 1) {
3046: $this->_closeFd();
3047: $p_archive_to_add->_closeFd();
3048: return $v_result;
3049: }
3050:
3051:
3052: @rewind($p_archive_to_add->_zip_fd);
3053:
3054:
3055: $v_zip_temp_name = ARCHIVE_ZIP_TEMPORARY_DIR.uniqid('archive_zip-').'.tmp';
3056:
3057:
3058: if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) {
3059: $this->_closeFd();
3060: $p_archive_to_add->_closeFd();
3061: $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL,
3062: 'Unable to open temporary file \''
3063: .$v_zip_temp_name.'\' in binary write mode');
3064: return Archive_Zip::errorCode();
3065: }
3066:
3067:
3068:
3069:
3070: $v_size = $v_central_dir['offset'];
3071: while ($v_size != 0) {
3072: $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
3073: ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
3074: $v_buffer = fread($this->_zip_fd, $v_read_size);
3075: @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
3076: $v_size -= $v_read_size;
3077: }
3078:
3079:
3080: $v_size = $v_central_dir_to_add['offset'];
3081: while ($v_size != 0) {
3082: $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
3083: ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
3084: $v_buffer = fread($p_archive_to_add->_zip_fd, $v_read_size);
3085: @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
3086: $v_size -= $v_read_size;
3087: }
3088:
3089:
3090: $v_offset = @ftell($v_zip_temp_fd);
3091:
3092:
3093: $v_size = $v_central_dir['size'];
3094: while ($v_size != 0) {
3095: $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
3096: ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
3097: $v_buffer = @fread($this->_zip_fd, $v_read_size);
3098: @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
3099: $v_size -= $v_read_size;
3100: }
3101:
3102:
3103: $v_size = $v_central_dir_to_add['size'];
3104: while ($v_size != 0) {
3105: $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
3106: ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
3107: $v_buffer = @fread($p_archive_to_add->_zip_fd, $v_read_size);
3108: @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
3109: $v_size -= $v_read_size;
3110: }
3111:
3112:
3113:
3114: $v_comment = '';
3115:
3116:
3117: $v_size = @ftell($v_zip_temp_fd)-$v_offset;
3118:
3119:
3120:
3121:
3122: $v_swap = $this->_zip_fd;
3123: $this->_zip_fd = $v_zip_temp_fd;
3124: $v_zip_temp_fd = $v_swap;
3125:
3126:
3127: if (($v_result = $this->_writeCentralHeader($v_central_dir['entries']
3128: +$v_central_dir_to_add['entries'],
3129: $v_size, $v_offset,
3130: $v_comment)) != 1) {
3131: $this->_closeFd();
3132: $p_archive_to_add->_closeFd();
3133: @fclose($v_zip_temp_fd);
3134: $this->_zip_fd = null;
3135:
3136:
3137: unset($v_header_list);
3138:
3139:
3140: return $v_result;
3141: }
3142:
3143:
3144: $v_swap = $this->_zip_fd;
3145: $this->_zip_fd = $v_zip_temp_fd;
3146: $v_zip_temp_fd = $v_swap;
3147:
3148:
3149: $this->_closeFd();
3150: $p_archive_to_add->_closeFd();
3151:
3152:
3153: @fclose($v_zip_temp_fd);
3154:
3155:
3156:
3157: @unlink($this->_zipname);
3158:
3159:
3160:
3161:
3162: $this->_tool_Rename($v_zip_temp_name, $this->_zipname);
3163:
3164:
3165: return $v_result;
3166: }
3167:
3168:
3169:
3170:
3171:
3172:
3173:
3174:
3175: 3176: 3177: 3178: 3179: 3180:
3181: function _duplicate($p_archive_filename)
3182: {
3183: $v_result=1;
3184:
3185:
3186: if (!is_file($p_archive_filename)) {
3187:
3188:
3189: $v_result = 1;
3190:
3191:
3192: return $v_result;
3193: }
3194:
3195:
3196: if (($v_result=$this->_openFd('wb')) != 1) {
3197:
3198: return $v_result;
3199: }
3200:
3201:
3202: if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) {
3203: $this->_closeFd();
3204: $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL,
3205: 'Unable to open archive file \''
3206: .$p_archive_filename.'\' in binary write mode');
3207: return Archive_Zip::errorCode();
3208: }
3209:
3210:
3211:
3212:
3213: $v_size = filesize($p_archive_filename);
3214: while ($v_size != 0) {
3215: $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
3216: ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
3217: $v_buffer = fread($v_zip_temp_fd, $v_read_size);
3218: @fwrite($this->_zip_fd, $v_buffer, $v_read_size);
3219: $v_size -= $v_read_size;
3220: }
3221:
3222:
3223: $this->_closeFd();
3224:
3225:
3226: @fclose($v_zip_temp_fd);
3227:
3228: return $v_result;
3229: }
3230:
3231:
3232: 3233: 3234: 3235: 3236: 3237: 3238: 3239:
3240: function _check_parameters(&$p_params, $p_default)
3241: {
3242:
3243:
3244: if (!is_array($p_params)) {
3245: $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER,
3246: 'Unsupported parameter, waiting for an array');
3247: return Archive_Zip::errorCode();
3248: }
3249:
3250:
3251: for (reset($p_params); list($v_key, $v_value) = each($p_params); ) {
3252: if (!isset($p_default[$v_key])) {
3253: $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER,
3254: 'Unsupported parameter with key \''.$v_key.'\'');
3255:
3256: return Archive_Zip::errorCode();
3257: }
3258: }
3259:
3260:
3261: for (reset($p_default); list($v_key, $v_value) = each($p_default); ) {
3262: if (!isset($p_params[$v_key])) {
3263: $p_params[$v_key] = $p_default[$v_key];
3264: }
3265: }
3266:
3267:
3268: $v_callback_list = array ('callback_pre_add','callback_post_add',
3269: 'callback_pre_extract','callback_post_extract');
3270: for ($i=0; $i<sizeof($v_callback_list); $i++) {
3271: $v_key=$v_callback_list[$i];
3272: if ( (isset($p_params[$v_key])) && ($p_params[$v_key] != '')) {
3273: if (!function_exists($p_params[$v_key])) {
3274: $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAM_VALUE,
3275: "Callback '".$p_params[$v_key]
3276: ."()' is not an existing function for "
3277: ."parameter '".$v_key."'");
3278: return Archive_Zip::errorCode();
3279: }
3280: }
3281: }
3282:
3283: return(1);
3284: }
3285:
3286:
3287:
3288:
3289:
3290:
3291:
3292: 3293: 3294: 3295: 3296: 3297: 3298: 3299:
3300: function _errorLog($p_error_code=0, $p_error_string='')
3301: {
3302: $this->_error_code = $p_error_code;
3303: $this->_error_string = $p_error_string;
3304: }
3305:
3306:
3307:
3308:
3309:
3310:
3311:
3312: 3313: 3314: 3315: 3316: 3317:
3318: function _errorReset()
3319: {
3320: $this->_error_code = 1;
3321: $this->_error_string = '';
3322: }
3323:
3324:
3325:
3326:
3327:
3328:
3329:
3330:
3331: 3332: 3333: 3334: 3335: 3336:
3337: function _tool_PathReduction($p_dir)
3338: {
3339: $v_result = "";
3340:
3341:
3342: if ($p_dir != "")
3343: {
3344:
3345: $v_list = explode("/", $p_dir);
3346:
3347:
3348: for ($i=sizeof($v_list)-1; $i>=0; $i--)
3349: {
3350:
3351: if ($v_list[$i] == ".")
3352: {
3353:
3354:
3355: }
3356: else if ($v_list[$i] == "..")
3357: {
3358:
3359: $i--;
3360: }
3361: else if (($v_list[$i] == "") && ($i!=(sizeof($v_list)-1)) && ($i!=0))
3362: {
3363:
3364:
3365: }
3366: else
3367: {
3368: $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
3369: }
3370: }
3371: }
3372:
3373:
3374: return $v_result;
3375: }
3376:
3377:
3378:
3379:
3380:
3381:
3382:
3383:
3384:
3385:
3386:
3387:
3388:
3389:
3390:
3391:
3392:
3393: 3394: 3395: 3396: 3397: 3398:
3399: function _tool_PathInclusion($p_dir, $p_path)
3400: {
3401: $v_result = 1;
3402:
3403:
3404: $v_list_dir = explode("/", $p_dir);
3405: $v_list_dir_size = sizeof($v_list_dir);
3406: $v_list_path = explode("/", $p_path);
3407: $v_list_path_size = sizeof($v_list_path);
3408:
3409:
3410: $i = 0;
3411: $j = 0;
3412: while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
3413:
3414:
3415: if ($v_list_dir[$i] == '') {
3416: $i++;
3417: continue;
3418: }
3419: if ($v_list_path[$j] == '') {
3420: $j++;
3421: continue;
3422: }
3423:
3424:
3425: if ( ($v_list_dir[$i] != $v_list_path[$j])
3426: && ($v_list_dir[$i] != '')
3427: && ( $v_list_path[$j] != '')) {
3428: $v_result = 0;
3429: }
3430:
3431:
3432: $i++;
3433: $j++;
3434: }
3435:
3436:
3437: if ($v_result) {
3438:
3439: while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
3440: while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
3441:
3442: if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
3443:
3444: $v_result = 2;
3445: }
3446: else if ($i < $v_list_dir_size) {
3447:
3448: $v_result = 0;
3449: }
3450: }
3451:
3452:
3453: return $v_result;
3454: }
3455:
3456:
3457:
3458:
3459:
3460:
3461:
3462:
3463:
3464:
3465:
3466:
3467:
3468: 3469: 3470: 3471: 3472: 3473: 3474:
3475: function _tool_CopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
3476: {
3477: $v_result = 1;
3478:
3479: if ($p_mode==0)
3480: {
3481: while ($p_size != 0)
3482: {
3483: $v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
3484: ? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
3485: $v_buffer = @fread($p_src, $v_read_size);
3486: @fwrite($p_dest, $v_buffer, $v_read_size);
3487: $p_size -= $v_read_size;
3488: }
3489: }
3490: else if ($p_mode==1)
3491: {
3492: while ($p_size != 0)
3493: {
3494: $v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
3495: ? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
3496: $v_buffer = @gzread($p_src, $v_read_size);
3497: @fwrite($p_dest, $v_buffer, $v_read_size);
3498: $p_size -= $v_read_size;
3499: }
3500: }
3501: else if ($p_mode==2)
3502: {
3503: while ($p_size != 0)
3504: {
3505: $v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
3506: ? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
3507: $v_buffer = @fread($p_src, $v_read_size);
3508: @gzwrite($p_dest, $v_buffer, $v_read_size);
3509: $p_size -= $v_read_size;
3510: }
3511: }
3512: else if ($p_mode==3)
3513: {
3514: while ($p_size != 0)
3515: {
3516: $v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
3517: ? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
3518: $v_buffer = @gzread($p_src, $v_read_size);
3519: @gzwrite($p_dest, $v_buffer, $v_read_size);
3520: $p_size -= $v_read_size;
3521: }
3522: }
3523:
3524:
3525: return $v_result;
3526: }
3527:
3528:
3529:
3530:
3531:
3532:
3533:
3534:
3535:
3536:
3537:
3538:
3539:
3540:
3541: 3542: 3543: 3544: 3545: 3546:
3547: function _tool_Rename($p_src, $p_dest)
3548: {
3549: $v_result = 1;
3550:
3551:
3552: if (!@rename($p_src, $p_dest)) {
3553:
3554:
3555: if (!@copy($p_src, $p_dest)) {
3556: $v_result = 0;
3557: }
3558: else if (!@unlink($p_src)) {
3559: $v_result = 0;
3560: }
3561: }
3562:
3563:
3564: return $v_result;
3565: }
3566:
3567:
3568:
3569:
3570:
3571:
3572:
3573:
3574:
3575:
3576:
3577:
3578:
3579: 3580: 3581: 3582: 3583: 3584: 3585:
3586: function _tool_TranslateWinPath($p_path, $p_remove_disk_letter=true)
3587: {
3588: if (stristr(php_uname(), 'windows')) {
3589:
3590: if ( ($p_remove_disk_letter)
3591: && (($v_position = strpos($p_path, ':')) != false)) {
3592: $p_path = substr($p_path, $v_position+1);
3593: }
3594:
3595: if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
3596: $p_path = strtr($p_path, '\\', '/');
3597: }
3598: }
3599: return $p_path;
3600: }
3601:
3602:
3603: }
3604:
3605:
3606: ?>