~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Frontier Kernel
Frontier/Common/source/file.c

Version: ~ [ 10.0 ] ~

** Warning: Cannot open xref database.

1 2 /* $Id: file.c,v 1.4 2005/01/11 22:48:05 andreradke Exp $ */ 3 4 /****************************************************************************** 5 6 UserLand Frontier(tm) -- High performance Web content management, 7 object database, system-level and Internet scripting environment, 8 including source code editing and debugging. 9 10 Copyright (C) 1992-2004 UserLand Software, Inc. 11 12 This program is free software; you can redistribute it and/or modify 13 it under the terms of the GNU General Public License as published by 14 the Free Software Foundation; either version 2 of the License, or 15 (at your option) any later version. 16 17 This program is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU General Public License for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program; if not, write to the Free Software 24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 26 ******************************************************************************/ 27 28 #include "frontier.h" 29 #include "standard.h" 30 31 #ifdef MACVERSION 32 #if TARGET_API_MAC_CARBON 33 #include "MoreFilesX.h" 34 #else 35 #include "MoreFilesExtras.h" 36 #endif 37 #endif 38 39 #include "filealias.h" 40 #include "cursor.h" 41 #include "dialogs.h" 42 #include "error.h" 43 #include "mac.h" 44 #include "memory.h" 45 #include "ops.h" 46 #include "quickdraw.h" 47 #include "resources.h" 48 #include "strings.h" 49 #include "frontierwindows.h" 50 #include "file.h" 51 #include "shell.h" 52 #include "shell.rsrc.h" 53 #include "langinternal.h" /*for langbackgroundtask*/ 54 55 56 #ifdef MACVERSION 57 #ifdef flcomponent 58 59 #include "SetUpA5.h" 60 61 #endif 62 #endif 63 64 65 66 boolean equalfilespecs (const tyfilespec *fs1, const tyfilespec *fs2) { 67 68 /* 69 5.0a25 dmb: until we set the volumeID to zero for all Win fsspecs, 70 we must not compare them here 71 */ 72 73 #ifdef MACVERSION 74 if ((*fs1).vRefNum != (*fs2).vRefNum) 75 return (false); 76 77 if ((*fs1).parID != (*fs2).parID) 78 return (false); 79 80 return (equalstrings ((ptrstring) fsname (fs1), (ptrstring) fsname (fs2))); 81 #endif 82 #ifdef WIN95VERSION 83 //if ((*fs1).volumeID != (*fs2).volumeID) 84 // return (false); 85 86 return (lstrcmp(fsname (fs1), fsname (fs2)) == 0); 87 #endif 88 } /*equalfilespecs*/ 89 90 91 boolean filesetposition (hdlfilenum fnum, long position) { 92 93 /* 94 5.0.2b6 dmb: report errors 95 */ 96 97 #ifdef MACVERSION 98 return (!oserror (SetFPos (fnum, fsFromStart, position))); 99 #endif 100 101 #ifdef WIN95VERSION 102 if (SetFilePointer (fnum, position, NULL, FILE_BEGIN) == -1L) { 103 104 winerror (); 105 106 return (false); 107 } 108 109 return (true); 110 #endif 111 } /*filesetposition*/ 112 113 114 boolean filegetposition (hdlfilenum fnum, long *position) { 115 116 #ifdef MACVERSION 117 return (!oserror (GetFPos (fnum, position))); 118 #endif 119 120 #ifdef WIN95VERSION 121 *position = SetFilePointer (fnum, 0L, NULL, FILE_CURRENT); 122 123 if (*position == -1L) { 124 125 winerror (); 126 127 return (false); 128 } 129 130 return (true); 131 #endif 132 } /*filegetposition*/ 133 134 135 boolean filegeteof (hdlfilenum fnum, long *position) { 136 137 #ifdef MACVERSION 138 /* 139 6/x/91 mao 140 */ 141 142 return (!oserror (GetEOF (fnum, position))); 143 #endif 144 145 #ifdef WIN95VERSION 146 long origpos; 147 148 filegetposition (fnum, &origpos); 149 150 *position = SetFilePointer (fnum, 0L, NULL, FILE_END); 151 152 filesetposition (fnum, origpos); 153 154 if (*position == -1L) { 155 156 winerror (); 157 158 return (false); 159 } 160 161 return (true); 162 #endif 163 } /*filegeteof*/ 164 165 166 boolean fileseteof (hdlfilenum fnum, long position) { 167 168 /* 169 5.0.2b6 dmb: report errors 170 */ 171 172 #ifdef MACVERSION 173 return (!oserror (SetEOF (fnum, position))); 174 #endif 175 176 #ifdef WIN95VERSION 177 long currentPosition; 178 179 currentPosition = SetFilePointer (fnum, 0L, NULL, FILE_CURRENT); 180 181 if (currentPosition == -1L) 182 goto error; 183 184 if (SetFilePointer (fnum, position, NULL, FILE_BEGIN) == -1L) 185 goto error; 186 187 if (!SetEndOfFile (fnum)) 188 goto error; 189 190 if (SetFilePointer (fnum, currentPosition, NULL, FILE_BEGIN) == -1L) 191 goto error; 192 193 return (true); 194 195 error: 196 winerror (); 197 198 return (false); 199 #endif 200 } /*fileseteof*/ 201 202 203 long filegetsize (hdlfilenum fnum) { 204 205 /* 206 get the size of a file that's already open. 207 */ 208 209 #ifdef MACVERSION 210 long filesize; 211 212 if (GetEOF (fnum, &filesize) != noErr) 213 filesize = 0; 214 215 return (filesize); 216 #endif 217 218 #ifdef WIN95VERSION 219 long filesize; 220 221 filesize = GetFileSize (fnum, NULL); 222 if (filesize == -1L) 223 filesize = 0L; 224 225 return (filesize); 226 #endif 227 } /*filegetsize*/ 228 229 230 boolean filetruncate (hdlfilenum fnum) { 231 232 return (fileseteof (fnum, 0L)); 233 } /*filetruncate*/ 234 235 236 boolean filewrite (hdlfilenum fnum, long ctwrite, void *buffer) { 237 238 /* 239 write ctwrite bytes from buffer to the current position in file number 240 fnum. return true iff successful. 241 */ 242 243 if (ctwrite > 0) { 244 245 #ifdef MACVERSION 246 if (oserror (FSWrite (fnum, &ctwrite, buffer))) 247 return (false); 248 #endif 249 250 #ifdef WIN95VERSION 251 DWORD numberBytesWritten; 252 253 if (WriteFile (fnum, buffer, ctwrite, &numberBytesWritten, NULL)) { 254 255 if ((DWORD)ctwrite == numberBytesWritten) 256 return (true); 257 } 258 259 winerror(); 260 261 return (false); 262 #endif 263 } 264 265 return (true); 266 } /*filewrite*/ 267 268 269 boolean filereaddata (hdlfilenum fnum, long ctread, long *ctactual, void *buffer) { 270 271 /* 272 lower level than fileread, we can read less than the number of 273 bytes requested. 274 */ 275 276 *ctactual = ctread; 277 278 if (ctread > 0) { 279 280 #ifdef MACVERSION 281 OSErr ec = FSRead (fnum, ctactual, buffer); 282 283 if (ec != noErr && ec != eofErr) { 284 285 oserror (ec); 286 287 return (false); 288 } 289 #endif 290 291 #ifdef WIN95VERSION 292 if (!ReadFile (fnum, buffer, ctread, ctactual, NULL)) { 293 294 winerror (); 295 296 return (false); 297 } 298 #endif 299 } 300 301 return (true); 302 } /*filereaddata*/ 303 304 305 boolean fileread (hdlfilenum fnum, long ctread, void *buffer) { 306 307 /* 308 read ctread bytes from the current position in file number fnum into 309 the buffer. return true iff successful. 310 */ 311 312 long ctactual; 313 314 if (!filereaddata (fnum, ctread, &ctactual, buffer)) 315 return (false); 316 317 if (ctactual < ctread) { 318 319 #ifdef MACVERSION 320 oserror (eofErr); 321 #endif 322 #ifdef WIN95VERSION 323 oserror (ERROR_HANDLE_EOF); 324 #endif 325 326 return (false); 327 } 328 329 return (true); 330 } /*fileread*/ 331 332 333 boolean filegetchar (hdlfilenum fnum, char *ch) { 334 335 /* 336 long pos; 337 338 if (!filegetposition (fnum, &pos)) 339 return (false); 340 341 if (pos >= filegetsize (fnum)) { 342 343 *fleof = true; 344 345 return (true); 346 } 347 348 *fleof = false; 349 */ 350 351 return (fileread (fnum, (long) 1, ch)); 352 } /*filegetchar*/ 353 354 355 boolean fileputchar (hdlfilenum fnum, char ch) { 356 357 return (filewrite (fnum, (long) 1, &ch)); 358 } /*fileputchar*/ 359 360 361 boolean filewritehandle (hdlfilenum fnum, Handle h) { 362 363 /* 364 write the indicated handle to the open file indicated by fnum at the 365 current position in the file. 366 */ 367 368 return (filewrite (fnum, gethandlesize (h), *h)); 369 } /*filewritehandle*/ 370 371 372 /* 373 static boolean filereadhandlebytes (short fnum, long ctbytes, Handle *hreturned) { 374 375 /% 376 6/x/91 mao 377 this one is parallel to filewritehandle 378 %/ 379 380 register Handle h; 381 382 if (!newclearhandle (ctbytes, hreturned)) 383 return (false); 384 385 h = *hreturned; /%copy into register%/ 386 387 if (oserror (fileread (fnum, ctbytes, *h))) { 388 389 disposehandle (h); 390 391 return (false); 392 } 393 394 return (true); 395 } /%filereadhandlebytes%/ 396 */ 397 398 399 boolean filereadhandle (hdlfilenum fnum, Handle *hreturned) { 400 401 /* 402 not exactly parallel to filewritehandle. we read the whole file into the 403 indicated handle and return true if it worked. 404 */ 405 406 register long filesize; 407 register Handle h; 408 409 filesize = filegetsize (fnum); 410 411 if (!newclearhandle (filesize, hreturned)) 412 return (false); 413 414 h = *hreturned; /*copy into register*/ 415 416 if (!fileread (fnum, filesize, *h)) { 417 418 disposehandle (h); 419 420 return (false); 421 } 422 423 return (true); 424 } /*filereadhandle*/ 425 426 427 #ifdef MACVERSION 428 429 //Code change by Timothy Paustian Monday, June 19, 2000 3:15:01 PM 430 //Changed to Opaque call for Carbon 431 432 static pascal void iocompletion (ParmBlkPtr pb) { 433 434 DisposePtr ((Ptr) pb); 435 } /*iocompletion*/ 436 437 438 #if TARGET_RT_MAC_CFM || TARGET_RT_MAC_MACHO 439 440 #if TARGET_API_MAC_CARBON 441 442 //looks like we need some kind of file UPP 443 //do we need to create a UPP, yes we do. 444 IOCompletionUPP iocompletionDesc = nil; 445 446 #define iocompletionUPP (iocompletionDesc) 447 448 #else 449 450 static RoutineDescriptor iocompletionDesc = BUILD_ROUTINE_DESCRIPTOR (uppIOCompletionProcInfo, iocompletion); 451 452 #define iocompletionUPP (&iocompletionDesc) 453 454 #endif 455 456 #else 457 458 static IOCompletionUPP iocompletionUPP = &iocompletion; 459 460 #endif 461 462 #endif //MACVERSION 463 464 boolean flushvolumechanges (const tyfilespec *fs, hdlfilenum fnum) { 465 #ifdef MACVERSION 466 /* 467 4.1b7 dmb: was -- FlushVol (nil, (*fs).vRefNum); 468 469 now use PB call to do asynch flush 470 */ 471 472 ParamBlockRec *pb; 473 474 pb = (ParamBlockRec *) NewPtrClear (sizeof (ParamBlockRec)); 475 476 (*pb).volumeParam.ioVRefNum = (*fs).vRefNum; 477 478 (*pb).volumeParam.ioCompletion = iocompletionUPP; 479 480 PBFlushVolAsync (pb); 481 #endif 482 483 #ifdef WIN95VERSION 484 if (fnum != NULL) 485 FlushFileBuffers (fnum); 486 #endif 487 return (true); 488 } /*flushvolumechanges*/ 489 490 //Code change by Timothy Paustian Wednesday, July 26, 2000 10:52:49 PM 491 //new routine to create UPPS for the async file saves. 492 void fileinit (void) { 493 #if TARGET_API_MAC_CARBON 494 if(iocompletionDesc == nil) 495 iocompletionDesc = NewIOCompletionUPP(iocompletion); 496 #endif 497 } /*fileinit*/ 498 499 500 void fileshutdown(void) { 501 502 #if TARGET_API_MAC_CARBON 503 if(iocompletionDesc != nil) 504 DisposeIOCompletionUPP(iocompletionDesc); 505 #endif 506 } /*fileshutdown*/ 507 508 509 static boolean filecreateandopen (const tyfilespec *fs, OSType creator, OSType filetype, hdlfilenum *fnum) { 510 #ifdef MACVERSION 511 OSStatus err = noErr; 512 // char s[256]; 513 514 setfserrorparam (fs); 515 516 if (oserror (FSpCreate (fs, creator, filetype, smSystemScript))) /*failed to open the file for writing*/ 517 return (false); 518 519 if (oserror (FSpOpenDF (fs, fsRdWrPerm, fnum))) { 520 521 FSClose (*fnum); 522 523 deletefile (fs); 524 525 return (false); /*failed to open the file for writing*/ 526 } 527 528 #if TARGET_API_MAC_CARBON 529 { 530 FSRef myRef; 531 err = FSpMakeFSRef (fs,&myRef); 532 if (!err) 533 FSSetNameLocked(&myRef); 534 } 535 #endif 536 537 return (true); 538 #endif 539 540 #ifdef WIN95VERSION 541 HANDLE fref; 542 543 fref = (Handle) CreateFile (stringbaseaddress (fsname (fs)), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 544 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 545 *fnum = 0; 546 547 if (fref == INVALID_HANDLE_VALUE) { 548 549 winfileerror (fs); 550 551 return (false); 552 } 553 554 *fnum = (hdlfilenum) fref; 555 return (true); 556 #endif 557 } /*filecreateandopen*/ 558 559 560 boolean fileopenorcreate (const tyfilespec *fs, OSType creator, OSType filetype, hdlfilenum *fnum) { 561 #ifdef MACVERSION 562 /* 563 open or create a file indicated by fs. return with fnum set to the Mac 564 filesystem's file number for the file. 565 566 if we open a file, we takes what we get in the creator and filetype department. 567 however, if we create a file it's of the indicated filetype and creator. 568 */ 569 570 if (FSpOpenDF (fs, fsRdWrPerm, fnum) == noErr) { 571 /*file exists and is open*/ 572 #if TARGET_API_MAC_CARBON 573 FSRef myRef; 574 if (FSpMakeFSRef (fs,&myRef)) 575 FSSetNameLocked(&myRef); 576 #else 577 FSpSetNameLocked(&fs); 578 #endif 579 return (true); 580 } 581 return (filecreateandopen (fs, creator, filetype, fnum)); 582 #endif 583 584 #ifdef WIN95VERSION 585 HANDLE fref; 586 DWORD dAccess; 587 char fn[300]; 588 589 dAccess = GENERIC_READ | GENERIC_WRITE; 590 591 copystring (fsname (fs), fn); 592 593 nullterminate (fn); 594 595 fref = (Handle) CreateFile (stringbaseaddress(fn), dAccess, FILE_SHARE_READ, 596 NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 597 *fnum = 0; 598 599 if (fref == INVALID_HANDLE_VALUE) { 600 601 winfileerror (fs); 602 603 return (false); 604 } 605 606 *fnum = (hdlfilenum) fref; 607 return (true); 608 #endif 609 } /*fileopenorcreate*/ 610 611 612 boolean opennewfile (const tyfilespec *fs, OSType creator, OSType filetype, hdlfilenum *fnum) { 613 614 boolean flfolder; 615 616 if (fileexists (fs, &flfolder)) { /*file exists, delete it*/ 617 //WriteToConsole("We're deleting a file that already exists. No idea why."); 618 if (!deletefile (fs)) 619 return (false); 620 } 621 622 return (filecreateandopen (fs, creator, filetype, fnum)); 623 } /*opennewfile*/ 624 625 626 boolean openfile (const tyfilespec *fs, hdlfilenum *fnum, boolean flreadonly) { 627 628 #ifdef MACVERSION 629 /* 630 5/23/91 dmb: make sure we clear fnum on error; if file is already open, 631 FSOpen will set fnum to the existing channel 632 633 4.1b4 dmb: added flreadonly paramater 634 */ 635 636 OSErr errcode; 637 OSErr err = noErr; 638 short perm; 639 640 setfserrorparam (fs); /*in case error message takes a filename parameter*/ 641 642 if (flreadonly) perm = fsRdPerm; 643 else perm = fsRdWrPerm; 644 645 646 errcode = FSpOpenDF (fs, perm, fnum); 647 648 if (oserror (errcode)) { 649 650 *fnum = 0; 651 652 return (false); 653 } 654 #if TARGET_API_MAC_CARBON 655 { 656 FSRef myRef; 657 err = FSpMakeFSRef (fs,&myRef); 658 if (!err) 659 err = FSSetNameLocked(&myRef); 660 } 661 #else 662 err = FSpSetNameLocked(fs); 663 #endif 664 665 if (err!=noErr){ 666 //sprintf(s,"error locking file name: %d",err); 667 //WriteToConsole(s); 668 } 669 670 return (true); 671 #endif 672 673 #ifdef WIN95VERSION 674 HANDLE fref; 675 DWORD dAccess; 676 char fn[300]; 677 678 if (flreadonly) 679 dAccess = GENERIC_READ; 680 else 681 dAccess = GENERIC_READ | GENERIC_WRITE; 682 683 copystring (fsname (fs), fn); 684 685 nullterminate (fn); 686 687 fref = (Handle) CreateFile (stringbaseaddress(fn), dAccess, FILE_SHARE_READ, 688 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 689 *fnum = 0; 690 691 if (fref == INVALID_HANDLE_VALUE) { 692 693 winfileerror (fs); 694 695 return (false); 696 } 697 698 *fnum = (hdlfilenum) fref; 699 return (true); 700 #endif 701 } /*openfile*/ 702 703 /******* 704 705 From MoreFilesExtras. 706 I'm going to use this to yank the fsspec back out from a refnum, 707 so that I can clear the finder name lock from the file prior to closing it. 708 709 *******/ 710 711 712 boolean closefile (hdlfilenum fnum) { 713 #ifdef MACVERSION 714 OSStatus err = noErr; 715 // char s[256]; 716 717 /* 718 dmb 8/20/90: check for 0. 719 */ 720 721 if (fnum != 0) { 722 #if TARGET_API_MAC_CARBON 723 FSRef myRef; 724 err = FileRefNumGetFSRef (fnum, &myRef); 725 if (err == noErr) { 726 FSClearNameLocked (&myRef); 727 } 728 #else 729 FSSpec fs; 730 err = FSpGetFileLocation (fnum,&fs); 731 if (err==noErr) { 732 FSpClearNameLocked (&fs); 733 } 734 #endif 735 else { 736 //sprintf(s,"Error is %d",err); 737 //WriteToConsole(s); 738 } 739 740 return (!oserror (FSClose (fnum))); 741 } 742 743 return (true); 744 #endif 745 746 #ifdef WIN95VERSION 747 if (fnum != 0) { 748 749 if (!CloseHandle (fnum)) { 750 751 winerror (); 752 753 return (false); 754 } 755 } 756 757 return (true); 758 #endif 759 } /*closefile*/ 760 761 762 boolean deletefile (const tyfilespec *fs) { 763 764 /* 765 2.1b2 dmb: new filespec-based version 766 767 5.0.1 dmb: always setsferror param 768 */ 769 770 #ifdef MACVERSION 771 setfserrorparam (fs); /*in case error message takes a filename parameter*/ 772 #if TARGET_API_MAC_CARBON 773 { 774 FSRef myRef; 775 if (FSpMakeFSRef (fs,&myRef)) 776 FSClearNameLocked(&myRef); 777 } 778 #else 779 FSpClearNameLocked(fs); 780 #endif 781 return (!oserror (FSpDelete (fs))); 782 #endif 783 784 #ifdef WIN95VERSION 785 char fn[300]; 786 boolean fldeletefolder; 787 788 setfserrorparam (fs); /*in case error message takes a filename parameter*/ 789 790 copystring (fsname (fs), fn); 791 792 cleanendoffilename(fn); 793 794 nullterminate (fn); 795 796 if (!fileisfolder (fs, &fldeletefolder)) 797 return (false); 798 799 if (fldeletefolder) { 800 801 if (RemoveDirectory (stringbaseaddress(fn))) 802 return (true); 803 804 goto error; 805 } 806 807 if (DeleteFile (stringbaseaddress(fn))) 808 return (true); 809 810 error: 811 winerror (); 812 813 return (false); 814 #endif 815 } /*deletefile*/ 816 817 818 819 boolean fileexists (const tyfilespec *fs, boolean *flfolder) { 820 #ifdef MACVERSION 821 /* 822 we figure if we can get info on it, it must exist. 823 824 can't call filegetinfo because it has an error message if the file 825 isn't found. 826 827 7/1/91 dmb: special case empty string so we don't try to get info about 828 the default volume and return true. 829 830 2.1b2 dmb: filespec implementation 831 832 5.0.2b15 rab: return false to non-existent volume specs. 833 */ 834 835 CInfoPBRec pb; 836 837 *flfolder = false; 838 839 if (isemptystring (fsname (fs))) 840 return (false); 841 842 clearbytes (&pb, sizeof (pb)); 843 844 pb.hFileInfo.ioNamePtr = (StringPtr) fsname (fs); 845 846 pb.hFileInfo.ioVRefNum = (*fs).vRefNum; 847 848 pb.hFileInfo.ioDirID = (*fs).parID; 849 850 if (PBGetCatInfoSync (&pb) != noErr) 851 return (false); 852 853 *flfolder = foldertest (&pb); 854 855 return (true); 856 #endif 857 #ifdef WIN95VERSION 858 HANDLE ff; 859 WIN32_FIND_DATA ffd; 860 char fn[300]; 861 862 *flfolder = false; 863 864 copystring (fsname (fs), fn); 865 866 /*if ends with \ get ride of it... and handle the root*/ 867 868 cleanendoffilename (fn); 869 870 nullterminate (fn); 871 872 if (stringlength(fn) == 2) { 873 if (isalpha(fn[1]) && fn[2] == ':') { 874 *flfolder = true; 875 return (fileisvolume(fs)); 876 } 877 } 878 879 ff = FindFirstFile (stringbaseaddress(fn), &ffd); 880 881 if (ff == INVALID_HANDLE_VALUE) 882 return (false); 883 884 *flfolder = ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY?true:false; 885 886 FindClose (ff); 887 return (true); 888 #endif 889 } /*fileexists*/ 890 891 892 boolean filegetfilename (const tyfilespec *pfs, bigstring name) { 893 894 #if MACVERSION 895 /* 896 filespecs for volumes have their strings set to the empty string. 897 */ 898 899 copystring (fsname (pfs), name); 900 901 if (stringlength (name) > 0) 902 return (true); 903 904 return (filegetvolumename ((*pfs).vRefNum, name)); 905 #endif 906 907 #if WIN95VERSION 908 lastword ((ptrstring) fsname (pfs), '\\', name); 909 910 return (true); 911 #endif 912 } /*filegetfilename*/ 913 914

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.