Version:
~ [ 10.0 ] ~
** Warning: Cannot open xref database.
1
2 /* $Id: fileverbs.c,v 1.7 2005/10/07 04:07:42 icreedon 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 #include "error.h"
32 #include "memory.h"
33 #include "strings.h"
34 #include "ops.h"
35 #include "resources.h"
36 #include "lang.h"
37 #include "langexternal.h"
38 #include "langinternal.h"
39 #include "langsystem7.h"
40 #include "process.h"
41 #include "kernelverbs.h"
42 #include "file.h"
43 #include "filesystem7.h"
44 #include "filealias.h"
45 #include "tablestructure.h"
46 #include "kernelverbdefs.h"
47 #include "shell.rsrc.h"
48
49
50 #ifdef MACVERSION
51 #define chpathseparator ':'
52 #endif
53
54 #ifdef WIN95VERSION
55 #define chpathseparator '\\'
56 #endif
57
58 boolean flsupportslargevolumes = false; /*true if volumes over 2 GB are supported by the OS*/
59
60
61 #ifdef WIN95VERSION
62
63 tyGetDiskFreeSpaceEx adrGetDiskFreeSpaceEx = NULL;
64
65 #endif
66
67
68 typedef enum tyfiletoken { /*verbs that are processed by file.c*/
69
70 filecreatedfunc,
71
72 filemodifiedfunc,
73
74 filetypefunc,
75
76 filecreatorfunc,
77
78 setfilecreatedfunc,
79
80 setfilemodifiedfunc,
81
82 setfiletypefunc,
83
84 setfilecreatorfunc,
85
86 fileisfolderfunc,
87
88 fileisvolumefunc,
89
90 fileislockedfunc,
91
92 filelockfunc,
93
94 fileunlockfunc,
95
96 filecopyfunc,
97
98 filecopydataforkfunc,
99
100 filecopyresourceforkfunc,
101
102 filedeletefunc,
103
104 filerenamefunc,
105
106 fileexistsfunc,
107
108 filesizefunc,
109
110 filefullpathfunc,
111
112 filegetpathfunc,
113
114 filesetpathfunc,
115
116 filefrompathfunc,
117
118 folderfrompathfunc,
119
120 /*
121 getprogrampathfunc,
122 */
123
124 getsystempathfunc,
125
126 getspecialpathfunc,
127
128 newfunc,
129
130 newfolderfunc,
131
132 newaliasfunc,
133
134 sfgetfilefunc,
135
136 sfputfilefunc,
137
138 sfgetfolderfunc,
139
140 sfgetdiskfunc,
141
142 filegeticonposfunc,
143
144 fileseticonposfunc,
145
146 getshortversionfunc,
147
148 setshortversionfunc,
149
150 getlongversionfunc,
151
152 setlongversionfunc,
153
154 filegetcommentfunc,
155
156 filesetcommentfunc,
157
158 filegetlabelfunc,
159
160 filesetlabelfunc,
161
162 filefindappfunc,
163
164 /*
165 fileeditlinefeedsfunc,
166 */
167
168 fileisbusyfunc,
169
170 filehasbundlefunc,
171
172 filesetbundlefunc,
173
174 fileisaliasfunc,
175
176 fileisvisiblefunc,
177
178 filesetvisiblefunc,
179
180 filefollowaliasfunc,
181
182 filemovefunc,
183
184 /*
185 filesinfolderfunc,
186 */
187
188 volumeejectfunc,
189
190 volumeisejectablefunc,
191
192 volumefreespacefunc,
193
194 volumesizefunc,
195
196 volumeblocksizefunc,
197
198 filesonvolumefunc,
199
200 foldersonvolumefunc,
201
202 unmountvolumefunc,
203
204 mountservervolumefunc,
205
206 /*
207 filelaunchfunc,
208 */
209
210 /*start of new verbs added by DW, 7/27/91*/
211
212 findinfilefunc,
213
214 countlinesfunc,
215
216 openfilefunc,
217
218 closefilefunc,
219
220 endoffilefunc,
221
222 setendoffilefunc,
223
224 getendoffilefunc,
225
226 setpositionfunc,
227
228 getpositionfunc,
229
230 readlinefunc,
231
232 writelinefunc,
233
234 readfunc,
235
236 writefunc,
237
238 comparefunc,
239
240 /*end of new verbs added by DW, 7/27/91*/
241
242 writewholefilefunc,
243
244 getpathcharfunc,
245
246 volumefreespacedoublefunc,
247
248 volumesizedoublefunc,
249
250 getmp3infofunc,
251
252 ctfileverbs
253 } tyfiletoken;
254
255
256 typedef enum tyreztoken {
257
258 rezgetresourcefunc,
259
260 rezputresourcefunc,
261
262 rezgetnamedresourcefunc,
263
264 rezputnamedresourcefunc,
265
266 rezcountrestypesfunc,
267
268 rezgetnthrestypefunc,
269
270 rezcountresourcesfunc,
271
272 rezgetnthresourcefunc,
273
274 rezgetnthresinfofunc,
275
276 rezresourceexistsfunc,
277
278 reznamedresourceexistsfunc,
279
280 rezdeleteresourcefunc,
281
282 rezdeletenamedresourcefunc,
283
284 rezgetresourceattrsfunc,
285
286 rezsetresourceattrsfunc,
287
288 ctrezverbs
289 } tyreztoken;
290
291
292
293 #if 0
294
295 static bigstring bsdefaultpath; /*see setpath*/
296
297
298 static checkfordrivenum (bigstring bspath) {
299
300 /*
301 interpret single-digit vol name as driver number
302 */
303
304 if ((stringlength (bspath) > 1) && (bspath [2] == chpathseparator)) {
305
306 byte ch = bspath [1];
307 short drivenum;
308 byte bsvol [64];
309
310 if (isnumeric (ch)) {
311
312 drivenum = ch - '';
313
314 if (drivenumtovolname (drivenum, bsvol))
315 replacestring (bspath, 1, 1, bsvol);
316 }
317 }
318 } /*checkfordrivenum*/
319
320
321 filecheckdefaultpath (bigstring bspath) {
322
323 /*
324 if bspath is a partial path, add our local current path, if set.
325
326 12/5/91 dmb: sneak in support drive number as "n:" here
327
328 12/27/91 dmb: if bsdefaultpath isn't empty, and we have a partial path,
329 make sure we don't double-up on colons if bspath starts with one.
330 */
331
332 short ix = 1;
333
334 if (!isemptystring (bspath)) {
335
336 if (!scanstring (chpathseparator, bspath, &ix) || (ix == 1)) { /*a partial path*/
337
338 if (!isemptystring (bsdefaultpath)) {
339
340 if (bspath [1] == chpathseparator) /*default path ends in one already*/
341 deletefirstchar (bspath);
342
343 insertstring (bsdefaultpath, bspath);
344 }
345 }
346
347 /*
348 else
349 checkfordrivenum (bspath);
350 */
351 }
352 } /*filecheckdefaultpath*/
353
354 #endif
355
356 static boolean getpathvalue (hdltreenode hparam1, short pnum, tyfilespec *fspath) {
357
358 /*
359 get a path parameter for the parameter list.
360
361 2.1b2 dmb: now that we use filespecs everywhere, we don't have much to do!
362 */
363
364 return (getfilespecvalue (hparam1, pnum, fspath));
365
366 /*
367 tyvaluerecord v;
368 bigstring bspath;
369
370 if (!getparamvalue (hparam1, pnum, &v))
371 return (false);
372
373 switch (v.valuetype) {
374
375 case stringvaluetype:
376
377 pullstringvalue (&v, bspath);
378
379 filecheckdefaultpath (bspath);
380
381 if (!pathtofilespec (bspath, fspath)) {
382
383 filenotfounderror (bspath);
384
385 return (false);
386 }
387
388 break;
389
390 default:
391 if (!coercetofilespec (&v))
392 return (false);
393
394 *fspath = **(*v).data.filespecvalue;
395
396 break;
397
398 return (true);
399 }
400 */
401
402 return (true);
403 } /*getpathvalue*/
404
405
406 static boolean getvolumevalue (hdltreenode hparam1, short pnum, tyfilespec *fsvol) {
407
408 /*
409 get a volume path parameter for the parameter list.
410
411 make sure that a colon is included so a volume name isn't interpreted
412 as a partial path
413
414 2.1b8 dmb: don't use pathtofilespec to convert the volume name,
415 because FSMakeFSSpec will prompt the user to insert the disk if
416 the volume has been ejected
417
418 2.1b11 dmb: ooops, we were copying bsvol into fsvol.name, potentially
419 overflowing the str64. fileparsevolname now returns the vol name. note
420 that if the caller needs to distinguish between volumes and non-volumes,
421 it can't call us.
422 */
423
424 bigstring bsvol;
425 tyvaluerecord v;
426
427 if (!getparamvalue (hparam1, pnum, &v))
428 return (false);
429
430 switch (v.valuetype) {
431
432 case stringvaluetype:/*already a string, easy case*/
433
434 pullstringvalue (&v, bsvol);
435
436 #ifdef NEWFILESPECTYPE
437 if (!fileparsevolname (bsvol, &(*fsvol).volumeID, (*fsvol).fullSpecifier)) {
438 #else
439 if (!fileparsevolname (bsvol, &(*fsvol).vRefNum, (*fsvol).name)) {
440 #endif
441
442 setoserrorparam (bsvol);
443
444 oserror (errorVolume);
445
446 return (false);
447 }
448 #ifdef MACVERSION
449 (*fsvol).parID = fsRtParID;
450 #endif
451
452 /* old code for string paths, pre-filespecs
453 if (!stringfindchar (chpathseparator, bsvol))
454 pushchar (chpathseparator, bsvol);
455
456 if (!pathtofilespec (bsvol, fsvol)) {
457 setoserrorparam (bsvol);
458 oserror (errorVolume);
459 return (false);
460 }
461 */
462
463 break;
464
465 default:
466 if (!coercetofilespec (&v))
467 return (false);
468
469 *fsvol = **v.data.filespecvalue;
470
471 break;
472
473 return (true);
474 }
475
476 return (true);
477 } /*getvolumevalue*/
478
479
480 static boolean copyfileverb (boolean fldata, boolean flresources, hdltreenode hparam1, tyvaluerecord *v) {
481
482 tyfilespec fs1, fs2;
483
484 if (!getpathvalue (hparam1, 1, &fs1)) /*fs1 holds the source path*/
485 return (false);
486
487 flnextparamislast = true;
488
489 if (!getpathvalue (hparam1, 2, &fs2)) /*fs2 holds the dest path*/
490 return (false);
491
492 if (equalfilespecs (&fs1, &fs2)) /*easy case making a copy of itself*/
493 (*v).data.flvalue = true;
494 else
495 (*v).data.flvalue = copyfile (&fs1, &fs2, fldata, flresources);
496
497 return (true);
498 } /*copyfileverb*/
499
500
501 static boolean filefrompathverb (hdltreenode hparam1, tyvaluerecord *vreturned) {
502
503 /*
504 2.1b2 dmb: do string manipulation if given a string, but otherwise
505 work with filespecs. less critical than with folderfrompath, but might
506 avoid full path string overflow
507
508 2.1b3 dmb: be sure to add colon to name of folder even when filespec is
509 being used.
510 */
511
512 tyvaluerecord v;
513 tyfilespec fs;
514 bigstring bs;
515 boolean flfolder;
516
517 flnextparamislast = true;
518
519 if (!getparamvalue (hparam1, 1, &v))
520 return (false);
521
522 switch (v.valuetype) {
523
524 case stringvaluetype:
525 pullstringvalue (&v, bs);
526
527 flfolder = endswithpathsep(bs);
528
529 if (flfolder)
530 setstringlength (bs, stringlength (bs) - 1);
531
532 filefrompath (bs, bs); /*bs now holds the filename*/
533
534 break;
535
536 default:
537 if (!coercetofilespec (&v))
538 return (false);
539
540 #if TARGET_API_MAC_CARBON == 1
541
542 fs.vRefNum = (**v.data.filespecvalue).vRefNum;
543 fs.parID = (**v.data.filespecvalue).parID;
544
545 copystring ((**v.data.filespecvalue).name, fs.name);
546
547 #else
548
549 fs = **v.data.filespecvalue;
550
551 #endif
552
553 #ifdef NEWFILESPECTYPE
554 copystring (fs.fullSpecifier, bs);
555 #else
556 copystring (fs.name, bs);
557 #endif
558 /*
559 if (!fileexists (&fs, &flfolder) || !fileisfolder (&fs, &flfolder))
560 flfolder = false;
561 */
562 fileexists (&fs, &flfolder); /*don't care about return, just flfolder value*/
563 #ifdef WIN95VERSION
564 if (endswithpathsep (bs))
565 setstringlength (bs, stringlength (bs) - 1);
566
567 filefrompath (bs, bs);
568 #endif
569 break;
570 }
571
572 if (flfolder)
573 pushchar (chpathseparator, bs);
574
575 return (setstringvalue (bs, vreturned));
576 } /*filefrompathverb*/
577
578
579 static boolean folderfrompathverb (hdltreenode hparam1, tyvaluerecord *vreturned) {
580
581 /*
582 2.1b2 dmb: do string manipulation if given a string, but otherwise
583 work with filespecs. in addition to avoiding string overflow, this
584 preserves ability to distinguish between identically-named volumes
585 */
586
587 tyvaluerecord v;
588
589 flnextparamislast = true;
590
591 if (!getparamvalue (hparam1, 1, &v))
592 return (false);
593
594 #ifdef WIN95VERSION
595 if (!coercetostring (&v))
596 return (false);
597 #endif
598
599 switch (v.valuetype) {
600
601 case stringvaluetype: {
602 bigstring bs;
603
604 pullstringvalue (&v, bs);
605
606 cleanendoffilename (bs);
607
608 folderfrompath (bs, bs); /*bs now holds the foldername*/
609
610 return (setstringvalue (bs, vreturned));
611 }
612
613 default: {
614 #ifdef MACVERSION
615 tyfilespec fs;
616
617 if (!coercetofilespec (&v))
618 return (false);
619
620 #if TARGET_API_MAC_CARBON == 1
621
622 fs.vRefNum = (**v.data.filespecvalue).vRefNum;
623
624 fs.parID = (**v.data.filespecvalue).parID;
625
626 copystring ((**v.data.filespecvalue).name, fs.name);
627
628 #else
629
630 fs = **v.data.filespecvalue;
631
632 #endif
633
634 if (!getfileparentfolder (&fs, &fs))
635 return (false);
636
637 return (setfilespecvalue (&fs, vreturned));
638 #else
639 return (false);
640 #endif
641 }
642 }
643 } /*folderfrompathverb*/
644
645
646 static boolean gettypelistvalue (hdltreenode hparam1, short pnum, tysftypelist *filetypes, ptrsftypelist *x) {
647
648 /*
649 2.1b4 dmb: new feature: accept a list of filetype for sfgetfile
650 */
651
652 tyvaluerecord val;
653 tyvaluerecord vitem;
654 long ctitems;
655 short i;
656 // OSType toss;
657 OSType filetype;
658
659 if (!getparamvalue (hparam1, 3, &val))
660 return (false);
661
662 *x = filetypes; /*assume success & point to the typelist buffer*/
663
664 switch (val.valuetype) {
665
666 case listvaluetype:
667 if (!langgetlistsize (&val, &ctitems))
668 return (false);
669
670 ctitems = min (ctitems, maxsftypelist);
671
672 (*filetypes).cttypes = (short)ctitems;
673
674 for (i = 0; i < ctitems; ++i) {
675
676 if (!langgetlistitem (&val, i + 1, nil, &vitem))
677 return (false);
678
679 if (!coercetoostype (&vitem))
680 return (false);
681
682 (*filetypes).types [i] = vitem.data.ostypevalue;
683 }
684
685 break;
686
687 default:
688 if (!coercetoostype (&val))
689 return (false);
690
691 filetype = val.data.ostypevalue;
692
693 if (filetype == 0) /*no file type specified*/
694 *x = nil;
695
696 else {
697
698 (*filetypes).cttypes = 1;
699
700 (*filetypes).types [0] = filetype;
701 }
702 }
703
704 return (true);
705 } /*gettypelistvalue*/
706
707
708 static boolean filedialogverb (tysfverb sfverb, hdltreenode hparam1, tyvaluerecord *vreturned) {
709
710 /*
711 put up one of the "standard file" dialogs. if sfverb is sfputfileverb we use the "put" dialog, otherwise the "get" dialog.
712
713 we take at least one parameter -- the name of a variable to receive the full path specified by the user.
714
715 if it's the getfile dialog, we take a second parameter -- it indicates the
716 type of the file.
717
718 2005-10-06 creedon: added creator parameter
719
720 12/27/91 dmb: in all cases, check the current value of the filename variable, and pass it on to sf dialog so it can potentially set default directory.
721 */
722
723 bigstring bsprompt;
724 bigstring bsvarname;
725 tyfilespec fs;
726 tyvaluerecord val;
727 tysftypelist filetypes;
728 ptrsftypelist typelist = nil;
729 hdlhashtable htable;
730 boolean fl;
731 OSType ostype, oscreator = kNavGenericSignature;
732 bigstring bsext;
733 hdlhashnode hnode;
734
735 if (!getstringvalue (hparam1, 1, bsprompt))
736 return (false);
737
738 if (sfverb != sfgetfileverb)
739 flnextparamislast = true;
740
741 if (!getvarparam (hparam1, 2, &htable, bsvarname)) /*returned filename holder*/
742 return (false);
743
744 if (sfverb == sfgetfileverb) { /* get extra parameters for get file dialog, indicating file type(s) and file creator */
745
746 short ctconsumed = 3;
747 short ctpositional = 3;
748 tyvaluerecord val;
749
750 if (!gettypelistvalue (hparam1, 3, &filetypes, &typelist))
751 return (false);
752
753 flnextparamislast = true;
754
755 setostypevalue (oscreator, &val);
756
757 if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, "\x07""creator", &val))
758 return (false);
759
760 oscreator = val.data.ostypevalue;
761
762 }
763
764 clearbytes (&fs, sizeof (fs));
765
766 /*
767 if (idstringvalue (htable, bsvarname, bsfname))
768 filecheckdefaultpath (bsfname);
769 */
770
771 if (hashtablelookup (htable, bsvarname, &val, &hnode)) {
772
773 if (!copyvaluerecord (val, &val))
774 return (false);
775
776 disablelangerror ();
777
778 if (coercetofilespec (&val))
779 fs = **val.data.filespecvalue;
780
781 enablelangerror ();
782 }
783
784 if (sfverb == sfputfileverb) {
785 lastword (fsname(&fs), '.', bsext);
786
787 if (!((stringlength (fsname(&fs)) == stringlength (bsext)) || (stringlength (bsext) > 4))) { /* extension */
788 stringtoostype (bsext, &ostype);
789 filetypes.cttypes = 1;
790 filetypes.types [0] = ostype;
791 typelist = &filetypes;
792 }
793 }
794
795 setbooleanvalue (false, vreturned);
796
797 if (!sfdialog (sfverb, bsprompt, typelist, &fs, oscreator)) /*user hit cancel*/
798 return (true);
799
800 if (!setfilespecvalue (&fs, &val))
801 return (false);
802
803 pushhashtable (htable);
804
805 fl = langsetsymbolval (bsvarname, val);
806
807 pophashtable ();
808
809 if (!fl)
810 return (false);
811
812 exemptfromtmpstack (&val);
813
814 (*vreturned).data.flvalue = true; /*the user did select a file*/
815
816 return (true);
817 } /*filedialogverb*/
818
819
820 static boolean getstringorintvalue (hdltreenode hfirst, short pnum, boolean flstring, short *intval, bigstring bsval) {
821
822 /*
823 if the parameter value is a string, set intval to -1 and return the string;
824 otherwise, return the value as an integer and set bsval to the empty string.
825
826 7/29/91 dmb: now strictly enforce flstring; if true, paramter must coerce to a
827 string, otherwise to an int.
828 */
829
830 if (flstring) {
831
832 if (!getstringvalue (hfirst, pnum, bsval))
833 return (false);
834
835 *intval = -1;
836 }
837 else {
838
839 if (!getintvalue (hfirst, pnum, intval))
840 return (false);
841
842 setemptystring (bsval);
843 }
844
845 return (true);
846 } /*getstringorintvalue*/
847
848
849 static boolean getresourceverb (hdltreenode hparam1, boolean flnamed, tyvaluerecord *v) {
850
851 /*
852 2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
853 */
854
855 tyfilespec fs;
856 OSType type;
857 short id, forktype;
858 short ctconsumed = 4;
859 short ctpositional = 4;
860 Handle h;
861 hdlhashtable htable;
862 bigstring bs, bsvarname;
863 tyvaluerecord val;
864
865 if (!getpathvalue (hparam1, 1, &fs))
866 return (false);
867
868 if (!getostypevalue (hparam1, 2, &type))
869 return (false);
870
871 if (!getstringorintvalue (hparam1, 3, flnamed, &id, bs))
872 return (false);
873
874 if (!getvarparam (hparam1, 4, &htable, bsvarname)) /*returned handle holder*/
875 return (false);
876
877 flnextparamislast = true;
878
879 setintvalue (resourcefork, &val); /* defaults to 1 */
880
881 if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, "\x04""fork", &val))
882 return (false);
883
884 forktype = val.data.intvalue;
885
886 if (!loadresourcehandle (&fs, type, id, bs, &h, forktype)) {
887
888 (*v).data.flvalue = false;
889
890 return (true);
891 }
892
893 if (!insertinhandle (h, 0L, &type, sizeof (type))) { /*out of memory*/
894
895 disposehandle (h);
896
897 return (false);
898 }
899
900 if (!langsetbinaryval (htable, bsvarname, h))
901 return (false);
902
903 (*v).data.flvalue = true;
904
905 return (true);
906 } /*getresourceverb*/
907
908
909 static boolean putresourceverb (hdltreenode hparam1, boolean flnamed, tyvaluerecord *v) {
910
911 /*
912 2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
913 */
914
915 tyfilespec fs;
916 OSType type, bintype;
917 short id, forktype;
918 short ctconsumed = 4;
919 short ctpositional = 4;
920 Handle hbinary;
921 bigstring bs;
922 tyvaluerecord val;
923
924 if (!getpathvalue (hparam1, 1, &fs))
925 return (false);
926
927 if (!getostypevalue (hparam1, 2, &type))
928 return (false);
929
930 if (!getstringorintvalue (hparam1, 3, flnamed, &id, bs))
931 return (false);
932
933 if (!getbinaryvalue (hparam1, 4, false, &hbinary))
934 return (false);
935
936 pullfromhandle (hbinary, 0L, sizeof (bintype), &bintype);
937
938 flnextparamislast = true;
939
940 setintvalue (resourcefork, &val); /* defaults to 1 */
941
942 if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, "\x04""fork", &val))
943 return (false);
944
945 forktype = val.data.intvalue;
946
947 (*v).data.flvalue = saveresourcehandle (&fs, type, id, bs, hbinary, forktype);
948
949 return (true);
950 } /*putresourceverb*/
951
952
953 static boolean countrestypesverb (hdltreenode hparam1, tyvaluerecord *v) {
954
955 /*
956 2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
957 */
958
959 tyfilespec fs;
960 short cttypes, forktype;
961 short ctconsumed = 1;
962 short ctpositional = 1;
963 tyvaluerecord val;
964
965 if (!getpathvalue (hparam1, 1, &fs))
966 return (false);
967
968 flnextparamislast = true;
969
970 setintvalue (resourcefork, &val); /* defaults to 1 */
971
972 if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, "\x04""fork", &val))
973 return (false);
974
975 forktype = val.data.intvalue;
976
977 if (!getnumresourcetypes (&fs, &cttypes, forktype))
978 cttypes = 0;
979
980 setlongvalue (cttypes, v);
981
982 return (true);
983 } /*countrestypesverb*/
984
985
986 static boolean getnthrestypeverb (hdltreenode hparam1, tyvaluerecord *v) {
987
988 /*
989 2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
990 */
991
992 tyfilespec fs;
993 short n, forktype;
994 short ctconsumed = 3;
995 short ctpositional = 3;
996 OSType type;
997 hdlhashtable htable;
998 bigstring bsvarname;
999 tyvaluerecord val;
1000 boolean fl;
1001
1002 if (!getpathvalue (hparam1, 1, &fs))
1003 return (false);
1004
1005 if (!getintvalue (hparam1, 2, &n))
1006 return (false);
1007
1008 if (!getvarparam (hparam1, 3, &htable, bsvarname)) /*returned handle holder*/
1009 return (false);
1010
1011 flnextparamislast = true;
1012
1013 setintvalue (resourcefork, &val); /* defaults to 1 */
1014
1015 if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, "\x04""fork", &val))
1016 return (false);
1017
1018 forktype = val.data.intvalue;
1019
1020 if (!getnthresourcetype (&fs, n, &type, forktype)) { /*not a fatal error*/
1021
1022 (*v).data.flvalue = false;
1023
1024 return (true);
1025 }
1026
1027 setostypevalue (type, &val);
1028
1029 fl = langsetsymboltableval (htable, bsvarname, val);
1030
1031 (*v).data.flvalue = fl;
1032
1033 return (fl);
1034 } /*getnthrestypeverb*/
1035
1036
1037 static boolean countresourcesverb (hdltreenode hparam1, tyvaluerecord *v) {
1038
1039 /*
1040 2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
1041 */
1042
1043 tyfilespec fs;
1044 OSType type;
1045 short ctresources, forktype;
1046 short ctconsumed = 2;
1047 short ctpositional = 2;
1048 tyvaluerecord val;
1049
1050 if (!getpathvalue (hparam1, 1, &fs))
1051 return (false);
1052
1053 if (!getostypevalue (hparam1, 2, &type))
1054 return (false);
1055
1056 flnextparamislast = true;
1057
1058 setintvalue (resourcefork, &val); /* defaults to 1 */
1059
1060 if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, "\x04""fork", &val))
1061 return (false);
1062
1063 forktype = val.data.intvalue;
1064
1065 if (!getnumresources (&fs, type, &ctresources, forktype))
1066 ctresources = 0;
1067
1068 setlongvalue (ctresources, v);
1069
1070 return (true);
1071 } /*countresourcesverb*/
1072
1073
1074 static boolean getnthresourceverb (hdltreenode hparam1, tyvaluerecord *v) {
1075
1076 /*
1077 2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
1078 */
1079
1080 tyfilespec fs;
1081 OSType type;
1082 short n, id, forktype;
1083 short ctconsumed = 5;
1084 short ctpositional = 5;
1085 Handle h;
1086 hdlhashtable ht1, ht2;
1087 bigstring bs, bs1, bs2;
1088 boolean fl;
1089 tyvaluerecord val;
1090
1091 if (!getpathvalue (hparam1, 1, &fs))
1092 return (false);
1093
1094 if (!getostypevalue (hparam1, 2, &type))
1095 return (false);
1096
1097 if (!getintvalue (hparam1, 3, &n))
1098 return (false);
1099
1100 if (!getvarparam (hparam1, 4, &ht1, bs1)) /*returned name holder*/
1101 return (false);
1102
1103 if (!getvarparam (hparam1, 5, &ht2, bs2)) /*returned handle holder*/
1104 return (false);
1105
1106 flnextparamislast = true;
1107
1108 setintvalue (resourcefork, &val); /* defaults to 1 */
1109
1110 if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, "\x04""fork", &val))
1111 return (false);
1112
1113 forktype = val.data.intvalue;
1114
1115 if (!getnthresourcehandle (&fs, type, n, &id, bs, &h, forktype)) {
1116
1117 (*v).data.flvalue = false;
1118
1119 return (true);
1120 }
1121
1122 pushhashtable (ht1);
1123
1124 fl = langsetstringval (bs1, bs);
1125
1126 pophashtable ();
1127
1128 if (!fl)
1129 return (false);
1130
1131 if (!insertinhandle (h, 0L, &type, sizeof (type))) {
1132
1133 disposehandle (h);
1134
1135 return (false);
1136 }
1137
1138 if (!langsetbinaryval (ht2, bs2, h))
1139 return (false);
1140
1141 (*v).data.flvalue = true;
1142
1143 return (true);
1144 } /*getnthresourceverb*/
1145
1146
1147 static boolean getnthresinfoverb (hdltreenode hparam1, tyvaluerecord *v) {
1148
1149 /*
1150 2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
1151
1152 6/2/92 dmb: created.
1153 */
1154
1155 tyfilespec fs;
1156 OSType type;
1157 short n, id, forktype;
1158 short ctconsumed = 5;
1159 short ctpositional = 5;
1160 hdlhashtable ht1;
1161 bigstring bs, bs1;
1162 boolean fl;
1163 tyvaluerecord val;
1164
1165 if (!langcheckparamcount (hparam1, 6))
1166 return (false);
1167
1168 if (!getpathvalue (hparam1, 1, &fs))
1169 return (false);
1170
1171 if (!getostypevalue (hparam1, 2, &type))
1172 return (false);
1173
1174 if (!getintvalue (hparam1, 3, &n))
1175 return (false);
1176
1177 setintvalue (resourcefork, &val); /* defaults to 1 */
1178
1179 if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, "\x04""fork", &val))
1180 return (false);
1181
1182 forktype = val.data.intvalue;
1183
1184 if (!getnthresourcehandle (&fs, type, n, &id, bs, nil, forktype)) {
1185
1186 (*v).data.flvalue = false;
1187
1188 return (true);
1189 }
1190
1191 if (!langsetlongvarparam (hparam1, 4, id))
1192 return (false);
1193
1194 if (!getvarparam (hparam1, 5, &ht1, bs1)) /*returned name holder*/
1195 return (false);
1196
1197 pushhashtable (ht1);
1198
1199 fl = langsetstringval (bs1, bs);
1200
1201 pophashtable ();
1202
1203 if (!fl)
1204 return (false);
1205
1206 (*v).data.flvalue = true;
1207
1208 return (true);
1209 } /*getnthresinfoverb*/
1210
1211
1212 static boolean resourceexistsverb (hdltreenode hparam1, boolean flnamed, tyvaluerecord *v) {
1213
1214 /*
1215 2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
1216 */
1217
1218 tyfilespec fs;
1219 OSType type;
1220 short id, forktype;
1221 short ctconsumed = 3;
1222 short ctpositional = 3;
1223 bigstring bs;
1224 tyvaluerecord val;
1225
1226 if (!getpathvalue (hparam1, 1, &fs))
1227 return (false);
1228
1229 if (!getostypevalue (hparam1, 2, &type))
1230 return (false);
1231
1232 if (!getstringorintvalue (hparam1, 3, flnamed, &id, bs))
1233 return (false);
1234
1235 flnextparamislast = true;
1236
1237 setintvalue (resourcefork, &val); /* defaults to 1 */
1238
1239 if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, "\x04""fork", &val))
1240 return (false);
1241
1242 forktype = val.data.intvalue;
1243
1244 (*v).data.flvalue = loadresourcehandle (&fs, type, id, bs, nil, forktype);
1245
1246 return (true);
1247 } /*resourceexistsverb*/
1248
1249
1250 static boolean getresourceattrsverb (hdltreenode hparam1, boolean flnamed, tyvaluerecord *v) {
1251
1252 /*
1253 2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
1254
1255 2.1b4 dmb: new verb
1256 */
1257
1258 tyfilespec fs;
1259 OSType type;
1260 short id, attrs, forktype;
1261 short ctconsumed = 3;
1262 short ctpositional = 3;
1263 bigstring bs;
1264 tyvaluerecord val;
1265
1266 if (!getpathvalue (hparam1, 1, &fs))
1267 return (false);
1268
1269 if (!getostypevalue (hparam1, 2, &type))
1270 return (false);
1271
1272 if (!getstringorintvalue (hparam1, 3, flnamed, &id, bs))
1273 return (false);
1274
1275 flnextparamislast = true;
1276
1277 setintvalue (resourcefork, &val); /* defaults to 1 */
1278
1279 if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, "\x04""fork", &val))
1280 return (false);
1281
1282 forktype = val.data.intvalue;
1283
1284 if (!getresourceattributes (&fs, type, id, bs, &attrs, forktype))
1285 return (false);
1286
1287 return (setintvalue (attrs, v));
1288 } /*getresourceattrsverb*/
1289
1290
1291 static boolean setresourceattrsverb (hdltreenode hparam1, boolean flnamed, tyvaluerecord *v) {
1292
1293 /*
1294 2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
1295
1296 2.1b4 dmb: new verb
1297 */
1298
1299 tyfilespec fs;
1300 OSType type;
1301 short id, attrs, forktype;
1302 short ctconsumed = 4;
1303 short ctpositional = 4;
1304 bigstring bs;
1305 tyvaluerecord val;
1306
1307 if (!getpathvalue (hparam1, 1, &fs))
1308 return (false);
1309
1310 if (!getostypevalue (hparam1, 2, &type))
1311 return (false);
1312
1313 if (!getstringorintvalue (hparam1, 3, flnamed, &id, bs))
1314 return (false);
1315
1316 if (!getintvalue (hparam1, 4, &attrs))
1317 return (false);
1318
1319 flnextparamislast = true;
1320
1321 setintvalue (resourcefork, &val); /* defaults to 1 */
1322
1323 if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, "\x04""fork", &val))
1324 return (false);
1325
1326 forktype = val.data.intvalue;
1327
1328 if (!setresourceattributes (&fs, type, id, bs, attrs, forktype))
1329 return (false);
1330
1331 (*v).data.flvalue = true;
1332
1333 return (true);
1334 } /*setresourceattrsverb*/
1335
1336
1337 static boolean deleteresourceverb (hdltreenode hparam1, boolean flnamed, tyvaluerecord *v) {
1338
1339 /*
1340 2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
1341 */
1342
1343 tyfilespec fs;
1344 OSType type;
1345 short id, forktype;
1346 short ctconsumed = 3;
1347 short ctpositional = 3;
1348 bigstring bs;
1349 tyvaluerecord val;
1350
1351 if (!getpathvalue (hparam1, 1, &fs))
1352 return (false);
1353
1354 if (!getostypevalue (hparam1, 2, &type))
1355 return (false);
1356
1357 if (!getstringorintvalue (hparam1, 3, flnamed, &id, bs))
1358 return (false);
1359
1360 flnextparamislast = true;
1361
1362 setintvalue (resourcefork, &val); /* defaults to 1 */
1363
1364 if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, "\x04""fork", &val))
1365 return (false);
1366
1367 forktype = val.data.intvalue;
1368
1369 (*v).data.flvalue = deleteresource (&fs, type, id, bs, forktype);
1370
1371 return (true);
1372 } /*deleteresourceverb*/
1373
1374
1375 static boolean geticonposverb (hdltreenode hparam1, tyvaluerecord *v) {
1376
1377 /*
1378 9/30/91 dmb: use setintvarparam, saves code
1379 */
1380
1381 tyfilespec fs;
1382 Point pos;
1383 /*
1384 hdlhashtable htable;
1385 bigstring bs;
1386 */
1387
1388 if (!langcheckparamcount (hparam1, 3))
1389 return (false);
1390
1391 if (!getpathvalue (hparam1, 1, &fs))
1392 return (false);
1393
1394 if (!getfilepos (&fs, &pos))
1395 return (false);
1396
1397 if (!setintvarparam (hparam1, 2, pos.h))
1398 return (false);
1399
1400 if (!setintvarparam (hparam1, 3, pos.v))
1401 return (false);
1402
1403 /*
1404 if (!getvarparam (hparam1, 2, &htable, bs))
1405 return (false);
1406
1407 pushhashtable (htable);
1408
1409 hashassignint (bs, pos.h);
1410
1411 pophashtable ();
1412
1413 if (!getvarparam (hparam1, 3, &htable, bs))
1414 return (false);
1415
1416 pushhashtable (htable);
1417
1418 hashassignint (bs, pos.v);
1419
1420 pophashtable ();
1421 */
1422
1423 (*v).data.flvalue = true;
1424
1425 return (true);
1426 } /*geticonposverb*/
1427
1428
1429 static boolean seticonposverb (hdltreenode hparam1, tyvaluerecord *v) {
1430
1431 tyfilespec fs;
1432 Point pos;
1433
1434 if (!getpathvalue (hparam1, 1, &fs))
1435 return (false);
1436
1437 if (!getintvalue (hparam1, 2, &pos.h))
1438 return (false);
1439
1440 flnextparamislast = true;
1441
1442 if (!getintvalue (hparam1, 3, &pos.v))
1443 return (false);
1444
1445 (*v).data.flvalue = setfilepos (&fs, pos);
1446
1447 return (true);
1448 } /*seticonposverb*/
1449
1450 #ifdef MACVERSION
1451 /*
1452 11/17/92 dmb: this definition of the version resourcemakes it easier to
1453 pick apart the BCD
1454 */
1455
1456 typedef struct lNumVersion {
1457 unsigned short majorRev1: 4; /*1st part of version number in BCD*/
1458 unsigned short majorRev2: 4; /* 2nd nibble of 1st part*/
1459 unsigned short minorRev : 4; /*2nd part is 1 nibble in BCD*/
1460 unsigned short bugFixRev : 4; /*3rd part is 1 nibble in BCD*/
1461 unsigned short stage : 8; /*stage code: dev, alpha, beta, final*/
1462 unsigned short nonRelRev1 : 4; /*revision level of non-released version*/
1463 unsigned short nonRelRev2: 4; /* 2nd nibble of revision level*/
1464 } lNumVersion;
1465
1466 typedef struct lVersRec {
1467 lNumVersion numericVersion; /*encoded version number*/
1468 short countryCode; /*country code from intl utilities*/
1469 Str255 shortVersion; /*version number string - worst case*/
1470 Str255 reserved; /*longMessage string packed after shortVersion*/
1471 } lVersRec, *lVersRecPtr, **lVersRecHndl;
1472
1473
1474 static byte bsstages [] = "\pdab"; /*dev, alpha, beta*/
1475
1476
1477 #define emptyversionsize ((long) sizeof (lNumVersion) + sizeof (short) + 2)
1478
1479
1480 static boolean versionnumtostring (lNumVersion numvers, bigstring bs) {
1481
1482 /*
1483 return the packed version number as a string, e.g. "1.0b2". need
1484 definitions above, which is mis-defined in the Think C headers
1485 */
1486
1487 /*
1488 lNumVersion numvers;
1489
1490 numvers = *(lNumVersion *) &versionnum;
1491 */
1492
1493 setemptystring (bs);
1494
1495 if (numvers.majorRev1 != 0)
1496 shorttostring (numvers.majorRev1, bs);
1497
1498 pushint (numvers.majorRev2, bs);
1499
1500 pushchar ('.', bs);
1501
1502 pushint (numvers.minorRev, bs);
1503
1504 if (numvers.bugFixRev > 0) {
1505
1506 pushchar ('.', bs);
1507
1508 pushint (numvers.bugFixRev, bs);
1509 }
1510
1511 if (numvers.stage < finalStage) {
1512
1513 pushchar (bsstages [numvers.stage / developStage], bs);
1514
1515 if (numvers.nonRelRev1 > 0)
1516 pushint (numvers.nonRelRev1, bs);
1517
1518 pushint (numvers.nonRelRev2, bs);
1519 }
1520
1521 return (true);
1522 } /*versionnumtostring*/
1523
1524
1525 typedef byte shortstring [16];
1526
1527 static short stringtobcd (bigstring bs) {
1528
1529 register short i;
1530 register short n = 0;
1531
1532 for (i = 1; i <= stringlength (bs); ++i)
1533 n = (n << 4) + (bs [i] - '');
1534
1535 return (n);
1536 } /*stringtobcd*/
1537
1538
1539 static boolean stringtoversionnum (bigstring bs, NumVersion *versionnum) {
1540
1541 /*
1542 convert the string to a packed version number. see above.
1543 */
1544
1545 NumVersion numvers;
1546 register short i;
1547 register byte ch;
1548 shortstring bsnumber [4]; /*the three rev numbers, as strings*/
1549 short number [4]; /*the rev numbers*/
1550 short ixnumber = 0;
1551
1552 numvers.stage = finalStage;
1553
1554 for (i = 0; i < 4; ++i)
1555 setemptystring (bsnumber [i]);
1556
1557 for (i = 1; i <= stringlength (bs); ++i) {
1558
1559 ch = bs [i];
1560
1561 if (isnumeric (ch)) { /*digit: add to current number string*/
1562
1563 pushchar (ch, bsnumber [ixnumber]);
1564
1565 continue;
1566 }
1567
1568 if (ixnumber == 3) /*we're full: take what we've got so far*/
1569 goto exit;
1570
1571 if (ch == '.') { /*decimal point: move on to next number*/
1572
1573 ++ixnumber;
1574
1575 continue;
1576 }
1577
1578 ixnumber = 3; /*only valid data would be stage character & number*/
1579
1580 switch (lowercasechar (ch)) {
1581
1582 case 'a':
1583 numvers.stage = alphaStage;
1584
1585 break;
1586
1587 case 'b':
1588 numvers.stage = betaStage;
1589
1590 break;
1591
1592 case 'd':
1593 numvers.stage = developStage;
1594
1595 break;
1596
1597 default:
1598 goto exit;
1599 }
1600 }
1601
1602 exit:
1603
1604 for (i = 0; i < 4; ++i)
1605 number [i] = stringtobcd (bsnumber [i]);
1606
1607 numvers.majorRev = number [0];
1608
1609 numvers.minorAndBugRev = (number [1] << 4) + number [2];
1610
1611 numvers.nonRelRev = number [3];
1612
1613 *versionnum = numvers;
1614
1615 return (true);
1616 } /*stringtoversionnum*/
1617
1618
1619 boolean filegetprogramversion (bigstring bsversion) {
1620
1621 /*
1622 12/19/91 dmb: this routine is here because this is the only file that currently
1623 knows the format of a 'vers' resource. it would more logically be in file.c
1624 */
1625
1626 lNumVersion versionnumber;
1627
1628 if (filereadresource (filegetapplicationrnum (), 'vers', 1, nil, sizeof (versionnumber), &versionnumber))
1629 return (versionnumtostring (versionnumber, bsversion));
1630
1631 setemptystring (bsversion);
1632
1633 return (false);
1634 } /*filegetprogramversion*/
1635
1636
1637 static boolean getshortversionverb (hdltreenode hparam1, tyvaluerecord *v) {
1638
1639 /*
1640 file.getversion (path): string; return the version number as a string, e.g. "1.0b2".
1641
1642 2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
1643 */
1644
1645 tyfilespec fs;
1646 lNumVersion versionnumber;
1647 bigstring bs;
1648 short forktype;
1649 short ctconsumed = 1;
1650 short ctpositional = 1;
1651 tyvaluerecord val;
1652
1653 if (!getpathvalue (hparam1, 1, &fs))
1654 return (false);
1655
1656 flnextparamislast = true;
1657
1658 setintvalue (resourcefork, &val); /* defaults to 1 */
1659
1660 if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, "\x04""fork", &val))
1661 return (false);
1662
1663 forktype = val.data.intvalue;
1664
1665 if (loadresource (&fs, -1, 'vers', 1, nil, sizeof (versionnumber), &versionnumber, forktype))
1666 versionnumtostring (versionnumber, bs);
1667 else
1668 setemptystring (bs);
1669
1670 return (setstringvalue (bs, v));
1671 } /*getshortversionverb*/
1672
1673
1674 static boolean mungeversionstring (VersRecHndl hvers, bigstring bsversion, boolean fllongvers) {
1675
1676 register byte *p;
1677 long ixvers;
1678 long ctvers;
1679
1680 p = (**hvers).shortVersion;
1681
1682 if (fllongvers)
1683 p += stringlength (p) + 1; /*skip to next contiguous string -- the long version*/
1684
1685 ixvers = p - (byte *) *hvers;
1686
1687 ctvers = stringsize (p);
1688
1689 return (mungehandle ((Handle) hvers, ixvers, ctvers, bsversion, stringsize (bsversion)));
1690 } /*mungeversionstring*/
1691
1692
1693 static boolean setshortversionverb (hdltreenode hparam1, tyvaluerecord *v) {
1694
1695 /*
1696 file.setversion (path): boolean; set the short version string. if a valid version number is specified, set the numeric fields as well
1697
1698 2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
1699 */
1700
1701 tyfilespec fs;
1702 bigstring bsversion;
1703 NumVersion versionnumber;
1704 VersRecHndl hvers;
1705 short forktype;
1706 short ctconsumed = 2;
1707 short ctpositional = 2;
1708 tyvaluerecord val;
1709
1710 if (!getpathvalue (hparam1, 1, &fs))
1711 return (false);
1712
1713 if (!getstringvalue (hparam1, 2, bsversion))
1714 return (false);
1715
1716 flnextparamislast = true;
1717
1718 setintvalue (resourcefork, &val); /* defaults to 1 */
1719
1720 if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, "\x04""fork", &val))
1721 return (false);
1722
1723 forktype = val.data.intvalue;
1724
1725 if (!loadresourcehandle (&fs, 'vers', 1, nil, (Handle *) &hvers, forktype))
1726 if (!newclearhandle (emptyversionsize, (Handle *) &hvers))
1727 return (false);
1728
1729 if (stringtoversionnum (bsversion, &versionnumber)) /*convert to BCD if possible*/
1730 (**hvers).numericVersion = versionnumber;
1731
1732 if (mungeversionstring (hvers, bsversion, false))
1733 if (saveresourcehandle (&fs, 'vers', 1, nil, (Handle) hvers, forktype))
1734 (*v).data.flvalue = true;
1735
1736 disposehandle ((Handle) hvers);
1737
1738 return (true);
1739 } /*setshortversionverb*/
1740
1741
1742 static boolean getlongversionverb (hdltreenode hparam1, tyvaluerecord *v) {
1743
1744 /*
1745 file.getfullversion (path): string; return the long version string "1.0b2 © Copyright 1991 UserLand Software.". need definitions above,
1746 which don't appear in the Think C headers anywhere
1747
1748 2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
1749 */
1750
1751 tyfilespec fs;
1752 lVersRecHndl hvers;
1753 bigstring bs;
1754 short forktype;
1755 short ctconsumed = 1;
1756 short ctpositional = 1;
1757 tyvaluerecord val;
1758
1759 if (!getpathvalue (hparam1, 1, &fs))
1760 return (false);
1761
1762 flnextparamislast = true;
1763
1764 setintvalue (resourcefork, &val); /* defaults to 1 */
1765
1766 if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, "\x04""fork", &val))
1767 return (false);
1768
1769 forktype = val.data.intvalue;
1770
1771 setemptystring (bs);
1772
1773 if (loadresourcehandle (&fs, 'vers', 1, nil, (Handle *) &hvers, forktype)) {
1774
1775 register byte *p;
1776
1777 p = (**hvers).shortVersion;
1778
1779 p += stringlength (p) + 1; /*skip to next contiguous string -- the long version*/
1780
1781 copystring (p, bs);
1782
1783 disposehandle ((Handle) hvers);
1784 }
1785
1786 return (setstringvalue (bs, v));
1787 } /*getlongversionverb*/
1788
1789
1790 static boolean setlongversionverb (hdltreenode hparam1, tyvaluerecord *v) {
1791
1792 /*
1793 file.setversion (path): boolean; set the long version string.
1794
1795 2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
1796 */
1797
1798 tyfilespec fs;
1799 bigstring bsversion;
1800 VersRecHndl hvers;
1801 short forktype;
1802 short ctconsumed = 2;
1803 short ctpositional = 2;
1804 tyvaluerecord val;
1805
1806 if (!getpathvalue (hparam1, 1, &fs))
1807 return (false);
1808
1809 if (!getstringvalue (hparam1, 2, bsversion))
1810 return (false);
1811
1812 flnextparamislast = true;
1813
1814 setintvalue (resourcefork, &val); /* defaults to 1 */
1815
1816 if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, "\x04""fork", &val))
1817 return (false);
1818
1819 forktype = val.data.intvalue;
1820
1821 if (!loadresourcehandle (&fs, 'vers', 1, nil, (Handle *) &hvers, forktype))
1822 if (!newclearhandle (emptyversionsize, (Handle *) &hvers))
1823 return (false);
1824
1825 if (mungeversionstring (hvers, bsversion, true))
1826 if (saveresourcehandle (&fs, 'vers', 1, nil, (Handle) hvers, forktype))
1827 (*v).data.flvalue = true;
1828
1829 disposehandle ((Handle) hvers);
1830
1831 return (true);
1832 } /*setlongversionverb*/
1833
1834
1835 static boolean getcommentverb (hdltreenode hparam1, tyvaluerecord *v) {
1836
1837 tyfilespec fs;
1838 bigstring bscomment;
1839
1840 flnextparamislast = true;
1841
1842 if (!getpathvalue (hparam1, 1, &fs))
1843 return (false);
1844
1845 if (!getfilecomment (&fs, bscomment))
1846 setemptystring (bscomment);
1847
1848 return (setstringvalue (bscomment, v));
1849 } /*getcommentverb*/
1850
1851
1852 static boolean setcommentverb (hdltreenode hparam1, tyvaluerecord *v) {
1853
1854 tyfilespec fs;
1855 bigstring bscomment;
1856
1857 if (!getpathvalue (hparam1, 1, &fs))
1858 return (false);
1859
1860 flnextparamislast = true;
1861
1862 if (!getstringvalue (hparam1, 2, bscomment))
1863 return (false);
1864
1865 return (setbooleanvalue (setfilecomment (&fs, bscomment), v));
1866 } /*setcommentverb*/
1867
1868
1869 static boolean getlabelverb (hdltreenode hparam1, tyvaluerecord *v) {
1870
1871 tyfilespec fs;
1872 bigstring bslabel;
1873
1874 flnextparamislast = true;
1875
1876 if (!getpathvalue (hparam1, 1, &fs))
1877 return (false);
1878
1879 if (!getfilelabel (&fs, bslabel))
1880 setemptystring (bslabel);
1881
1882 return (setstringvalue (bslabel, v));
1883 } /*getlabelverb*/
1884
1885
1886 static boolean setlabelverb (hdltreenode hparam1, tyvaluerecord *v) {
1887
1888 tyfilespec fs;
1889 bigstring bslabel;
1890
1891 if (!getpathvalue (hparam1, 1, &fs))
1892 return (false);
1893
1894 flnextparamislast = true;
1895
1896 if (!getstringvalue (hparam1, 2, bslabel))
1897 return (false);
1898
1899 return (setbooleanvalue (setfilelabel (&fs, bslabel), v));
1900 } /*setlabelverb*/
1901
1902 #endif
1903
1904
1905 static boolean findapplicationverb (hdltreenode hparam1, tyvaluerecord *v) {
1906
1907 OSType creator;
1908 tyfilespec fsapp;
1909
1910 flnextparamislast = true;
1911
1912 if (!getostypevalue (hparam1, 1, &creator))
1913 return (false);
1914
1915 if (!findapplication (creator, &fsapp))
1916 clearbytes (&fsapp, sizeof (fsapp));
1917
1918 return (setfilespecvalue (&fsapp, v));
1919 } /*findapplicationverb*/
1920
1921
1922 #ifdef WIN95VERSION
1923
1924 boolean filegetprogramversion (bigstring bsversion) {
1925
1926 return (getstringlist (defaultlistnumber, programversion, bsversion));
1927 } /*filegetprogramversion*/
1928
1929
1930 static boolean getshortversionverb (hdltreenode hparam1, tyvaluerecord *v) {
1931
1932 /*
1933 file.getversion (path): string; return the version number as
1934 a string, e.g. "1.0b2".
1935 */
1936
1937 tyfilespec fs;
1938 DWORD dummyhandle;
1939 bigstring bs;
1940 DWORD buflen;
1941 char * buf;
1942 VS_FIXEDFILEINFO * ffi;
1943 char * info;
1944 boolean flffi;
1945
1946 flnextparamislast = true;
1947
1948 if (!getpathvalue (hparam1, 1, &fs))
1949 return (false);
1950
1951 nullterminate (fsname(&fs));
1952
1953 setemptystring (bs);
1954
1955 buflen = GetFileVersionInfoSize (stringbaseaddress(fsname(&fs)), &dummyhandle);
1956
1957 if (buflen > 0) {
1958 buf = (char *) LocalAlloc (LPTR, buflen);
1959
1960 if (buf != NULL) {
1961 if (GetFileVersionInfo (stringbaseaddress(fsname(&fs)), dummyhandle, buflen, buf)) {
1962 buflen = sizeof(VS_FIXEDFILEINFO);
1963
1964 flffi = VerQueryValue (buf, "\\", &ffi, &buflen);
1965
1966 if (flffi)
1967 flffi = buflen > 0;
1968
1969 buflen = 0;
1970
1971 VerQueryValue (buf, "\\StringFileInfo\\040904E4\\FileVersion", &info, &buflen);
1972
1973 if (buflen == 0) {
1974 VerQueryValue (buf, "\\StringFileInfo\\040904B0\\FileVersion", &info, &buflen);
1975 }
1976
1977 if (buflen != 0)
1978 copyctopstring (info, bs);
1979 else if (flffi) {
1980 wsprintf (stringbaseaddress (bs), "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
1981 LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
1982 setstringlength (bs, strlen(stringbaseaddress(bs)));
1983 }
1984 }
1985
1986 LocalFree (buf);
1987 }
1988 }
1989
1990 return (setstringvalue (bs, v));
1991 } /*getshortversionverb*/
1992
1993
1994 static boolean getlongversionverb (hdltreenode hparam1, tyvaluerecord *v) {
1995
1996 /*
1997 file.getfullversion (path): string; return the long version string
1998 "1.0b2 © Copyright 1991 UserLand Software.". need definitions above,
1999 which don't appear in the Think C headers anywhere
2000 */
2001
2002 tyfilespec fs;
2003 DWORD dummyhandle;
2004 bigstring bs, bs2;
2005 DWORD buflen;
2006 char * buf;
2007 VS_FIXEDFILEINFO * ffi;
2008 char * info;
2009
2010 flnextparamislast = true;
2011
2012 if (!getpathvalue (hparam1, 1, &fs))
2013 return (false);
2014
2015 nullterminate (fsname(&fs));
2016
2017 setemptystring (bs);
2018 setemptystring (bs2);
2019
2020 buflen = GetFileVersionInfoSize (stringbaseaddress(fsname(&fs)), &dummyhandle);
2021
2022 if (buflen > 0) {
2023 buf = (char *) LocalAlloc (LPTR, buflen);
2024
2025 if (buf != NULL) {
2026 if (GetFileVersionInfo (stringbaseaddress(fsname(&fs)), dummyhandle, buflen, buf)) {
2027 buflen = sizeof(VS_FIXEDFILEINFO);
2028 VerQueryValue (buf, "\\", &ffi, &buflen);
2029
2030 VerQueryValue (buf, "\\StringFileInfo\\040904E4\\FileVersion", &info, &buflen);
2031
2032 if (buflen == 0) {
2033 VerQueryValue (buf, "\\StringFileInfo\\040904B0\\FileVersion", &info, &buflen);
2034 }
2035
2036 if (buflen != 0)
2037 copyctopstring (info, bs);
2038
2039 VerQueryValue (buf, "\\StringFileInfo\\040904E4\\LegalCopyright", &info, &buflen);
2040
2041 if (buflen == 0) {
2042 VerQueryValue (buf, "\\StringFileInfo\\040904B0\\LegalCopyright", &info, &buflen);
2043 }
2044
2045 if (buflen != 0)
2046 copyctopstring (info, bs2);
2047
2048 if (stringlength(bs) > 0)
2049 pushspace (bs);
2050
2051 pushstring (bs2, bs);
2052 }
2053
2054 LocalFree (buf);
2055 }
2056 }
2057
2058 return (setstringvalue (bs, v));
2059 } /*getlongversionverb*/
2060
2061 static boolean getcommentverb (hdltreenode hparam1, tyvaluerecord *v) {
2062
2063 /*
2064 file.getversion (path): string; return the version number as
2065 a string, e.g. "1.0b2".
2066 */
2067
2068 tyfilespec fs;
2069 DWORD dummyhandle;
2070 bigstring bs;
2071 DWORD buflen;
2072 char * buf;
2073 VS_FIXEDFILEINFO * ffi;
2074 char * info;
2075
2076 flnextparamislast = true;
2077
2078 if (!getpathvalue (hparam1, 1, &fs))
2079 return (false);
2080
2081 nullterminate (fsname(&fs));
2082
2083 setemptystring (bs);
2084
2085 buflen = GetFileVersionInfoSize (stringbaseaddress(fsname(&fs)), &dummyhandle);
2086
2087 if (buflen > 0) {
2088 buf = (char *) LocalAlloc (LPTR, buflen);
2089
2090 if (buf != NULL) {
2091 if (GetFileVersionInfo (stringbaseaddress(fsname(&fs)), dummyhandle, buflen, buf)) {
2092 buflen = sizeof(VS_FIXEDFILEINFO);
2093 VerQueryValue (buf, "\\", &ffi, &buflen);
2094
2095 VerQueryValue (buf, "\\StringFileInfo\\040904E4\\FileDescription", &info, &buflen);
2096
2097 if (buflen == 0) {
2098 VerQueryValue (buf, "\\StringFileInfo\\040904B0\\FileDescription", &info, &buflen);
2099 }
2100
2101 if (buflen != 0)
2102 copyctopstring (info, bs);
2103 }
2104
2105 LocalFree (buf);
2106 }
2107 }
2108
2109 return (setstringvalue (bs, v));
2110 } /*getcommentverb*/
2111
2112 #endif
2113
2114 /*start of new verbs added by DW, 7/27/91*/
2115
2116 static boolean findfileverb (hdltreenode hparam1, tyvaluerecord *v) {
2117
2118 /*
2119 8/25/92 dmb: set return value to true or false, so glue isn't needed
2120 */
2121
2122 tyfilespec fs;
2123 bigstring pattern;
2124 long index;
2125
2126 if (!getpathvalue (hparam1, 1, &fs))
2127 return (false);
2128
2129 flnextparamislast = true;
2130
2131 if (!getstringvalue (hparam1, 2, pattern))
2132 return (false);
2133
2134 fiffindinfile (&fs, pattern, &index);
2135
2136 /*
2137 setlongvalue (index, v);
2138 */
2139
2140 setbooleanvalue ((boolean) (index >= 0), v);
2141
2142 return (true);
2143 } /*findfileverb*/
2144
2145
2146 static boolean countlinesverb (hdltreenode hparam1, tyvaluerecord *v) {
2147
2148 tyfilespec fs;
2149 long ctlines;
2150
2151 flnextparamislast = true;
2152
2153 if (!getpathvalue (hparam1, 1, &fs))
2154 return (false);
2155
2156 fifcharcounter (&fs, chreturn, &ctlines);
2157
2158 setlongvalue (ctlines, v);
2159
2160 return (true);
2161 } /*countlinesverb*/
2162
2163
2164 static boolean openfileverb (hdltreenode hparam1, tyvaluerecord *v) {
2165
2166 /*
2167 5.0.1 dmb: removed incorrect case for W95
2168 */
2169
2170 tyfilespec fs;
2171
2172 flnextparamislast = true;
2173
2174 if (!getpathvalue (hparam1, 1, &fs))
2175 return (false);
2176
2177 (*v).data.flvalue = fifopenfile (&fs, (long) currentprocess);
2178
2179 return (true);
2180 } /*openfileverb*/
2181
2182
2183 static boolean closefileverb (hdltreenode hparam1, tyvaluerecord *v) {
2184
2185 tyfilespec fs;
2186
2187 flnextparamislast = true;
2188
2189 if (!getpathvalue (hparam1, 1, &fs))
2190 return (false);
2191
2192 (*v).data.flvalue = fifclosefile (&fs);
2193
2194 return (true);
2195 } /*closefileverb*/
2196
2197
2198 static boolean endoffileverb (hdltreenode hparam1, tyvaluerecord *v) {
2199
2200 tyfilespec fs;
2201
2202 flnextparamislast = true;
2203
2204 if (!getpathvalue (hparam1, 1, &fs))
2205 return (false);
2206
2207 (*v).data.flvalue = fifendoffile (&fs);
2208
2209 return (true);
2210 } /*endoffileverb*/
2211
2212
2213 static boolean setendoffileverb (hdltreenode hparam1, tyvaluerecord *v) {
2214
2215 tyfilespec fs;
2216 long eof;
2217
2218 if (!getpathvalue (hparam1, 1, &fs))
2219 return (false);
2220
2221 flnextparamislast = true;
2222
2223 if (!getlongvalue (hparam1, 2, &eof))
2224 return (false);
2225
2226 (*v).data.flvalue = fifsetendoffile (&fs, eof);
2227
2228 return (true);
2229 } /*endoffileverb*/
2230
2231
2232 static boolean getendoffileverb (hdltreenode hparam1, tyvaluerecord *v) {
2233
2234 tyfilespec fs;
2235 long eof;
2236
2237 flnextparamislast = true;
2238
2239 if (!getpathvalue (hparam1, 1, &fs))
2240 return (false);
2241
2242 if (!fifgetendoffile (&fs, &eof))
2243 return (false);
2244
2245 return (setlongvalue (eof, v));
2246 } /*endoffileverb*/
2247
2248
2249 static boolean setpositionverb (hdltreenode hparam1, tyvaluerecord *v) {
2250
2251 tyfilespec fs;
2252 long pos;
2253
2254 if (!getpathvalue (hparam1, 1, &fs))
2255 return (false);
2256
2257 flnextparamislast = true;
2258
2259 if (!getlongvalue (hparam1, 2, &pos))
2260 return (false);
2261
2262 (*v).data.flvalue = fifsetposition (&fs, pos);
2263
2264 return (true);
2265 } /*positionverb*/
2266
2267
2268 static boolean getpositionverb (hdltreenode hparam1, tyvaluerecord *v) {
2269
2270 tyfilespec fs;
2271 long pos;
2272
2273 flnextparamislast = true;
2274
2275 if (!getpathvalue (hparam1, 1, &fs))
2276 return (false);
2277
2278 if (!fifgetposition (&fs, &pos))
2279 return (false);
2280
2281 return (setlongvalue (pos, v));
2282 } /*positionverb*/
2283
2284
2285 static boolean readlineverb (hdltreenode hparam1, tyvaluerecord *v) {
2286
2287 tyfilespec fs;
2288 Handle linestring;
2289
2290 flnextparamislast = true;
2291
2292 if (!getpathvalue (hparam1, 1, &fs))
2293 return (false);
2294
2295 fifreadline (&fs, &linestring);
2296
2297 return (setheapvalue (linestring, stringvaluetype, v));
2298 } /*readlineverb*/
2299
2300
2301 static boolean writelineverb (hdltreenode hparam1, tyvaluerecord *v) {
2302
2303 tyfilespec fs;
2304 Handle linestring;
2305
2306 if (!getpathvalue (hparam1, 1, &fs))
2307 return (false);
2308
2309 flnextparamislast = true;
2310
2311 if (!gettextvalue (hparam1, 2, &linestring))
2312 return (false);
2313
2314 (*v).data.flvalue = fifwriteline (&fs, linestring);
2315
2316 return (true);
2317 } /*writelineverb*/
2318
2319
2320 static boolean readverb (hdltreenode hparam1, tyvaluerecord *v) {
2321
2322 tyfilespec fs;
2323 Handle x;
2324 long ctbytes;
2325
2326 if (!getpathvalue (hparam1, 1, &fs))
2327 return (false);
2328
2329 flnextparamislast = true;
2330
2331 if (!getlongvalue (hparam1, 2, &ctbytes))
2332 return (false);
2333
2334 if (!fifreadhandle (&fs, ctbytes, &x))
2335 return (true);
2336
2337 if ((ctbytes < longinfinity) && (ctbytes != gethandlesize (x))) { /*ran out of data*/
2338
2339 disposehandle (x);
2340
2341 return (true);
2342 }
2343
2344 return (setbinaryvalue (x, '\?\?\?\?', v));
2345 } /*readverb*/
2346
2347
2348 static boolean writeverb (hdltreenode hparam1, tyvaluerecord *v) {
2349
2350 /*
2351 5.0.2b17 dmb: use new getreadonlytextvalue
2352 */
2353
2354 tyfilespec fs;
2355 //tyvaluerecord val;
2356 Handle hdata;
2357
2358 if (!getpathvalue (hparam1, 1, &fs))
2359 return (false);
2360
2361 flnextparamislast = true;
2362
2363 /*
2364 if (!getbinaryparam (hparam1, 2, &val))
2365 return (false);
2366
2367 if (!coercetostring (&val))
2368 return (false);
2369
2370 (*v).data.flvalue = fifwritehandle (&fs, (Handle) val.data.stringvalue);
2371 */
2372 if (!getreadonlytextvalue (hparam1, 2, &hdata))
2373 return (false);
2374
2375 (*v).data.flvalue = fifwritehandle (&fs, hdata);
2376
2377 return (true);
2378 } /*writeverb*/
2379
2380
2381 #if 0
2382
2383 static boolean writewholefileverb (hdltreenode hparam1, tyvaluerecord *v) {
2384
2385 /*
2386 on writeWholeFile (f, s, type = nil, creator = nil, creationdate = clock.now ()) {
2387 Ç10/31/97 at 1:41:20 PM by DW -- moved from toys.writeWholeFile
2388 ÇFriday, July 18, 1997 at 10:22:07 AM by PBS
2389 ÇConditionalized for multiple platforms, with optional parameters.
2390 file.new (f);
2391 file.open (f);
2392 if sys.os () == "MacOS" {
2393 if type != nil {
2394 file.setType (f, type)};
2395 if creator != nil {
2396 file.setCreator (f, creator)};
2397 file.setCreated (f, creationdate)};
2398 file.write (f, s);
2399 file.close (f);
2400 return (true)}
2401 */
2402
2403 tyfilespec fs;
2404 tyvaluerecord val;
2405
2406 if (!getpathvalue (hparam1, 1, &fs))
2407 return (false);
2408
2409 flnextparamislast = true;
2410
2411 if (!getbinaryparam (hparam1, 2, &val))
2412 return (false);
2413
2414 if (!coercetostring (&val)) //strip binary type
2415 return (false);
2416
2417 (*v).data.flvalue = fifwritehandle (&fs, (Handle) val.data.stringvalue);
2418
2419 return (true);
2420 } /*writewholefileverb*/
2421
2422 #endif
2423
2424
2425 static boolean comparefilesverb (hdltreenode hparam1, tyvaluerecord *v) {
2426
2427 tyfilespec fs1, fs2;
2428
2429 if (!getpathvalue (hparam1, 1, &fs1))
2430 return (false);
2431
2432 flnextparamislast = true;
2433
2434 if (!getpathvalue (hparam1, 2, &fs2))
2435 return (false);
2436
2437 (*v).data.flvalue = fifcomparefiles (&fs1, &fs2);
2438
2439 return (true);
2440 } /*comparefilesverb*/
2441
2442
2443 /*end of new verbs added by DW, 7/27/91*/
2444
2445 #ifdef MACVERSION
2446 static boolean newaliasverb (hdltreenode hparam1, tyvaluerecord *vreturned) {
2447
2448 /*
2449 6/2/92 dmb: make sure that destination path doesn't end in a colon;
2450 otherwise pathtofilespec will fail
2451 */
2452
2453 tyfilespec fs, fsalias;
2454
2455 if (!langcanusealiases ())
2456 return (false);
2457
2458 if (!getpathvalue (hparam1, 1, &fs)) /*bs holds the source file's path*/
2459 return (false);
2460
2461 flnextparamislast = true;
2462
2463 if (!getpathvalue (hparam1, 2, &fsalias)) /*bsalias holds the new alias's path*/
2464 return (false);
2465
2466 if (!surefile (&fs)) /*make sure source file exists*/
2467 return (false);
2468
2469 setoserrorparam ((ptrstring) fsalias.name); /*assume error will relate to new file*/
2470
2471 setbooleanvalue (MakeAliasFile (&fs, &fsalias), vreturned);
2472
2473 return (true);
2474 } /*newaliasverb*/
2475
2476
2477 static boolean followaliasverb (hdltreenode hparam1, tyvaluerecord *vreturned) {
2478
2479 /*
2480 1/29/92 dmb: a kernel version of what used to be implemented in glue.
2481 there a difference in the functionality as coded here: ResolveAliasFile
2482 is being asked to follow chains of aliases; it will follow an alias to an alias
2483 to the original. to match the original version & documentation, if the original
2484 file is not an alias, the empty string is returned.
2485 also, we need to Gestalt aliases...
2486 */
2487
2488 bigstring bs;
2489 FSSpec fs;
2490 boolean flfolder;
2491 Boolean flaliasfolder, flwasalias;
2492 OSErr errcode;
2493
2494 if (!langcanusealiases ())
2495 return (false);
2496
2497 flnextparamislast = true;
2498
2499 if (!getpathvalue (hparam1, 1, &fs)) /*bs holds the file path*/
2500 return (false);
2501
2502 if (!fileexists (&fs, &flfolder)) { /*make sure original*/
2503
2504 setoserrorparam (bs);
2505
2506 oserror (errorFileNotFound); /*file not found*/
2507
2508 return (false);
2509 }
2510
2511 errcode = ResolveAliasFile (&fs, true, &flaliasfolder, &flwasalias);
2512
2513 switch (errcode) {
2514
2515 case errorNone:
2516 if (flwasalias)
2517 return (setfilespecvalue (&fs, vreturned));
2518 else
2519 setemptystring (bs);
2520
2521 break;
2522
2523 case errorFileNotFound:
2524 setemptystring (bs);
2525
2526 break;
2527
2528 case userCanceledErr:
2529 return (false);
2530
2531 default:
2532 oserror (errcode);
2533
2534 return (false);
2535 }
2536
2537 return (setstringvalue (bs, vreturned));
2538 } /*followaliasverb*/
2539 #endif
2540
2541
2542 #ifdef MACVERSION
2543 boolean filelaunchanythingverb (hdltreenode hparam1, tyvaluerecord *vreturned) {
2544
2545 /*
2546 6/1/92 dmb: generate oserror if System7Open fails
2547 */
2548
2549 tyfilespec fs;
2550
2551 #ifdef flsystem6
2552
2553 if (!langcanuseappleevents ())
2554 return (false);
2555
2556 #endif
2557
2558 flnextparamislast = true;
2559
2560 if (!getpathvalue (hparam1, 1, &fs)) /*bs holds the file's path*/
2561 return (false);
2562
2563 setoserrorparam (fs.name);
2564
2565 if (oserror (System7Open (fs)))
2566 return (false);
2567
2568 return (setbooleanvalue (true, vreturned));
2569 } /*filelaunchanythingverb*/
2570 #endif
2571
2572 static boolean filefunctionvalue (short token, hdltreenode hparam1, tyvaluerecord *vreturned, bigstring bserror) {
2573
2574 /*
2575 bridges file.c with the language. the name of the verb is bs, its first parameter
2576 is hparam1, and we return a value in vreturned.
2577
2578 we use a limited number of support routines from lang.c to get parameters and
2579 to return values.
2580
2581 return false only if the error is serious enough to halt the running of the script
2582 that called us, otherwise error values are returned through the valuerecord, which
2583 is available to the script.
2584
2585 if we return false, we try to provide a descriptive error message in the
2586 returned string bserror.
2587
2588 10/15/91: file.setpath, file.folderfrompath now handle partial paths corectly
2589
2590 2/13/92 dmb: re-hooked up hasbundle verb
2591
2592 6/2/92 dmb: made filefrompath work as documented so that glue isn't needed
2593
2594 6/9/92 dmb: added file.isvisible, file.setvisible
2595
2596 8/25/92 dmb: made newfunc delete existing file, so glue isn't necessary
2597
2598 9/26/92 dmb: use one bigstring instead of two for filefrompath and folderfrompath.
2599 also, dont allow getfullfilepath to generate an error in folderfrompath
2600
2601 9/30/92 dmb: call new langcheckstackspace; most file functions chew up a good bit
2602
2603 2.1b2 dmb: use filespecs everywhere. added volumeblocksize verb
2604
2605 2.1b12 dmb: if mountservervolumefunc's volumepath is improperly formed, generate
2606 informative message instead of failing silently
2607
2608 5.0.2b16 dmb: added getpathcharfunc
2609 */
2610
2611 register hdltreenode hp1 = hparam1;
2612 register tyvaluerecord *v = vreturned;
2613
2614 setbooleanvalue (false, v); /*by default, file functions return false*/
2615
2616 if (!langcheckstackspace ())
2617 return (false);
2618
2619 switch (token) {
2620
2621 case filecreatedfunc: {
2622
2623 unsigned long datecreated, datetoss;
2624 boolean fl;
2625 tyfilespec fs;
2626
2627 flnextparamislast = true;
2628
2629 if (!getpathvalue (hp1, 1, &fs)) /*fs holds the file path*/
2630 break;
2631
2632 if (fileisvolume (&fs))
2633 fl = volumecreated (&fs, &datecreated);
2634 else
2635 fl = getfiledates (&fs, &datecreated, &datetoss);
2636
2637 if (!fl)
2638 break;
2639
2640 return (setdatevalue (datecreated, v));
2641 }
2642
2643 case filemodifiedfunc: {
2644
2645 unsigned long datemodified, datetoss;
2646 tyfilespec fs;
2647
2648 flnextparamislast = true;
2649
2650 if (!getpathvalue (hp1, 1, &fs))
2651 break;
2652
2653 if (!getfiledates (&fs, &datetoss, &datemodified))
2654 break;
2655
2656 return (setdatevalue (datemodified, v));
2657 }
2658
2659 case filetypefunc: {
2660
2661 OSType type;
2662 tyfilespec fs;
2663
2664 flnextparamislast = true;
2665
2666 if (!getpathvalue (hp1, 1, &fs))
2667 break;
2668
2669 if (!getfiletype (&fs, &type))
2670 break;
2671
2672 return (setostypevalue (type, v));
2673 }
2674
2675 case filecreatorfunc: {
2676
2677 OSType creator;
2678 tyfilespec fs;
2679
2680 flnextparamislast = true;
2681
2682 if (!getpathvalue (hp1, 1, &fs))
2683 break;
2684
2685 if (!getfilecreator (&fs, &creator))
2686 break;
2687
2688 return (setostypevalue (creator, v));
2689 }
2690
2691 case setfilecreatedfunc: {
2692 tyfilespec fs;
2693 unsigned long when;
2694
2695 if (!getpathvalue (hp1, 1, &fs))
2696 break;
2697
2698 flnextparamislast = true;
2699
2700 if (!getdatevalue (hp1, 2, &when))
2701 break;
2702
2703 if (!setfilecreated (&fs, when))
2704 break;
2705
2706 (*v).data.flvalue = true;
2707
2708 return (true);
2709 }
2710
2711 case setfilemodifiedfunc: {
2712 tyfilespec fs;
2713 unsigned long when;
2714
2715 if (!getpathvalue (hp1, 1, &fs))
2716 break;
2717
2718 flnextparamislast = true;
2719
2720 if (!getdatevalue (hp1, 2, &when))
2721 break;
2722
2723 if (!setfilemodified (&fs, when))
2724 break;
2725
2726 (*v).data.flvalue = true;
2727
2728 return (true);
2729 }
2730
2731 case fileisfolderfunc: {
2732 tyfilespec fs;
2733
2734 flnextparamislast = true;
2735
2736 if (!getpathvalue (hp1, 1, &fs))
2737 break;
2738
2739 if (!fileisfolder (&fs, &(*v).data.flvalue))
2740 break;
2741
2742 return (true);
2743 }
2744
2745 case fileisvolumefunc: {
2746 tyfilespec fs;
2747
2748 flnextparamislast = true;
2749
2750 if (!getpathvalue (hp1, 1, &fs)) /*was getvolumevalue*/
2751 break;
2752
2753 (*v).data.flvalue = fileisvolume (&fs);
2754
2755 return (true);
2756 }
2757
2758 case fileislockedfunc: {
2759 boolean fl;
2760 tyfilespec fs;
2761
2762 flnextparamislast = true;
2763
2764 if (!getpathvalue (hp1, 1, &fs))
2765 break;
2766
2767 if (fileisvolume (&fs))
2768 fl = isvolumelocked (&fs, &(*v).data.flvalue);
2769 else
2770 fl = fileislocked (&fs, &(*v).data.flvalue);
2771
2772 if (!fl)
2773 break;
2774
2775 return (true);
2776 }
2777
2778 case fileisbusyfunc: {
2779 tyfilespec fs;
2780
2781 flnextparamislast = true;
2782
2783 if (!getpathvalue (hp1, 1, &fs))
2784 break;
2785
2786 if (!fileisbusy (&fs, &(*v).data.flvalue))
2787 break;
2788
2789 return (true);
2790 }
2791
2792 case filehasbundlefunc: {
2793 tyfilespec fs;
2794
2795 flnextparamislast = true;
2796
2797 if (!getpathvalue (hp1, 1, &fs))
2798 break;
2799
2800 if (!filehasbundle (&fs, &(*v).data.flvalue))
2801 break;
2802
2803 return (true);
2804 }
2805
2806 case filesetbundlefunc: {
2807 tyfilespec fs;
2808 boolean flbundle;
2809 boolean flfolder;
2810
2811 if (!getpathvalue (hp1, 1, &fs))
2812 break;
2813
2814 flnextparamislast = true;
2815
2816 if (!getbooleanvalue (hp1, 2, &flbundle))
2817 break;
2818
2819 if (!fileisfolder (&fs, &flfolder))
2820 break;
2821
2822 if (!flfolder) {
2823
2824 if (!filesetbundle (&fs, flbundle))
2825 break;
2826
2827 (*v).data.flvalue = true;
2828 }
2829
2830 return (true);
2831 }
2832
2833 case fileisaliasfunc: {
2834 tyfilespec fs;
2835
2836 flnextparamislast = true;
2837
2838 if (!getpathvalue (hp1, 1, &fs))
2839 break;
2840
2841 if (!fileisalias (&fs, &(*v).data.flvalue))
2842 break;
2843
2844 return (true);
2845 }
2846
2847 case fileisvisiblefunc: {
2848 tyfilespec fs;
2849
2850 flnextparamislast = true;
2851
2852 if (!getpathvalue (hp1, 1, &fs))
2853 break;
2854
2855 if (!fileisvisible (&fs, &(*v).data.flvalue))
2856 break;
2857
2858 return (true);
2859 }
2860
2861 case filesetvisiblefunc: {
2862 tyfilespec fs;
2863 boolean flvisible;
2864
2865 if (!getpathvalue (hp1, 1, &fs))
2866 break;
2867
2868 flnextparamislast = true;
2869
2870 if (!getbooleanvalue (hp1, 2, &flvisible))
2871 break;
2872
2873 if (!filesetvisible (&fs, flvisible))
2874 break;
2875
2876 (*v).data.flvalue = true;
2877
2878 return (true);
2879 }
2880
2881 case filesizefunc: {
2882 tyfilespec fs;
2883 long size;
2884
2885 flnextparamislast = true;
2886
2887 if (!getpathvalue (hp1, 1, &fs))
2888 break;
2889
2890 if (!filesize (&fs, &size))
2891 break;
2892
2893 return (setlongvalue (size, v));
2894 }
2895
2896 case filelockfunc: {
2897 tyfilespec fs;
2898 boolean fl;
2899
2900 flnextparamislast = true;
2901
2902 if (!getpathvalue (hp1, 1, &fs))
2903 break;
2904
2905 if (fileisvolume (&fs))
2906 fl = lockvolume (&fs, true);
2907 else
2908 fl = lockfile (&fs);
2909
2910 if (!fl)
2911 break;
2912
2913 (*v).data.flvalue = true;
2914
2915 return (true);
2916 }
2917
2918 case fileunlockfunc: {
2919 tyfilespec fs;
2920 boolean fl;
2921
2922 flnextparamislast = true;
2923
2924 if (!getpathvalue (hp1, 1, &fs))
2925 break;
2926
2927 if (fileisvolume (&fs))
2928 fl = lockvolume (&fs, false);
2929 else
2930 fl = unlockfile (&fs);
2931
2932 if (!fl)
2933 break;
2934
2935 (*v).data.flvalue = true;
2936
2937 return (true);
2938 }
2939
2940 case filefullpathfunc: {
2941 tyfilespec fs;
2942
2943 flnextparamislast = true;
2944
2945 if (!getpathvalue (hp1, 1, &fs))
2946 break;
2947
2948 /*getfullfilepath*/
2949
2950 return (setfilespecvalue (&fs, v));
2951 }
2952
2953 case filecopyfunc:
2954 return (copyfileverb (true, true, hp1, v));
2955
2956 case filecopydataforkfunc:
2957 return (copyfileverb (true, false, hp1, v));
2958
2959 case filecopyresourceforkfunc:
2960 return (copyfileverb (false, true, hp1, v));
2961
2962 case filedeletefunc: {
2963 tyfilespec fs;
2964
2965 flnextparamislast = true;
2966
2967 if (!getpathvalue (hp1, 1, &fs))
2968 break;
2969
2970 if (!deletefile (&fs))
2971 break;
2972
2973 (*v).data.flvalue = true;
2974
2975 return (true);
2976 }
2977
2978 case fileexistsfunc: {
2979 boolean fl;
2980 tyfilespec fs;
2981 boolean flfolder;
2982
2983 if (!langcheckparamcount (hp1, 1))
2984 break;
2985
2986 disablelangerror ();
2987
2988 fl = getpathvalue (hp1, 1, &fs);
2989
2990 enablelangerror ();
2991
2992 (*v).data.flvalue = fl && fileexists (&fs, &flfolder);
2993
2994 return (true);
2995 }
2996
2997 case filefrompathfunc:
2998 return (filefrompathverb (hp1, v));
2999
3000 case filegetpathfunc: {
3001 tyfilespec fs;
3002
3003 if (!langcheckparamcount (hp1, 0)) /*no parameters expected*/
3004 break;
3005
3006 if (!filegetdefaultpath (&fs))
3007 break;
3008
3009 return (setfilespecvalue (&fs, v));
3010 }
3011
3012 case filesetpathfunc: {
3013 tyfilespec fs;
3014
3015 flnextparamislast = true;
3016
3017 if (!getpathvalue (hp1, 1, &fs))
3018 break;
3019
3020 if (!filesetdefaultpath (&fs))
3021 break;
3022
3023 (*v).data.flvalue = true;
3024
3025 return (true);
3026 }
3027
3028 case newfunc: {
3029 tyfilespec fs;
3030 boolean flfolder;
3031
3032 flnextparamislast = true;
3033
3034 if (!getpathvalue (hp1, 1, &fs))
3035 break;
3036
3037 if (fileexists (&fs, &flfolder)) { /*8/25/92 dmb*/
3038
3039 if (!deletefile (&fs))
3040 break;
3041 }
3042
3043 if (!newfile (&fs, '\?\?\?\?', '\?\?\?\?'))
3044 break;
3045
3046 (*v).data.flvalue = true;
3047
3048 return (true);
3049 }
3050
3051 case newfolderfunc: {
3052 tyfilespec fs;
3053
3054 flnextparamislast = true;
3055
3056 if (!getpathvalue (hp1, 1, &fs))
3057 break;
3058
3059 if (!newfolder (&fs))
3060 break;
3061
3062 (*v).data.flvalue = true;
3063
3064 return (true);
3065 }
3066
3067 case filerenamefunc: {
3068 tyfilespec fs;
3069 bigstring bs;
3070
3071 if (!getpathvalue (hp1, 1, &fs)) /*bs1 holds the path*/
3072 break;
3073
3074 flnextparamislast = true;
3075
3076 if (!getstringvalue (hp1, 2, bs)) /*bs2 holds the new name*/
3077 break;
3078
3079 /*
3080 if (fileisvolume (bs1))
3081 (*v).data.flvalue = renamevolume (bs1, bs2);
3082 else
3083 */
3084
3085 if (!renamefile (&fs, bs))
3086 break;
3087
3088 (*v).data.flvalue = true;
3089
3090 return (true);
3091 }
3092
3093 case filemovefunc: {
3094 tyfilespec fs1, fs2;
3095
3096 if (!getpathvalue (hp1, 1, &fs1)) /*bs1 holds the path*/
3097 break;
3098
3099 flnextparamislast = true;
3100
3101 if (!getpathvalue (hp1, 2, &fs2)) /*bs2 holds the new name*/
3102 break;
3103
3104 if (!movefile (&fs1, &fs2))
3105 break;
3106
3107 (*v).data.flvalue = true;
3108
3109 return (true);
3110 }
3111
3112 /*
3113 case filesinfolder: {
3114 tyfilespec fs;
3115 long ctfiles;
3116
3117 flnextparamislast = true;
3118
3119 if (!getpathvalue (hp1, 1, &fs))
3120 break;
3121
3122 if (!filesinfolder (&fs, &ctfiles))
3123 break;
3124
3125 return (setlongvalue (ctfiles, v));
3126 }
3127 */
3128
3129 case sfgetfilefunc:
3130 return (filedialogverb (sfgetfileverb, hp1, v));
3131
3132 case sfputfilefunc:
3133 return (filedialogverb (sfputfileverb, hp1, v));
3134
3135 case sfgetfolderfunc:
3136 return (filedialogverb (sfgetfolderverb, hp1, v));
3137
3138 case sfgetdiskfunc:
3139 return (filedialogverb (sfgetdiskverb, hp1, v));
3140
3141 /*
3142 case fileeditlinefeedsfunc:
3143 return (editlinefeedsverb (hp1, v));
3144 */
3145
3146 case volumeisejectablefunc: {
3147 tyfilespec fs;
3148
3149 flnextparamislast = true;
3150
3151 if (!getvolumevalue (hp1, 1, &fs))
3152 break;
3153
3154 return (isejectable (&fs, &(*v).data.flvalue));
3155 }
3156
3157
3158 case volumefreespacefunc: {
3159 tyfilespec fs;
3160 long ctbytes;
3161
3162 flnextparamislast = true;
3163
3164 if (!getvolumevalue (hp1, 1, &fs))
3165 break;
3166
3167 if (!getfreespace (&fs, &ctbytes))
3168 break;
3169
3170 return (setlongvalue (ctbytes, v));
3171 }
3172
3173
3174 case volumesizefunc: {
3175 tyfilespec fs;
3176 long ctbytes;
3177
3178 flnextparamislast = true;
3179
3180 if (!getvolumevalue (hp1, 1, &fs))
3181 break;
3182
3183 if (!getvolumesize (&fs, &ctbytes))
3184 break;
3185
3186 return (setlongvalue (ctbytes, v));
3187 }
3188
3189
3190 case volumefreespacedoublefunc: { /*6.1b16 AR*/
3191 tyfilespec fs;
3192 double totalbytes, freebytes;
3193
3194 flnextparamislast = true;
3195
3196 if (!getvolumevalue (hp1, 1, &fs))
3197 break;
3198
3199 if (!langgetextendedvolumeinfo (&fs, &totalbytes, &freebytes))
3200 break;
3201
3202 return (setdoublevalue (freebytes, v));
3203 }
3204
3205
3206 case volumesizedoublefunc: { /*6.1b16 AR*/
3207 tyfilespec fs;
3208 double totalbytes, freebytes;
3209
3210 flnextparamislast = true;
3211
3212 if (!getvolumevalue (hp1, 1, &fs))
3213 break;
3214
3215 if (!langgetextendedvolumeinfo (&fs, &totalbytes, &freebytes))
3216 break;
3217
3218 return (setdoublevalue (totalbytes, v));
3219 }
3220
3221
3222 case volumeblocksizefunc: {
3223 tyfilespec fs;
3224 long ctbytes;
3225
3226 flnextparamislast = true;
3227
3228 if (!getvolumevalue (hp1, 1, &fs))
3229 break;
3230
3231 if (!getvolumeblocksize (&fs, &ctbytes))
3232 break;
3233
3234 return (setlongvalue (ctbytes, v));
3235 }
3236
3237 case filesonvolumefunc: {
3238 tyfilespec fs;
3239 long ctfiles;
3240
3241 flnextparamislast = true;
3242
3243 if (!getvolumevalue (hp1, 1, &fs))
3244 break;
3245
3246 if (!filesonvolume (&fs, &ctfiles))
3247 break;
3248
3249 return (setlongvalue (ctfiles, v));
3250 }
3251
3252 case foldersonvolumefunc: {
3253 tyfilespec fs;
3254 long ctfolders;
3255
3256 flnextparamislast = true;
3257
3258 if (!getvolumevalue (hp1, 1, &fs))
3259 break;
3260
3261 if (!foldersonvolume (&fs, &ctfolders))
3262 break;
3263
3264 return (setlongvalue (ctfolders, v));
3265 }
3266
3267
3268 /* 11/7/91 dmb: now called from shellsysverbs.c
3269 case filelaunchfunc:
3270 return (filelaunchanythingverb (hp1, v));
3271 */
3272
3273 /*start of new verbs added by DW, 7/27/91*/
3274
3275 case findinfilefunc:
3276 return (findfileverb (hp1, v));
3277
3278 case countlinesfunc:
3279 return (countlinesverb (hp1, v));
3280
3281 case openfilefunc:
3282 return (openfileverb (hp1, v));
3283
3284 case closefilefunc:
3285 return (closefileverb (hp1, v));
3286
3287 case endoffilefunc:
3288 return (endoffileverb (hp1, v));
3289
3290 case setendoffilefunc:
3291 return (setendoffileverb (hp1, v));
3292
3293 case getendoffilefunc:
3294 return (getendoffileverb (hp1, v));
3295
3296 case setpositionfunc:
3297 return (setpositionverb (hp1, v));
3298
3299 case getpositionfunc:
3300 return (getpositionverb (hp1, v));
3301
3302 case readlinefunc:
3303 return (readlineverb (hp1, v));
3304
3305 case writelinefunc:
3306 return (writelineverb (hp1, v));
3307
3308 case readfunc:
3309 return (readverb (hp1, v));
3310
3311 case writefunc:
3312 return (writeverb (hp1, v));
3313
3314 case comparefunc:
3315 return (comparefilesverb (hp1, v));
3316
3317 /*end of new verbs added by DW, 7/27/91*/
3318
3319 //case writewholefilefunc:
3320 // return (writewholefileverb (hp1, v));
3321
3322 case getpathcharfunc:
3323 if (!langcheckparamcount (hp1, 0))
3324 return (false);
3325
3326 #ifdef MACVERSION
3327 return (setstringvalue ("\x01" ":", v));
3328 #endif
3329 #ifdef WIN95VERSION
3330 return (setstringvalue ("\x01" "\\", v));
3331 #endif
3332
3333 case getshortversionfunc:
3334 return (getshortversionverb (hp1, v));
3335
3336 case getlongversionfunc:
3337 return (getlongversionverb (hp1, v));
3338
3339 case filegetcommentfunc:
3340 return (getcommentverb (hp1, v));
3341
3342 case filefindappfunc:
3343 return (findapplicationverb (hp1, v));
3344
3345 /* 3/20/97 - The following are MAC speciifc verbs and are therefore grouped
3346 together here for ease of ifdefing */
3347
3348 #ifdef MACVERSION
3349 case newaliasfunc:
3350 return (newaliasverb (hp1, v));
3351
3352 case filefollowaliasfunc:
3353 return (followaliasverb (hp1, v));
3354
3355 case filegeticonposfunc:
3356 return (geticonposverb (hp1, v));
3357
3358 case fileseticonposfunc:
3359 return (seticonposverb (hp1, v));
3360
3361 case setshortversionfunc:
3362 return (setshortversionverb (hp1, v));
3363
3364 case setlongversionfunc:
3365 return (setlongversionverb (hp1, v));
3366
3367 case filesetcommentfunc:
3368 return (setcommentverb (hp1, v));
3369
3370 case filegetlabelfunc:
3371 return (getlabelverb (hp1, v));
3372
3373 case filesetlabelfunc:
3374 return (setlabelverb (hp1, v));
3375
3376 case unmountvolumefunc: {
3377 tyfilespec fs;
3378
3379 flnextparamislast = true;
3380
3381 if (!getvolumevalue (hp1, 1, &fs))
3382 break;
3383
3384 if (!unmountvolume (&fs))
3385 break;
3386
3387 return (setbooleanvalue (true, v));
3388 }
3389
3390 #if TARGET_API_MAC_CARBON != 1 /*7.0B59 PBS: not implemented in OS X yet*/
3391
3392 case mountservervolumefunc: {
3393 bigstring bsvol, bsuser, bspassword;
3394
3395 if (!getstringvalue (hp1, 1, bsvol))
3396 break;
3397
3398 if (!getstringvalue (hp1, 2, bsuser))
3399 break;
3400
3401 flnextparamislast = true;
3402
3403 if (!getstringvalue (hp1, 3, bspassword))
3404 break;
3405
3406 if (countwords (bsvol, chpathseparator) != 3) {
3407
3408 langparamerror (badnetworkvolumespecificationerror, bsvol);
3409
3410 return (false);
3411 }
3412
3413 if (!mountvolume (bsvol, bsuser, bspassword))
3414 break;
3415
3416 return (setbooleanvalue (true, v));
3417 }
3418 #endif
3419
3420 case volumeejectfunc: {
3421 tyfilespec fs;
3422
3423 flnextparamislast = true;
3424
3425 if (!getvolumevalue (hp1, 1, &fs))
3426 break;
3427
3428 (*v).data.flvalue = ejectvol (&fs);
3429
3430 return (true);
3431 }
3432
3433 case setfiletypefunc: {
3434 tyfilespec fs;
3435 OSType type;
3436
3437 if (!getpathvalue (hp1, 1, &fs))
3438 break;
3439
3440 flnextparamislast = true;
3441
3442 if (!getostypevalue (hp1, 2, &type))
3443 break;
3444
3445 if (!setfiletype (&fs, type))
3446 break;
3447
3448 (*v).data.flvalue = true;
3449
3450 return (true);
3451 }
3452
3453 case setfilecreatorfunc: {
3454 tyfilespec fs;
3455 OSType creator;
3456
3457 if (!getpathvalue (hp1, 1, &fs))
3458 break;
3459
3460 flnextparamislast = true;
3461
3462 if (!getostypevalue (hp1, 2, &creator))
3463 break;
3464
3465 if (!setfilecreator (&fs, creator))
3466 break;
3467
3468 (*v).data.flvalue = true;
3469
3470 return (true);
3471 }
3472
3473 #endif
3474
3475 case folderfrompathfunc:
3476 return (folderfrompathverb (hp1, v));
3477
3478
3479 case getsystempathfunc: {
3480 byte bsvol [258]; /*2*/
3481 byte bsfolder [258]; /*6*/
3482 tyfilespec fs;
3483
3484 if (!langcheckparamcount (hp1, 0)) /*no parameters expected*/
3485 break;
3486
3487 #ifdef flsystem6
3488 filegetpath (filegetsystemvnum (), bs);
3489 return (setstringvalue (bs, v));
3490 #else
3491
3492 setemptystring (bsvol);
3493
3494 #ifdef MACVERSION
3495
3496 #if TARGET_API_MAC_CARBON == 1
3497 ostypetostring ('pref', bsfolder);
3498 #else
3499 ostypetostring ('macs', bsfolder);
3500 #endif
3501
3502 #endif
3503
3504 #ifdef WIN95VERSION
3505 copyctopstring ("SYSTEM", bsfolder);
3506 #endif
3507
3508 if (!getspecialfolderpath (bsvol, bsfolder, false, &fs))
3509 break;
3510
3511 return (setfilespecvalue (&fs, v));
3512
3513 #endif
3514
3515 }
3516
3517 case getspecialpathfunc: {
3518 bigstring bsvol, bsfolder;
3519 tyfilespec fs;
3520 boolean flcreate;
3521
3522 if (!getstringvalue (hp1, 1, bsvol))
3523 break;
3524
3525 if (!getstringvalue (hp1, 2, bsfolder))
3526 break;
3527
3528 flnextparamislast = true;
3529
3530 if (!getbooleanvalue (hp1, 3, &flcreate))
3531 break;
3532
3533 if (!getspecialfolderpath (bsvol, bsfolder, flcreate, &fs))
3534 break;
3535
3536 return (setfilespecvalue (&fs, v));
3537 }
3538
3539 case getmp3infofunc: {
3540
3541 long seconds, bitrate, frequency, offset;
3542 tyfilespec fs;
3543 boolean fl, flvariablebitrate;
3544
3545 if (!langcheckparamcount (hparam1, 6)) /*preflight before changing values*/
3546 return (false);
3547
3548 if (!getpathvalue (hp1, 1, &fs))
3549 return (false);
3550
3551 if (!fifopenfile (&fs, (long) currentprocess))
3552 return (false);
3553
3554 fl = getmp3info (&fs, &seconds, &bitrate, &frequency, &offset, &flvariablebitrate);
3555
3556 if (!fifclosefile (&fs))
3557 return (false);
3558
3559 if (!fl)
3560 return (false);
3561
3562 if (!langsetlongvarparam (hp1, 2, seconds))
3563 return (false);
3564
3565 if (!langsetlongvarparam (hp1, 3, bitrate))
3566 return (false);
3567
3568 if (!langsetlongvarparam (hp1, 4, frequency))
3569 return (false);
3570
3571 if (!langsetlongvarparam (hp1, 5, offset))
3572 return (false);
3573
3574 if (!langsetbooleanvarparam (hp1, 6, flvariablebitrate))
3575 return (false);
3576
3577 return (true);
3578 }
3579
3580 #ifdef WIN95VERSION
3581 case newaliasfunc:
3582 case filefollowaliasfunc:
3583 case filegeticonposfunc:
3584 case fileseticonposfunc:
3585 case setshortversionfunc:
3586 case setlongversionfunc:
3587 case filesetcommentfunc:
3588 case filegetlabelfunc:
3589 case filesetlabelfunc:
3590 case unmountvolumefunc:
3591 case mountservervolumefunc:
3592 case volumeejectfunc:
3593 case setfiletypefunc:
3594 case setfilecreatorfunc:
3595 #endif
3596 default:
3597 getstringlist (langerrorlist, unimplementedverberror, bserror);
3598
3599 break;
3600 } /*switch*/
3601
3602 return (false);
3603 } /*filefunctionvalue*/
3604
3605
3606 static boolean rezfunctionvalue (short token, hdltreenode hparam1, tyvaluerecord *vreturned, bigstring bserror) {
3607
3608 register hdltreenode hp1 = hparam1;
3609 register tyvaluerecord *v = vreturned;
3610
3611 setbooleanvalue (false, v); /*by default, rez functions return false*/
3612
3613 switch (token) {
3614 #ifdef MACVERSION
3615 case rezgetresourcefunc:
3616 return (getresourceverb (hp1, false, v));
3617
3618 case rezputresourcefunc:
3619 return (putresourceverb (hp1, false, v));
3620
3621 case rezgetnamedresourcefunc:
3622 return (getresourceverb (hp1, true, v));
3623
3624 case rezputnamedresourcefunc:
3625 return (putresourceverb (hp1, true, v));
3626
3627 case rezcountrestypesfunc:
3628 return (countrestypesverb (hp1, v));
3629
3630 case rezgetnthrestypefunc:
3631 return (getnthrestypeverb (hp1, v));
3632
3633 case rezcountresourcesfunc:
3634 return (countresourcesverb (hp1, v));
3635
3636 case rezgetnthresourcefunc:
3637 return (getnthresourceverb (hp1, v));
3638
3639 case rezgetnthresinfofunc:
3640 return (getnthresinfoverb (hp1, v));
3641
3642 case rezresourceexistsfunc:
3643 return (resourceexistsverb (hp1, false, v));
3644
3645 case reznamedresourceexistsfunc:
3646 return (resourceexistsverb (hp1, true, v));
3647
3648 case rezdeleteresourcefunc:
3649 return (deleteresourceverb (hp1, false, v));
3650
3651 case rezdeletenamedresourcefunc:
3652 return (deleteresourceverb (hp1, true, v));
3653
3654 case rezgetresourceattrsfunc:
3655 return (getresourceattrsverb (hp1, false, v));
3656
3657 case rezsetresourceattrsfunc:
3658 return (setresourceattrsverb (hp1, false, v));
3659 #endif
3660 default:
3661 getstringlist (langerrorlist, unimplementedverberror, bserror);
3662
3663 break;
3664 } /*switch*/
3665
3666 return (false);
3667 } /*rezfunctionvalue*/
3668
3669
3670 boolean fileinitverbs (void) {
3671
3672 /*
3673 if you just changed or added some definitions in fileinitbuiltins, call
3674 fileinstallbuiltins here. rebuild, run the program, come back and change
3675 it to fileloadbuiltins, rebuild and go on...
3676
3677 12/18/90 dmb: no longer save hash tables in program file, so we just
3678 initialize the builtins directly.
3679
3680 10/2/91 dmb: broke out resource verb into rez table
3681
3682 2.1b5 dmb: use new loadfunctionprocessor verb
3683 */
3684
3685 if (!loadfunctionprocessor (idfileverbs, &filefunctionvalue))
3686 return (false);
3687
3688 if (!loadfunctionprocessor (idrezverbs, &rezfunctionvalue))
3689 return (false);
3690
3691 return (true);
3692 } /*fileinitverbs*/
3693
3694
3695
3696 boolean filestart (void) {
3697
3698 /*
3699 6.1b15 AR: Initialize flsupportslargevolumes.
3700
3701 Windows 95 OSR2: The GetDiskFreeSpaceEx function is available on Windows 95 systems
3702 beginning with OEM Service Release 2 (OSR2).
3703
3704 To determine whether GetDiskFreeSpaceEx is available, call the LoadLibrary
3705 or LoadLibraryEx function to load the KERNEL32.DLL file, then call the
3706 GetProcAddress function to obtain an address for GetDiskFreeSpaceEx.
3707 If GetProcAddress fails, or if GetDiskFreeSpaceEx fails with the
3708 ERROR_CALL_NOT_IMPLEMENTED code, use the GetDiskFreeSpace function
3709 instead of GetDiskFreeSpaceEx
3710 */
3711
3712 #ifdef WIN95VERSION
3713
3714 HMODULE hmodule;
3715
3716 char kerneldllname[] = "kernel32.dll\0";
3717 char procname[] = "GetDiskFreeSpaceExA\0";
3718
3719 hmodule = GetModuleHandle (kerneldllname);
3720
3721 if (hmodule != nil) {
3722
3723 adrGetDiskFreeSpaceEx = (tyGetDiskFreeSpaceEx) GetProcAddress (hmodule, procname);
3724
3725 if (adrGetDiskFreeSpaceEx != NULL)
3726 flsupportslargevolumes = true;
3727 }
3728 #endif
3729
3730 return (true);
3731 }/*filestart*/
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.