fileverbs.c

Go to the documentation of this file.
00001 
00002 /*  $Id: fileverbs.c 1329 2006-04-24 21:40:07Z creecode $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028 #include "frontier.h"
00029 #include "standard.h"
00030 
00031 #include "error.h"
00032 #include "memory.h"
00033 #include "strings.h"
00034 #include "ops.h"
00035 #include "resources.h"
00036 #include "lang.h"
00037 #include "langexternal.h"
00038 #include "langinternal.h"
00039 #include "langsystem7.h"
00040 #include "process.h"
00041 #include "kernelverbs.h"
00042 #include "file.h"
00043 #include "filesystem7.h"
00044 #include "filealias.h"
00045 #include "tablestructure.h"
00046 #include "kernelverbdefs.h"
00047 #include "shell.rsrc.h"
00048 #include "byteorder.h"      /* 2006-04-16 aradke: for SWAP_REZ_BYTE_ORDER */
00049 #include "oplist.h"         /* 2006-04-23 creedon */
00050 
00051 
00052 #ifdef MACVERSION
00053     #define chpathseparator ':'
00054 #endif
00055 
00056 #ifdef WIN95VERSION
00057     #define chpathseparator '\\'
00058 #endif
00059 
00060 boolean flsupportslargevolumes = false; /*true if volumes over 2 GB are supported by the OS*/
00061 
00062 
00063 #ifdef WIN95VERSION
00064 
00065 tyGetDiskFreeSpaceEx adrGetDiskFreeSpaceEx = NULL;
00066 
00067 #endif
00068 
00069 
00070 typedef enum tyfiletoken { /*verbs that are processed by file.c*/
00071     
00072     filecreatedfunc, 
00073     
00074     filemodifiedfunc, 
00075     
00076     filetypefunc, 
00077     
00078     filecreatorfunc,
00079     
00080     setfilecreatedfunc, 
00081     
00082     setfilemodifiedfunc, 
00083     
00084     setfiletypefunc,
00085     
00086     setfilecreatorfunc,
00087     
00088     fileisfolderfunc, 
00089     
00090     fileisvolumefunc,
00091     
00092     fileislockedfunc, 
00093     
00094     filelockfunc,
00095     
00096     fileunlockfunc,
00097     
00098     filecopyfunc, 
00099     
00100     filecopydataforkfunc,
00101     
00102     filecopyresourceforkfunc,
00103     
00104     filedeletefunc, 
00105     
00106     filerenamefunc,
00107     
00108     fileexistsfunc, 
00109     
00110     filesizefunc,
00111     
00112     filefullpathfunc,
00113 
00114     filegetpathfunc,
00115     
00116     filesetpathfunc,
00117     
00118     filefrompathfunc, 
00119     
00120     folderfrompathfunc, 
00121     
00122     /*
00123     getprogrampathfunc,
00124     */
00125     
00126     getsystempathfunc,
00127     
00128     getspecialpathfunc,
00129     
00130     newfunc,
00131     
00132     newfolderfunc, 
00133     
00134     newaliasfunc,
00135     
00136     sfgetfilefunc, 
00137     
00138     sfputfilefunc,
00139     
00140     sfgetfolderfunc,
00141     
00142     sfgetdiskfunc,
00143     
00144     filegeticonposfunc,
00145     
00146     fileseticonposfunc,
00147     
00148     getshortversionfunc,
00149     
00150     setshortversionfunc,
00151     
00152     getlongversionfunc,
00153     
00154     setlongversionfunc,
00155     
00156     filegetcommentfunc,
00157     
00158     filesetcommentfunc,
00159     
00160     filegetlabelfunc,
00161     
00162     filesetlabelfunc,
00163     
00164     filefindappfunc,
00165     
00166     /*
00167     fileeditlinefeedsfunc,
00168     */
00169     
00170     fileisbusyfunc,
00171     
00172     filehasbundlefunc,
00173     
00174     filesetbundlefunc,
00175     
00176     fileisaliasfunc,
00177     
00178     fileisvisiblefunc,
00179     
00180     filesetvisiblefunc,
00181     
00182     filefollowaliasfunc,
00183     
00184     filemovefunc,
00185     
00186     /*
00187     filesinfolderfunc,
00188     */
00189     
00190     volumeejectfunc,
00191     
00192     volumeisejectablefunc, 
00193     
00194     volumefreespacefunc,
00195     
00196     volumesizefunc,
00197     
00198     volumeblocksizefunc,
00199     
00200     filesonvolumefunc,
00201     
00202     foldersonvolumefunc,
00203     
00204     unmountvolumefunc,
00205     
00206     mountservervolumefunc,
00207     
00208     /*
00209     filelaunchfunc,
00210     */
00211     
00212     /*start of new verbs added by DW, 7/27/91*/
00213     
00214         findinfilefunc,
00215         
00216         countlinesfunc,
00217         
00218         openfilefunc,
00219         
00220         closefilefunc,
00221         
00222         endoffilefunc,
00223         
00224         setendoffilefunc,
00225         
00226         getendoffilefunc,
00227 
00228         setpositionfunc,
00229 
00230         getpositionfunc,
00231 
00232         readlinefunc,
00233         
00234         writelinefunc,
00235         
00236         readfunc,
00237         
00238         writefunc,
00239         
00240         comparefunc,
00241     
00242     /*end of new verbs added by DW, 7/27/91*/
00243     
00244     writewholefilefunc,
00245         
00246     getpathcharfunc,
00247 
00248     volumefreespacedoublefunc,
00249 
00250     volumesizedoublefunc,
00251     
00252     getmp3infofunc,
00253     
00254     readwholefilefunc,          /* 2006-04-11 aradke */
00255     
00256     getlabelindexfunc,          /* 2006-04-23 creedon */
00257     
00258     setlabelindexfunc,          /* 2006-04-23 creedon */
00259     
00260     getlabelnamesfunc,          /* 2006-04-23 creedon */
00261     
00262     ctfileverbs
00263     } tyfiletoken;
00264 
00265 
00266 typedef enum tyreztoken {
00267     
00268     rezgetresourcefunc,
00269     
00270     rezputresourcefunc,
00271     
00272     rezgetnamedresourcefunc,
00273     
00274     rezputnamedresourcefunc,
00275     
00276     rezcountrestypesfunc,
00277     
00278     rezgetnthrestypefunc,
00279     
00280     rezcountresourcesfunc,
00281     
00282     rezgetnthresourcefunc,
00283     
00284     rezgetnthresinfofunc,
00285     
00286     rezresourceexistsfunc,
00287     
00288     reznamedresourceexistsfunc,
00289     
00290     rezdeleteresourcefunc,
00291     
00292     rezdeletenamedresourcefunc,
00293     
00294     rezgetresourceattrsfunc,
00295     
00296     rezsetresourceattrsfunc,
00297     
00298     ctrezverbs
00299     } tyreztoken;
00300 
00301 
00302 
00303 #if 0
00304 
00305 static bigstring bsdefaultpath; /*see setpath*/
00306 
00307 
00308 static checkfordrivenum (bigstring bspath) {
00309     
00310     /*
00311     interpret single-digit vol name as driver number
00312     */
00313     
00314     if ((stringlength (bspath) > 1) && (bspath [2] == chpathseparator)) {
00315         
00316         byte ch = bspath [1];
00317         short drivenum;
00318         byte bsvol [64];
00319         
00320         if (isnumeric (ch)) {
00321             
00322             drivenum = ch - '0';
00323             
00324             if (drivenumtovolname (drivenum, bsvol))
00325                 replacestring (bspath, 1, 1, bsvol);
00326             }
00327         }
00328     } /*checkfordrivenum*/
00329 
00330 
00331 filecheckdefaultpath (bigstring bspath) {
00332     
00333     /*
00334     if bspath is a partial path, add our local current path, if set.
00335     
00336     12/5/91 dmb: sneak in support drive number as "n:" here
00337     
00338     12/27/91 dmb: if bsdefaultpath isn't empty, and we have a partial path, 
00339     make sure we don't double-up on colons if bspath starts with one.
00340     */
00341     
00342     short ix = 1;
00343     
00344     if (!isemptystring (bspath)) {
00345         
00346         if (!scanstring (chpathseparator, bspath, &ix) || (ix == 1)) { /*a partial path*/
00347             
00348             if (!isemptystring (bsdefaultpath)) {
00349                 
00350                 if (bspath [1] == chpathseparator) /*default path ends in one already*/
00351                     deletefirstchar (bspath);
00352                 
00353                 insertstring (bsdefaultpath, bspath);
00354                 }
00355             }
00356         
00357         /*
00358         else
00359             checkfordrivenum (bspath);
00360         */
00361         }
00362     } /*filecheckdefaultpath*/
00363 
00364 #endif
00365 
00366 static boolean getpathvalue (hdltreenode hparam1, short pnum, tyfilespec *fspath) {
00367     
00368     /*
00369     get a path parameter for the parameter list.
00370     
00371     2.1b2 dmb: now that we use filespecs everywhere, we don't have much to do!
00372     */
00373     
00374     return (getfilespecvalue (hparam1, pnum, fspath));
00375     
00376     /*
00377     tyvaluerecord v;
00378     bigstring bspath;
00379     
00380     if (!getparamvalue (hparam1, pnum, &v))
00381         return (false);
00382     
00383     switch (v.valuetype) {
00384         
00385         case stringvaluetype:
00386             
00387             pullstringvalue (&v, bspath);
00388             
00389             filecheckdefaultpath (bspath);
00390             
00391             if (!pathtofilespec (bspath, fspath)) {
00392                 
00393                 filenotfounderror (bspath);
00394                 
00395                 return (false);
00396                 }
00397             
00398             break;
00399         
00400         default:
00401             if (!coercetofilespec (&v))
00402                 return (false);
00403             
00404             *fspath = **(*v).data.filespecvalue;
00405             
00406             break;
00407     
00408         return (true);
00409         }
00410     */
00411     
00412     return (true);
00413     } /*getpathvalue*/
00414 
00415 
00416 static boolean getvolumevalue (hdltreenode hparam1, short pnum, tyfilespec *fsvol) {
00417     
00418     /*
00419     get a volume path parameter for the parameter list.
00420     
00421     make sure that a colon is included so a volume name isn't interpreted 
00422     as a partial path
00423     
00424     2.1b8 dmb: don't use pathtofilespec to convert the volume name, 
00425     because FSMakeFSSpec will prompt the user to insert the disk if 
00426     the volume has been ejected
00427     
00428     2.1b11 dmb: ooops, we were copying bsvol into fsvol.name, potentially 
00429     overflowing the str64. fileparsevolname now returns the vol name.  note  
00430     that if the caller needs to distinguish between volumes and non-volumes, 
00431     it can't call us.
00432     */
00433     
00434     bigstring bsvol;
00435     tyvaluerecord v;
00436     
00437     if (!getparamvalue (hparam1, pnum, &v))
00438         return (false);
00439     
00440     switch (v.valuetype) {
00441         
00442         case stringvaluetype:/*already a string, easy case*/
00443             
00444             pullstringvalue (&v, bsvol);
00445             
00446         #ifdef NEWFILESPECTYPE
00447             if (!fileparsevolname (bsvol, &(*fsvol).volumeID, (*fsvol).fullSpecifier)) {
00448         #else
00449             if (!fileparsevolname (bsvol, &(*fsvol).vRefNum, (*fsvol).name)) {
00450         #endif
00451                 
00452                 setoserrorparam (bsvol);
00453                 
00454                 oserror (errorVolume);
00455                 
00456                 return (false);
00457                 }
00458         #ifdef MACVERSION           
00459             (*fsvol).parID = fsRtParID;
00460         #endif          
00461 
00462             /* old code for string paths, pre-filespecs
00463             if (!stringfindchar (chpathseparator, bsvol))
00464                 pushchar (chpathseparator, bsvol);
00465             
00466             if (!pathtofilespec (bsvol, fsvol)) {
00467                 setoserrorparam (bsvol);
00468                 oserror (errorVolume);
00469                 return (false);
00470                 }
00471             */
00472             
00473             break;
00474         
00475         default:
00476             if (!coercetofilespec (&v))
00477                 return (false);
00478             
00479             *fsvol = **v.data.filespecvalue;
00480             
00481             break;
00482         
00483         return (true);
00484         }
00485     
00486     return (true);
00487     } /*getvolumevalue*/
00488 
00489 
00490 static boolean copyfileverb (boolean fldata, boolean flresources, hdltreenode hparam1, tyvaluerecord *v) {
00491     
00492     tyfilespec fs1, fs2;
00493     
00494     if (!getpathvalue (hparam1, 1, &fs1)) /*fs1 holds the source path*/
00495         return (false);
00496     
00497     flnextparamislast = true;
00498     
00499     if (!getpathvalue (hparam1, 2, &fs2)) /*fs2 holds the dest path*/
00500         return (false);
00501     
00502     if (equalfilespecs (&fs1, &fs2)) /*easy case making a copy of itself*/
00503         (*v).data.flvalue = true;
00504     else
00505         (*v).data.flvalue = copyfile (&fs1, &fs2, fldata, flresources);
00506     
00507     return (true);
00508     } /*copyfileverb*/
00509 
00510 
00511 static boolean filefrompathverb (hdltreenode hparam1, tyvaluerecord *vreturned) {
00512     
00513     /*
00514     2.1b2 dmb: do string manipulation if given a string, but otherwise 
00515     work with filespecs. less critical than with folderfrompath, but might 
00516     avoid full path string overflow
00517     
00518     2.1b3 dmb: be sure to add colon to name of folder even when filespec is 
00519     being used.
00520     */
00521     
00522     tyvaluerecord v;
00523     tyfilespec fs;
00524     bigstring bs;
00525     boolean flfolder;
00526     
00527     flnextparamislast = true;
00528     
00529     if (!getparamvalue (hparam1, 1, &v))
00530         return (false);
00531     
00532     switch (v.valuetype) {
00533     
00534         case stringvaluetype:
00535             pullstringvalue (&v, bs);
00536 
00537             flfolder = endswithpathsep(bs);
00538 
00539             if (flfolder)
00540                 setstringlength (bs, stringlength (bs) - 1);
00541             
00542             filefrompath (bs, bs); /*bs now holds the filename*/
00543             
00544             break;
00545         
00546         default:
00547             if (!coercetofilespec (&v))
00548                 return (false);
00549         
00550             #if TARGET_API_MAC_CARBON == 1
00551     
00552                 fs.vRefNum = (**v.data.filespecvalue).vRefNum;
00553                 fs.parID = (**v.data.filespecvalue).parID;
00554         
00555                 copystring ((**v.data.filespecvalue).name, fs.name);
00556     
00557             #else
00558         
00559                 fs = **v.data.filespecvalue;
00560             
00561             #endif
00562             
00563         #ifdef NEWFILESPECTYPE
00564             copystring (fs.fullSpecifier, bs);
00565         #else
00566             copystring (fs.name, bs);
00567         #endif          
00568             /*
00569             if (!fileexists (&fs, &flfolder) || !fileisfolder (&fs, &flfolder))
00570                 flfolder = false;
00571             */
00572             fileexists (&fs, &flfolder);    /*don't care about return, just flfolder value*/
00573         #ifdef WIN95VERSION
00574             if (endswithpathsep (bs))
00575                 setstringlength (bs, stringlength (bs) - 1);
00576 
00577             filefrompath (bs, bs);      
00578         #endif
00579             break;
00580         }
00581 
00582     if (flfolder)
00583         pushchar (chpathseparator, bs);
00584     
00585     return (setstringvalue (bs, vreturned));
00586     } /*filefrompathverb*/
00587 
00588 
00589 static boolean folderfrompathverb (hdltreenode hparam1, tyvaluerecord *vreturned) {
00590     
00591     /*
00592     2.1b2 dmb: do string manipulation if given a string, but otherwise 
00593     work with filespecs. in addition to avoiding string overflow, this 
00594     preserves ability to distinguish between identically-named volumes
00595     */
00596     
00597     tyvaluerecord v;
00598     
00599     flnextparamislast = true;
00600     
00601     if (!getparamvalue (hparam1, 1, &v))
00602         return (false);
00603     
00604     #ifdef WIN95VERSION
00605     if (!coercetostring (&v))
00606         return (false);
00607     #endif
00608 
00609     switch (v.valuetype) {
00610     
00611         case stringvaluetype: {
00612             bigstring bs;
00613             
00614             pullstringvalue (&v, bs);
00615             
00616             cleanendoffilename (bs);
00617             
00618             folderfrompath (bs, bs); /*bs now holds the foldername*/
00619             
00620             return (setstringvalue (bs, vreturned));
00621             }
00622         
00623         default: {
00624         #ifdef MACVERSION
00625             tyfilespec fs;
00626             
00627             if (!coercetofilespec (&v))
00628                 return (false);         
00629             
00630             #if TARGET_API_MAC_CARBON == 1
00631 
00632                 fs.vRefNum = (**v.data.filespecvalue).vRefNum;
00633                 
00634                 fs.parID = (**v.data.filespecvalue).parID;
00635                 
00636                 copystring ((**v.data.filespecvalue).name, fs.name);
00637             
00638             #else
00639                 
00640                 fs = **v.data.filespecvalue;
00641             
00642             #endif
00643             
00644             if (!getfileparentfolder (&fs, &fs))
00645                 return (false);
00646             
00647             return (setfilespecvalue (&fs, vreturned));
00648         #else
00649             return (false);
00650         #endif
00651             }
00652         }
00653     } /*folderfrompathverb*/
00654 
00655 
00656 static boolean gettypelistvalue (hdltreenode hparam1, short pnum, tysftypelist *filetypes, ptrsftypelist *x) {
00657 #pragma unused(pnum)
00658     /*
00659     2.1b4 dmb: new feature: accept a list of filetype for sfgetfile
00660     */
00661     
00662     tyvaluerecord val;
00663     tyvaluerecord vitem;
00664     long ctitems;
00665     short i;
00666 //  OSType toss;
00667     OSType filetype;
00668     
00669     if (!getparamvalue (hparam1, 3, &val))
00670         return (false);
00671     
00672     *x = filetypes; /*assume success & point to the typelist buffer*/
00673     
00674     switch (val.valuetype) {
00675         
00676         case listvaluetype:
00677             if (!langgetlistsize (&val, &ctitems))
00678                 return (false);
00679             
00680             ctitems = min (ctitems, maxsftypelist);
00681             
00682             (*filetypes).cttypes = (short)ctitems;
00683             
00684             for (i = 0; i < ctitems; ++i) {
00685                 
00686                 if (!langgetlistitem (&val, i + 1, nil, &vitem))
00687                     return (false);
00688                 
00689                 if (!coercetoostype (&vitem))
00690                     return (false);
00691                 
00692                 (*filetypes).types [i] = vitem.data.ostypevalue;
00693                 }
00694             
00695             break;
00696         
00697         default:
00698             if (!coercetoostype (&val))
00699                 return (false);
00700             
00701             filetype = val.data.ostypevalue;
00702             
00703             if (filetype == 0) /*no file type specified*/
00704                 *x = nil;
00705             
00706             else {
00707                 
00708                 (*filetypes).cttypes = 1;
00709                 
00710                 (*filetypes).types [0] = filetype;
00711                 }
00712         }
00713     
00714     return (true);
00715     } /*gettypelistvalue*/
00716 
00717 
00718 static boolean filedialogverb (tysfverb sfverb, hdltreenode hparam1, tyvaluerecord *vreturned) {
00719     
00720     /*
00721     put up one of the "standard file" dialogs.  if sfverb is sfputfileverb we use the "put" dialog, otherwise the "get" dialog.
00722     
00723     we take at least one parameter -- the name of a variable to receive the full path specified by the user.
00724     
00725     if it's the getfile dialog, we take a second parameter -- it indicates the
00726     type of the file.
00727     
00728     2005-10-06 creedon: added creator parameter
00729     
00730     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.
00731     */
00732     
00733     bigstring bsprompt;
00734     bigstring bsvarname;
00735     tyfilespec fs;
00736     tyvaluerecord val;
00737     tysftypelist filetypes;
00738     ptrsftypelist typelist = nil;
00739     hdlhashtable htable;
00740     boolean fl;
00741     OSType ostype, oscreator = kNavGenericSignature;
00742     bigstring bsext;
00743     hdlhashnode hnode;
00744     
00745     if (!getstringvalue (hparam1, 1, bsprompt))
00746         return (false);
00747     
00748     if (sfverb != sfgetfileverb)
00749         flnextparamislast = true;
00750     
00751     if (!getvarparam (hparam1, 2, &htable, bsvarname)) /*returned filename holder*/
00752         return (false);
00753     
00754     if (sfverb == sfgetfileverb) { /* get extra parameters for get file dialog, indicating file type(s) and file creator */
00755         
00756         short ctconsumed = 3;
00757         short ctpositional = 3;
00758         tyvaluerecord lval;
00759 
00760         if (!gettypelistvalue (hparam1, 3, &filetypes, &typelist))
00761             return (false);
00762             
00763         flnextparamislast = true;
00764         
00765         setostypevalue (oscreator, &lval);
00766 
00767         if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, BIGSTRING ("\x07""creator"), &lval))
00768             return (false);
00769     
00770         oscreator = lval.data.ostypevalue;
00771 
00772         }
00773     
00774     clearbytes (&fs, sizeof (fs));
00775     
00776     /*
00777     if (idstringvalue (htable, bsvarname, bsfname))
00778         filecheckdefaultpath (bsfname);
00779     */
00780     
00781     if (hashtablelookup (htable, bsvarname, &val, &hnode)) {
00782         
00783         if (!copyvaluerecord (val, &val))
00784             return (false);
00785         
00786         disablelangerror ();
00787         
00788         if (coercetofilespec (&val))
00789             fs = **val.data.filespecvalue;
00790         
00791         enablelangerror ();
00792         }
00793 
00794     if (sfverb == sfputfileverb) {
00795         lastword (fsname(&fs), '.', bsext);
00796 
00797         if (!((stringlength (fsname(&fs)) == stringlength (bsext)) || (stringlength (bsext) > 4))) {    /* extension */
00798             stringtoostype (bsext, &ostype);
00799             filetypes.cttypes = 1;
00800             filetypes.types [0] = ostype;
00801             typelist = &filetypes;
00802             }
00803         }
00804     
00805     setbooleanvalue (false, vreturned); 
00806     
00807     if (!sfdialog (sfverb, bsprompt, typelist, &fs, oscreator)) /*user hit cancel*/
00808         return (true);
00809     
00810     if (!setfilespecvalue (&fs, &val))
00811         return (false);
00812     
00813     pushhashtable (htable);
00814     
00815     fl = langsetsymbolval (bsvarname, val);
00816     
00817     pophashtable ();
00818     
00819     if (!fl)
00820         return (false);
00821     
00822     exemptfromtmpstack (&val);
00823     
00824     (*vreturned).data.flvalue = true; /*the user did select a file*/
00825     
00826     return (true);
00827     } /*filedialogverb*/
00828 
00829 
00830 static boolean getstringorintvalue (hdltreenode hfirst, short pnum, boolean flstring, short *intval, bigstring bsval) {
00831     
00832     /*
00833     if the parameter value is a string, set intval to -1 and return the string; 
00834     otherwise, return the value as an integer and set bsval to the empty string.
00835     
00836     7/29/91 dmb: now strictly enforce flstring; if true, paramter must coerce to a 
00837     string, otherwise to an int.
00838     */
00839     
00840     if (flstring) {
00841         
00842         if (!getstringvalue (hfirst, pnum, bsval))
00843             return (false);
00844         
00845         *intval = -1;
00846         }
00847     else {
00848         
00849         if (!getintvalue (hfirst, pnum, intval))
00850             return (false);
00851         
00852         setemptystring (bsval);
00853         }
00854     
00855     return (true);
00856     } /*getstringorintvalue*/
00857 
00858 
00859 static boolean getresourceverb (hdltreenode hparam1, boolean flnamed, tyvaluerecord *v) {
00860 
00861     /*
00862     2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
00863     */ 
00864     
00865     tyfilespec fs;
00866     OSType type;
00867     short id, forktype;
00868     short ctconsumed = 4;
00869     short ctpositional = 4;
00870     Handle h;
00871     hdlhashtable htable;
00872     bigstring bs, bsvarname;
00873     tyvaluerecord val;
00874     
00875     if (!getpathvalue (hparam1, 1, &fs)) 
00876         return (false);
00877     
00878     if (!getostypevalue (hparam1, 2, &type))
00879         return (false);
00880     
00881     if (!getstringorintvalue (hparam1, 3, flnamed, &id, bs))
00882         return (false);
00883     
00884     if (!getvarparam (hparam1, 4, &htable, bsvarname)) /*returned handle holder*/
00885         return (false);
00886     
00887     flnextparamislast = true;
00888     
00889     setintvalue (resourcefork, &val); /* defaults to 1 */
00890 
00891     if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, BIGSTRING ("\x04""fork"), &val))
00892         return (false);
00893     
00894     forktype = val.data.intvalue;
00895 
00896     if (!loadresourcehandle (&fs, type, id, bs, &h, forktype)) {
00897         
00898         (*v).data.flvalue = false;
00899         
00900         return (true);
00901         }
00902     
00903     if (!insertinhandle (h, 0L, &type, sizeof (type))) { /*out of memory*/
00904         
00905         disposehandle (h);
00906         
00907         return (false);
00908         }
00909     
00910     if (!langsetbinaryval (htable, bsvarname, h))
00911         return (false);
00912     
00913     (*v).data.flvalue = true;
00914     
00915     return (true);
00916     } /*getresourceverb*/
00917 
00918 
00919 static boolean putresourceverb (hdltreenode hparam1, boolean flnamed, tyvaluerecord *v) {
00920 
00921     /*
00922     2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
00923     */ 
00924     
00925     tyfilespec fs;
00926     OSType type, bintype;
00927     short id, forktype;
00928     short ctconsumed = 4;
00929     short ctpositional = 4;
00930     Handle hbinary;
00931     bigstring bs;
00932     tyvaluerecord val;
00933     
00934     if (!getpathvalue (hparam1, 1, &fs)) 
00935         return (false);
00936     
00937     if (!getostypevalue (hparam1, 2, &type))
00938         return (false);
00939     
00940     if (!getstringorintvalue (hparam1, 3, flnamed, &id, bs))
00941         return (false);
00942     
00943     if (!getbinaryvalue (hparam1, 4, false, &hbinary))
00944         return (false);
00945     
00946     pullfromhandle (hbinary, 0L, sizeof (bintype), &bintype);
00947     
00948     flnextparamislast = true;
00949     
00950     setintvalue (resourcefork, &val); /* defaults to 1 */
00951 
00952     if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, BIGSTRING ("\x04""fork"), &val))
00953         return (false);
00954 
00955     forktype = val.data.intvalue;
00956 
00957     (*v).data.flvalue = saveresourcehandle (&fs, type, id, bs, hbinary, forktype);
00958     
00959     return (true);
00960     } /*putresourceverb*/
00961 
00962 
00963 static boolean countrestypesverb (hdltreenode hparam1, tyvaluerecord *v) {
00964     
00965     /*
00966     2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
00967     */ 
00968     
00969     tyfilespec fs;
00970     short cttypes, forktype;
00971     short ctconsumed = 1;
00972     short ctpositional = 1;
00973     tyvaluerecord val;
00974     
00975     if (!getpathvalue (hparam1, 1, &fs)) 
00976         return (false);
00977     
00978     flnextparamislast = true;
00979     
00980     setintvalue (resourcefork, &val); /* defaults to 1 */
00981 
00982     if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, BIGSTRING ("\x04""fork"), &val))
00983         return (false);
00984     
00985     forktype = val.data.intvalue;
00986 
00987     if (!getnumresourcetypes (&fs, &cttypes, forktype))
00988         cttypes = 0;
00989     
00990     setlongvalue (cttypes, v);
00991     
00992     return (true);
00993     } /*countrestypesverb*/
00994 
00995 
00996 static boolean getnthrestypeverb (hdltreenode hparam1, tyvaluerecord *v) {
00997     
00998     /*
00999     2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
01000     */ 
01001     
01002     tyfilespec fs;
01003     short n, forktype;
01004     short ctconsumed = 3;
01005     short ctpositional = 3;
01006     OSType type;
01007     hdlhashtable htable;
01008     bigstring bsvarname;
01009     tyvaluerecord val;
01010     boolean fl;
01011     
01012     if (!getpathvalue (hparam1, 1, &fs)) 
01013         return (false);
01014     
01015     if (!getintvalue (hparam1, 2, &n))
01016         return (false);
01017     
01018     if (!getvarparam (hparam1, 3, &htable, bsvarname)) /*returned handle holder*/
01019         return (false);
01020     
01021     flnextparamislast = true;
01022     
01023     setintvalue (resourcefork, &val); /* defaults to 1 */
01024 
01025     if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, BIGSTRING ("\x04""fork"), &val))
01026         return (false);
01027     
01028     forktype = val.data.intvalue;
01029 
01030     if (!getnthresourcetype (&fs, n, &type, forktype)) { /*not a fatal error*/
01031         
01032         (*v).data.flvalue = false;
01033         
01034         return (true);
01035         }
01036     
01037     setostypevalue (type, &val);
01038     
01039     fl = langsetsymboltableval (htable, bsvarname, val);
01040     
01041     (*v).data.flvalue = fl;
01042     
01043     return (fl);
01044     } /*getnthrestypeverb*/
01045 
01046 
01047 static boolean countresourcesverb (hdltreenode hparam1, tyvaluerecord *v) {
01048     
01049     /*
01050     2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
01051     */ 
01052     
01053     tyfilespec fs;
01054     OSType type;
01055     short ctresources, forktype;
01056     short ctconsumed = 2;
01057     short ctpositional = 2;
01058     tyvaluerecord val;
01059     
01060     if (!getpathvalue (hparam1, 1, &fs)) 
01061         return (false);
01062     
01063     if (!getostypevalue (hparam1, 2, &type))
01064         return (false);
01065     
01066     flnextparamislast = true;
01067     
01068     setintvalue (resourcefork, &val); /* defaults to 1 */
01069 
01070     if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, BIGSTRING ("\x04""fork"), &val))
01071         return (false);
01072     
01073     forktype = val.data.intvalue;
01074 
01075     if (!getnumresources (&fs, type, &ctresources, forktype))
01076         ctresources = 0;
01077     
01078     setlongvalue (ctresources, v);
01079     
01080     return (true);
01081     } /*countresourcesverb*/
01082 
01083 
01084 static boolean getnthresourceverb (hdltreenode hparam1, tyvaluerecord *v) {
01085 
01086     /*
01087     2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
01088     */ 
01089     
01090     tyfilespec fs;
01091     OSType type;
01092     short n, id, forktype;
01093     short ctconsumed = 5;
01094     short ctpositional = 5;
01095     Handle h;
01096     hdlhashtable ht1, ht2;
01097     bigstring bs, bs1, bs2;
01098     boolean fl;
01099     tyvaluerecord val;
01100 
01101     if (!getpathvalue (hparam1, 1, &fs)) 
01102         return (false);
01103     
01104     if (!getostypevalue (hparam1, 2, &type))
01105         return (false);
01106     
01107     if (!getintvalue (hparam1, 3, &n))
01108         return (false);
01109     
01110     if (!getvarparam (hparam1, 4, &ht1, bs1)) /*returned name holder*/
01111         return (false);
01112     
01113     if (!getvarparam (hparam1, 5, &ht2, bs2)) /*returned handle holder*/
01114         return (false);
01115         
01116     flnextparamislast = true;
01117     
01118     setintvalue (resourcefork, &val); /* defaults to 1 */
01119 
01120     if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, BIGSTRING ("\x04""fork"), &val))
01121         return (false);
01122     
01123     forktype = val.data.intvalue;
01124 
01125     if (!getnthresourcehandle (&fs, type, n, &id, bs, &h, forktype)) {
01126         
01127         (*v).data.flvalue = false;
01128         
01129         return (true);
01130         }
01131     
01132     pushhashtable (ht1);
01133     
01134     fl = langsetstringval (bs1, bs);
01135     
01136     pophashtable ();
01137     
01138     if (!fl)
01139         return (false);
01140     
01141     if (!insertinhandle (h, 0L, &type, sizeof (type))) {
01142         
01143         disposehandle (h);
01144         
01145         return (false);
01146         }
01147     
01148     if (!langsetbinaryval (ht2, bs2, h))
01149         return (false);
01150     
01151     (*v).data.flvalue = true;
01152     
01153     return (true);
01154     } /*getnthresourceverb*/
01155 
01156 
01157 static boolean getnthresinfoverb (hdltreenode hparam1, tyvaluerecord *v) {
01158     
01159     /*
01160     2005-12-26 creedon: commented out param count check
01161     
01162     2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
01163     
01164     6/2/92 dmb: created.
01165     */
01166     
01167     tyfilespec fs;
01168     OSType type;
01169     short n, id, forktype;
01170     short ctconsumed = 5;
01171     short ctpositional = 5;
01172     hdlhashtable ht1;
01173     bigstring bs, bs1;
01174     boolean fl;
01175     tyvaluerecord val;
01176     
01177     /* if (!langcheckparamcount (hparam1, 5))
01178         return (false); */
01179     
01180     if (!getpathvalue (hparam1, 1, &fs)) 
01181         return (false);
01182     
01183     if (!getostypevalue (hparam1, 2, &type))
01184         return (false);
01185     
01186     if (!getintvalue (hparam1, 3, &n))
01187         return (false);
01188     
01189     setintvalue (resourcefork, &val); /* defaults to 1 */
01190 
01191     if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, BIGSTRING ("\x04""fork"), &val))
01192         return (false);
01193     
01194     forktype = val.data.intvalue;
01195 
01196     if (!getnthresourcehandle (&fs, type, n, &id, bs, nil, forktype)) {
01197         
01198         (*v).data.flvalue = false;
01199         
01200         return (true);
01201         }
01202     
01203     if (!langsetlongvarparam (hparam1, 4, id))
01204         return (false);
01205     
01206     if (!getvarparam (hparam1, 5, &ht1, bs1)) /*returned name holder*/
01207         return (false);
01208     
01209     pushhashtable (ht1);
01210     
01211     fl = langsetstringval (bs1, bs);
01212     
01213     pophashtable ();
01214     
01215     if (!fl)
01216         return (false);
01217     
01218     (*v).data.flvalue = true;
01219     
01220     return (true);
01221     } /*getnthresinfoverb*/
01222 
01223 
01224 static boolean resourceexistsverb (hdltreenode hparam1, boolean flnamed, tyvaluerecord *v) {
01225     
01226     /*
01227     2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
01228     */ 
01229     
01230     tyfilespec fs;
01231     OSType type;
01232     short id, forktype;
01233     short ctconsumed = 3;
01234     short ctpositional = 3;
01235     bigstring bs;
01236     tyvaluerecord val;
01237     
01238     if (!getpathvalue (hparam1, 1, &fs)) 
01239         return (false);
01240     
01241     if (!getostypevalue (hparam1, 2, &type))
01242         return (false);
01243     
01244     if (!getstringorintvalue (hparam1, 3, flnamed, &id, bs))
01245         return (false);
01246     
01247     flnextparamislast = true;
01248     
01249     setintvalue (resourcefork, &val); /* defaults to 1 */
01250 
01251     if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, BIGSTRING ("\x04""fork"), &val))
01252         return (false);
01253     
01254     forktype = val.data.intvalue;
01255 
01256     (*v).data.flvalue = loadresourcehandle (&fs, type, id, bs, nil, forktype);
01257     
01258     return (true);
01259     } /*resourceexistsverb*/
01260 
01261 
01262 static boolean getresourceattrsverb (hdltreenode hparam1, boolean flnamed, tyvaluerecord *v) {
01263     
01264     /*
01265     2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
01266     
01267     2.1b4 dmb: new verb
01268     */
01269     
01270     tyfilespec fs;
01271     OSType type;
01272     short id, attrs, forktype;
01273     short ctconsumed = 3;
01274     short ctpositional = 3;
01275     bigstring bs;
01276     tyvaluerecord val;
01277 
01278     if (!getpathvalue (hparam1, 1, &fs)) 
01279         return (false);
01280     
01281     if (!getostypevalue (hparam1, 2, &type))
01282         return (false);
01283     
01284     if (!getstringorintvalue (hparam1, 3, flnamed, &id, bs))
01285         return (false);
01286     
01287     flnextparamislast = true;
01288     
01289     setintvalue (resourcefork, &val); /* defaults to 1 */
01290 
01291     if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, BIGSTRING ("\x04""fork"), &val))
01292         return (false);
01293     
01294     forktype = val.data.intvalue;
01295 
01296     if (!getresourceattributes (&fs, type, id, bs, &attrs, forktype))
01297         return (false);
01298     
01299     return (setintvalue (attrs, v));
01300     } /*getresourceattrsverb*/
01301 
01302 
01303 static boolean setresourceattrsverb (hdltreenode hparam1, boolean flnamed, tyvaluerecord *v) {
01304     
01305     /*
01306     2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
01307     
01308     2.1b4 dmb: new verb
01309     */
01310     
01311     tyfilespec fs;
01312     OSType type;
01313     short id, attrs, forktype;
01314     short ctconsumed = 4;
01315     short ctpositional = 4;
01316     bigstring bs;
01317     tyvaluerecord val;
01318     
01319     if (!getpathvalue (hparam1, 1, &fs)) 
01320         return (false);
01321     
01322     if (!getostypevalue (hparam1, 2, &type))
01323         return (false);
01324     
01325     if (!getstringorintvalue (hparam1, 3, flnamed, &id, bs))
01326         return (false);
01327     
01328     if (!getintvalue (hparam1, 4, &attrs))
01329         return (false);
01330     
01331     flnextparamislast = true;
01332     
01333     setintvalue (resourcefork, &val); /* defaults to 1 */
01334 
01335     if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, BIGSTRING ("\x04""fork"), &val))
01336         return (false);
01337     
01338     forktype = val.data.intvalue;
01339 
01340     if (!setresourceattributes (&fs, type, id, bs, attrs, forktype))
01341         return (false);
01342     
01343     (*v).data.flvalue = true;
01344     
01345     return (true);
01346     } /*setresourceattrsverb*/
01347 
01348 
01349 static boolean deleteresourceverb (hdltreenode hparam1, boolean flnamed, tyvaluerecord *v) {
01350     
01351     /*
01352     2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
01353     */ 
01354     
01355     tyfilespec fs;
01356     OSType type;
01357     short id, forktype;
01358     short ctconsumed = 3;
01359     short ctpositional = 3;
01360     bigstring bs;
01361     tyvaluerecord val;
01362     
01363     if (!getpathvalue (hparam1, 1, &fs)) 
01364         return (false);
01365     
01366     if (!getostypevalue (hparam1, 2, &type))
01367         return (false);
01368     
01369     if (!getstringorintvalue (hparam1, 3, flnamed, &id, bs))
01370         return (false);
01371     
01372     flnextparamislast = true;
01373     
01374     setintvalue (resourcefork, &val); /* defaults to 1 */
01375 
01376     if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, BIGSTRING ("\x04""fork"), &val))
01377         return (false);
01378     
01379     forktype = val.data.intvalue;
01380 
01381     (*v).data.flvalue = deleteresource (&fs, type, id, bs, forktype);
01382     
01383     return (true);
01384     } /*deleteresourceverb*/
01385 
01386 
01387 static boolean geticonposverb (hdltreenode hparam1, tyvaluerecord *v) {
01388     
01389     /*
01390     9/30/91 dmb: use setintvarparam, saves code
01391     */
01392     
01393     tyfilespec fs;
01394     Point pos;
01395     /*
01396     hdlhashtable htable;
01397     bigstring bs;
01398     */
01399     
01400     if (!langcheckparamcount (hparam1, 3))
01401         return (false);
01402     
01403     if (!getpathvalue (hparam1, 1, &fs)) 
01404         return (false);
01405     
01406     if (!getfilepos (&fs, &pos))
01407         return (false);
01408     
01409     if (!setintvarparam (hparam1, 2, pos.h))
01410         return (false);
01411     
01412     if (!setintvarparam (hparam1, 3, pos.v))
01413         return (false);
01414     
01415     /*
01416     if (!getvarparam (hparam1, 2, &htable, bs)) 
01417         return (false);
01418     
01419     pushhashtable (htable);
01420     
01421     hashassignint (bs, pos.h);
01422     
01423     pophashtable ();
01424     
01425     if (!getvarparam (hparam1, 3, &htable, bs)) 
01426         return (false);
01427     
01428     pushhashtable (htable);
01429     
01430     hashassignint (bs, pos.v);
01431     
01432     pophashtable ();
01433     */
01434     
01435     (*v).data.flvalue = true;
01436     
01437     return (true);
01438     } /*geticonposverb*/
01439 
01440 
01441 static boolean seticonposverb (hdltreenode hparam1, tyvaluerecord *v) {
01442 
01443     tyfilespec fs;
01444     Point pos;
01445     
01446     if (!getpathvalue (hparam1, 1, &fs)) 
01447         return (false);
01448     
01449     if (!getintvalue (hparam1, 2, &pos.h)) 
01450         return (false);
01451     
01452     flnextparamislast = true;
01453     
01454     if (!getintvalue (hparam1, 3, &pos.v)) 
01455         return (false);
01456     
01457     (*v).data.flvalue = setfilepos (&fs, pos);
01458     
01459     return (true);
01460     } /*seticonposverb*/
01461 
01462 #ifdef MACVERSION
01463 /*
01464 11/17/92 dmb: this definition of the version resourcemakes it easier to 
01465 pick apart the BCD
01466 */
01467 
01468 typedef struct lNumVersion {
01469 #ifdef SWAP_REZ_BYTE_ORDER
01470     unsigned short nonRelRev2: 4;       /*  2nd nibble of revision level*/
01471     unsigned short nonRelRev1 : 4;      /*revision level of non-released version*/
01472     unsigned short stage : 8;           /*stage code: dev, alpha, beta, final*/
01473     unsigned short bugFixRev : 4;       /*3rd part is 1 nibble in BCD*/
01474     unsigned short minorRev : 4;        /*2nd part is 1 nibble in BCD*/
01475     unsigned short majorRev2: 4;        /*  2nd nibble of 1st part*/
01476     unsigned short majorRev1: 4;        /*1st part of version number in BCD*/
01477 #else
01478     unsigned short majorRev1: 4;        /*1st part of version number in BCD*/
01479     unsigned short majorRev2: 4;        /*  2nd nibble of 1st part*/
01480     unsigned short minorRev : 4;        /*2nd part is 1 nibble in BCD*/
01481     unsigned short bugFixRev : 4;       /*3rd part is 1 nibble in BCD*/
01482     unsigned short stage : 8;           /*stage code: dev, alpha, beta, final*/
01483     unsigned short nonRelRev1 : 4;      /*revision level of non-released version*/
01484     unsigned short nonRelRev2: 4;       /*  2nd nibble of revision level*/
01485 #endif
01486     } lNumVersion;
01487 
01488 typedef struct lVersRec {
01489     lNumVersion numericVersion;     /*encoded version number*/
01490     short countryCode;              /*country code from intl utilities*/
01491     Str255 shortVersion;            /*version number string - worst case*/
01492     Str255 reserved;                /*longMessage string packed after shortVersion*/
01493     } lVersRec, *lVersRecPtr, **lVersRecHndl;
01494 
01495 
01496 static byte bsstages [] = "\pdab";  /*dev, alpha, beta*/
01497 
01498 
01499 #define emptyversionsize ((long) sizeof (lNumVersion) + sizeof (short) + 2)
01500 
01501 
01502 static boolean versionnumtostring (lNumVersion numvers, bigstring bs) {
01503     
01504     /*
01505     return the packed version number as a string, e.g. "1.0b2".  need 
01506     definitions above, which is mis-defined in the Think C headers
01507     */
01508     
01509     /*
01510     lNumVersion numvers;
01511     
01512     numvers = *(lNumVersion *) &versionnum;
01513     */
01514     
01515     setemptystring (bs);
01516     
01517     if (numvers.majorRev1 != 0)
01518         shorttostring (numvers.majorRev1, bs);
01519     
01520     pushint (numvers.majorRev2, bs);
01521     
01522     pushchar ('.', bs);
01523     
01524     pushint (numvers.minorRev, bs);
01525     
01526     if (numvers.bugFixRev > 0) {
01527         
01528         pushchar ('.', bs);
01529         
01530         pushint (numvers.bugFixRev, bs);
01531         }
01532     
01533     if (numvers.stage < finalStage) {
01534         
01535         pushchar (bsstages [numvers.stage / developStage], bs);
01536         
01537         if (numvers.nonRelRev1 > 0)
01538             pushint (numvers.nonRelRev1, bs);
01539         
01540         pushint (numvers.nonRelRev2, bs);
01541         }
01542     
01543     return (true);
01544     } /*versionnumtostring*/
01545 
01546 
01547 typedef byte shortstring [16];
01548 
01549 static short stringtobcd (bigstring bs) {
01550     
01551     register short i;
01552     register short n = 0;
01553     
01554     for (i = 1; i <= stringlength (bs); ++i)
01555         n = (n << 4) + (bs [i] - '0');
01556     
01557     return (n);
01558     } /*stringtobcd*/
01559 
01560 
01561 static boolean stringtoversionnum (bigstring bs, NumVersion *versionnum) {
01562     
01563     /*
01564     convert the string to a packed version number.  see above.
01565     */
01566     
01567     NumVersion numvers;
01568     register short i;
01569     register byte ch;
01570     shortstring bsnumber [4]; /*the three rev numbers, as strings*/
01571     short number [4]; /*the rev numbers*/
01572     short ixnumber = 0;
01573     
01574     numvers.stage = finalStage;
01575     
01576     for (i = 0; i < 4; ++i)
01577         setemptystring (bsnumber [i]);
01578     
01579     for (i = 1; i <= stringlength (bs); ++i) {
01580         
01581         ch = bs [i];
01582         
01583         if (isnumeric (ch)) { /*digit: add to current number string*/
01584             
01585             pushchar (ch, bsnumber [ixnumber]);
01586             
01587             continue;
01588             }
01589         
01590         if (ixnumber == 3) /*we're full: take what we've got so far*/
01591             goto exit;
01592         
01593         if (ch == '.') { /*decimal point: move on to next number*/
01594             
01595             ++ixnumber;
01596             
01597             continue;
01598             }
01599         
01600         ixnumber = 3; /*only valid data would be stage character & number*/
01601         
01602         switch (lowercasechar (ch)) {
01603             
01604             case 'a':
01605                 numvers.stage = alphaStage;
01606                 
01607                 break;
01608             
01609             case 'b':
01610                 numvers.stage = betaStage;
01611                 
01612                 break;
01613             
01614             case 'd':
01615                 numvers.stage = developStage;
01616                 
01617                 break;
01618             
01619             default:
01620                 goto exit;
01621             }
01622         }
01623     
01624     exit:
01625     
01626     for (i = 0; i < 4; ++i)
01627         number [i] = stringtobcd (bsnumber [i]);
01628     
01629     numvers.majorRev = number [0];
01630     
01631     numvers.minorAndBugRev = (number [1] << 4) + number [2];
01632     
01633     numvers.nonRelRev = number [3];
01634     
01635     *versionnum = numvers;
01636     
01637     return (true);
01638     } /*stringtoversionnum*/
01639 
01640 
01641 boolean filegetprogramversion (bigstring bsversion) {
01642     
01643     /*
01644     12/19/91 dmb: this routine is here because this is the only file that currently 
01645     knows the format of a 'vers' resource.  it would more logically be in file.c
01646     */
01647     
01648     lNumVersion versionnumber;
01649     
01650     if (filereadresource (filegetapplicationrnum (), 'vers', 1, nil, sizeof (versionnumber), &versionnumber))
01651         return (versionnumtostring (versionnumber, bsversion));
01652     
01653     setemptystring (bsversion);
01654     
01655     return (false);
01656     } /*filegetprogramversion*/
01657 
01658 
01659 static boolean getshortversionverb (hdltreenode hparam1, tyvaluerecord *v) {
01660     
01661     /*
01662     file.getversion (path): string; return the version number as a string, e.g. "1.0b2".
01663     
01664     2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
01665     */
01666     
01667     tyfilespec fs;
01668     lNumVersion versionnumber;
01669     bigstring bs;
01670     short forktype;
01671     short ctconsumed = 1;
01672     short ctpositional = 1;
01673     tyvaluerecord val;
01674     
01675     if (!getpathvalue (hparam1, 1, &fs)) 
01676         return (false);
01677     
01678     flnextparamislast = true;
01679     
01680     setintvalue (resourcefork, &val); /* defaults to 1 */
01681 
01682     if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, BIGSTRING ("\x04""fork"), &val))
01683         return (false);
01684     
01685     forktype = val.data.intvalue;
01686 
01687     if (loadresource (&fs, -1, 'vers', 1, nil, sizeof (versionnumber), &versionnumber, forktype))
01688         versionnumtostring (versionnumber, bs);
01689     else
01690         setemptystring (bs);
01691     
01692     return (setstringvalue (bs, v));
01693     } /*getshortversionverb*/
01694 
01695 
01696 static boolean mungeversionstring (VersRecHndl hvers, bigstring bsversion, boolean fllongvers) {
01697     
01698     register byte *p;
01699     long ixvers;
01700     long ctvers;
01701     
01702     p = (**hvers).shortVersion;
01703     
01704     if (fllongvers)
01705         p += stringlength (p) + 1; /*skip to next contiguous string -- the long version*/
01706     
01707     ixvers = p - (byte *) *hvers;
01708     
01709     ctvers = stringsize (p);
01710     
01711     return (mungehandle ((Handle) hvers, ixvers, ctvers, bsversion, stringsize (bsversion)));
01712     } /*mungeversionstring*/
01713 
01714 
01715 static boolean setshortversionverb (hdltreenode hparam1, tyvaluerecord *v) {
01716     
01717     /*
01718     file.setversion (path): boolean; set the short version string.  if a valid version number is specified, set the numeric fields as well
01719     
01720     2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
01721     */
01722     
01723     tyfilespec fs;
01724     bigstring bsversion;
01725     NumVersion versionnumber;
01726     VersRecHndl hvers;
01727     short forktype;
01728     short ctconsumed = 2;
01729     short ctpositional = 2;
01730     tyvaluerecord val;
01731     
01732     if (!getpathvalue (hparam1, 1, &fs)) 
01733         return (false);
01734     
01735     if (!getstringvalue (hparam1, 2, bsversion)) 
01736         return (false);
01737     
01738     flnextparamislast = true;
01739     
01740     setintvalue (resourcefork, &val); /* defaults to 1 */
01741 
01742     if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, BIGSTRING ("\x04""fork"), &val))
01743         return (false);
01744     
01745     forktype = val.data.intvalue;
01746 
01747     if (!loadresourcehandle (&fs, 'vers', 1, nil, (Handle *) &hvers, forktype))
01748         if (!newclearhandle (emptyversionsize, (Handle *) &hvers))
01749             return (false);
01750     
01751     if (stringtoversionnum (bsversion, &versionnumber)) /*convert to BCD if possible*/
01752         (**hvers).numericVersion = versionnumber;
01753     
01754     if (mungeversionstring (hvers, bsversion, false))
01755         if (saveresourcehandle (&fs, 'vers', 1, nil, (Handle) hvers, forktype))
01756             (*v).data.flvalue = true;
01757     
01758     disposehandle ((Handle) hvers);
01759     
01760     return (true);
01761     } /*setshortversionverb*/
01762 
01763 
01764 static boolean getlongversionverb (hdltreenode hparam1, tyvaluerecord *v) {
01765 
01766     /*
01767     file.getfullversion (path): string; return the long version string "1.0b2 © Copyright 1991 UserLand Software.".  need definitions above, 
01768     which don't appear in the Think C headers anywhere
01769     
01770     2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
01771     */
01772     
01773     tyfilespec fs;
01774     lVersRecHndl hvers;
01775     bigstring bs;
01776     short forktype;
01777     short ctconsumed = 1;
01778     short ctpositional = 1;
01779     tyvaluerecord val;
01780     
01781     if (!getpathvalue (hparam1, 1, &fs)) 
01782         return (false);
01783     
01784     flnextparamislast = true;
01785     
01786     setintvalue (resourcefork, &val); /* defaults to 1 */
01787 
01788     if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, BIGSTRING ("\x04""fork"), &val))
01789         return (false);
01790     
01791     forktype = val.data.intvalue;
01792 
01793     setemptystring (bs);
01794     
01795     if (loadresourcehandle (&fs, 'vers', 1, nil, (Handle *) &hvers, forktype)) {
01796         
01797         register byte *p;
01798         
01799         p = (**hvers).shortVersion;
01800         
01801         p += stringlength (p) + 1; /*skip to next contiguous string -- the long version*/
01802         
01803         copystring (p, bs);
01804         
01805         disposehandle ((Handle) hvers);
01806         }
01807     
01808     return (setstringvalue (bs, v));
01809     } /*getlongversionverb*/
01810 
01811 
01812 static boolean setlongversionverb (hdltreenode hparam1, tyvaluerecord *v) {
01813     
01814     /*
01815     file.setversion (path): boolean; set the long version string.
01816     
01817     2005-09-02 creedon: added support for fork parameter, see resources.c: openresourcefile and pushresourcefile
01818     */
01819     
01820     tyfilespec fs;
01821     bigstring bsversion;
01822     VersRecHndl hvers;
01823     short forktype;
01824     short ctconsumed = 2;
01825     short ctpositional = 2;
01826     tyvaluerecord val;
01827     
01828     if (!getpathvalue (hparam1, 1, &fs)) 
01829         return (false);
01830     
01831     if (!getstringvalue (hparam1, 2, bsversion)) 
01832         return (false);
01833     
01834     flnextparamislast = true;
01835     
01836     setintvalue (resourcefork, &val); /* defaults to 1 */
01837 
01838     if (!getoptionalparamvalue (hparam1, &ctconsumed, &ctpositional, BIGSTRING ("\x04""fork"), &val))
01839         return (false);
01840     
01841     forktype = val.data.intvalue;
01842 
01843     if (!loadresourcehandle (&fs, 'vers', 1, nil, (Handle *) &hvers, forktype))
01844         if (!newclearhandle (emptyversionsize, (Handle *) &hvers))
01845             return (false);
01846     
01847     if (mungeversionstring (hvers, bsversion, true))
01848         if (saveresourcehandle (&fs, 'vers', 1, nil, (Handle) hvers, forktype))
01849             (*v).data.flvalue = true;
01850     
01851     disposehandle ((Handle) hvers);
01852     
01853     return (true);
01854     } /*setlongversionverb*/
01855 
01856 
01857 static boolean getcommentverb (hdltreenode hparam1, tyvaluerecord *v) {
01858     
01859     tyfilespec fs;
01860     bigstring bscomment;
01861     
01862     flnextparamislast = true;
01863     
01864     if (!getpathvalue (hparam1, 1, &fs)) 
01865         return (false);
01866     
01867     if (!getfilecomment (&fs, bscomment))
01868         setemptystring (bscomment);
01869     
01870     return (setstringvalue (bscomment, v));
01871     } /*getcommentverb*/
01872 
01873 
01874 static boolean setcommentverb (hdltreenode hparam1, tyvaluerecord *v) {
01875     
01876     tyfilespec fs;
01877     bigstring bscomment;
01878     
01879     if (!getpathvalue (hparam1, 1, &fs)) 
01880         return (false);
01881     
01882     flnextparamislast = true;
01883     
01884     if (!getstringvalue (hparam1, 2, bscomment)) 
01885         return (false);
01886     
01887     return (setbooleanvalue (setfilecomment (&fs, bscomment), v));
01888     } /*setcommentverb*/
01889 
01890 
01891 static boolean getlabelverb (hdltreenode hparam1, tyvaluerecord *v) {
01892     
01893     tyfilespec fs;
01894     bigstring bslabel;
01895     
01896     flnextparamislast = true;
01897     
01898     if (!getpathvalue (hparam1, 1, &fs)) 
01899         return (false);
01900     
01901     if (!getfilelabel (&fs, bslabel))
01902         setemptystring (bslabel);
01903     
01904     return (setstringvalue (bslabel, v));
01905     } /*getlabelverb*/
01906 
01907 
01908 static boolean setlabelverb (hdltreenode hparam1, tyvaluerecord *v) {
01909     
01910     tyfilespec fs;
01911     bigstring bslabel;
01912     
01913     if (!getpathvalue (hparam1, 1, &fs)) 
01914         return (false);
01915     
01916     flnextparamislast = true;
01917     
01918     if (!getstringvalue (hparam1, 2, bslabel)) 
01919         return (false);
01920     
01921     return (setbooleanvalue (setfilelabel (&fs, bslabel), v));
01922     } /*setlabelverb*/
01923 
01924 
01925 static boolean getlabelindexverb (hdltreenode hparam1, tyvaluerecord *v) {
01926 
01927     /*
01928     2006-04-24 creedon: created, cribbed from getlabelverb function
01929     */
01930     
01931     tyfilespec fs;
01932     short ixlabel;
01933     
01934     flnextparamislast = true;
01935 
01936     if (!getpathvalue (hparam1, 1, &fs)) 
01937         return (false);
01938 
01939     if (!getfilelabelindex (&fs, &ixlabel))
01940         return (false);
01941     
01942     return (setintvalue (ixlabel, v));
01943     } /* getlabelindexverb */
01944 
01945 
01946 static boolean setlabelindexverb (hdltreenode hparam1, tyvaluerecord *v) {
01947 
01948     /*
01949     2006-04-24 creedon: created, cribbed from setlabelverb function
01950     */
01951     
01952     tyfilespec fs;
01953     short index;
01954     
01955     if (!getpathvalue (hparam1, 1, &fs)) 
01956         return (false);
01957     
01958     flnextparamislast = true;
01959     
01960     if (!getintvalue (hparam1, 2, &index)) 
01961         return (false);
01962         
01963     return (setbooleanvalue (setfilelabelindex (&fs, index, true), v));
01964     } /* setlabelindexverb */
01965 
01966 
01967 static boolean getlabelnamesverb (hdltreenode hparam1, tyvaluerecord *v) {
01968     #pragma unused (hparam1)
01969 
01970     /*
01971     2006-04-24 creedon: created, cribbed from statusbargetsectionsfunc case of langfunctionvalue function
01972     */
01973 
01974     bigstring bsarray [8];
01975     hdllistrecord hlist;
01976     int ix;
01977     RGBColor labelcolor;
01978     short mapfromuserinterfaceindex [8] = {0, 6, 7, 5, 2, 4, 3, 1};
01979 
01980     for (ix = 0; ix < 8; ++ix)
01981     
01982         if (GetLabel (ix, &labelcolor, bsarray [ix]) != noErr)
01983         
01984             return (false);
01985             
01986     if (!opnewlist (&hlist, false))
01987         return (false);
01988 
01989     for (ix = 0; ix < 8; ++ix)
01990 
01991         if (!langpushliststring (hlist, bsarray [mapfromuserinterfaceindex [ix]]))
01992         
01993             goto getlabelnamesverberror;
01994 
01995     return (setheapvalue ((Handle) hlist, listvaluetype, v));
01996     
01997     getlabelnamesverberror:
01998 
01999     opdisposelist (hlist);
02000     
02001     return (false);
02002 
02003     } /* getlabelnamesverb */
02004         
02005 #endif
02006 
02007 
02008 static boolean findapplicationverb (hdltreenode hparam1, tyvaluerecord *v) {
02009     
02010     OSType creator;
02011     tyfilespec fsapp;
02012     
02013     flnextparamislast = true;
02014     
02015     if (!getostypevalue (hparam1, 1, &creator)) 
02016         return (false);
02017     
02018     if (!findapplication (creator, &fsapp))
02019         clearbytes (&fsapp, sizeof (fsapp));
02020     
02021     return (setfilespecvalue (&fsapp, v));
02022     } /*findapplicationverb*/
02023 
02024 
02025 #ifdef WIN95VERSION
02026 
02027 boolean filegetprogramversion (bigstring bsversion) {
02028     
02029     return (getstringlist (defaultlistnumber, programversion, bsversion));
02030     } /*filegetprogramversion*/
02031 
02032 
02033 static boolean getshortversionverb (hdltreenode hparam1, tyvaluerecord *v) {
02034     
02035     /*
02036     file.getversion (path): string; return the version number as 
02037     a string, e.g. "1.0b2".
02038     */
02039     
02040     tyfilespec fs;
02041     DWORD dummyhandle;
02042     bigstring bs;
02043     DWORD buflen;
02044     char * buf;
02045     VS_FIXEDFILEINFO * ffi;
02046     char * info;
02047     boolean flffi;
02048     
02049     flnextparamislast = true;
02050     
02051     if (!getpathvalue (hparam1, 1, &fs)) 
02052         return (false);
02053     
02054     nullterminate (fsname(&fs));
02055 
02056     setemptystring (bs);
02057 
02058     buflen = GetFileVersionInfoSize (stringbaseaddress(fsname(&fs)), &dummyhandle);
02059 
02060     if (buflen > 0) {
02061         buf = (char *) LocalAlloc (LPTR, buflen);
02062         
02063         if (buf != NULL) {
02064             if (GetFileVersionInfo (stringbaseaddress(fsname(&fs)), dummyhandle, buflen, buf)) {
02065                 buflen = sizeof(VS_FIXEDFILEINFO);
02066 
02067                 flffi = VerQueryValue (buf, "\\", &ffi, &buflen);
02068 
02069                 if (flffi)
02070                     flffi = buflen > 0;
02071 
02072                 buflen = 0;
02073 
02074                 VerQueryValue (buf, "\\StringFileInfo\\040904E4\\FileVersion", &info, &buflen);
02075                 
02076                 if (buflen == 0) {
02077                     VerQueryValue (buf, "\\StringFileInfo\\040904B0\\FileVersion", &info, &buflen);
02078                     }
02079 
02080                 if (buflen != 0)
02081                     copyctopstring (info, bs);
02082                 else if (flffi) {
02083                     wsprintf (stringbaseaddress (bs), "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS), 
02084                             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
02085                     setstringlength (bs, strlen(stringbaseaddress(bs)));
02086                     }
02087                 }
02088 
02089             LocalFree (buf);
02090             }
02091         }
02092 
02093     return (setstringvalue (bs, v));
02094     } /*getshortversionverb*/
02095 
02096 
02097 static boolean getlongversionverb (hdltreenode hparam1, tyvaluerecord *v) {
02098 
02099     /*
02100     file.getfullversion (path): string; return the long version string 
02101     "1.0b2 © Copyright 1991 UserLand Software.".  need definitions above, 
02102     which don't appear in the Think C headers anywhere
02103     */
02104     
02105     tyfilespec fs;
02106     DWORD dummyhandle;
02107     bigstring bs, bs2;
02108     DWORD buflen;
02109     char * buf;
02110     VS_FIXEDFILEINFO * ffi;
02111     char * info;
02112     
02113     flnextparamislast = true;
02114     
02115     if (!getpathvalue (hparam1, 1, &fs)) 
02116         return (false);
02117     
02118     nullterminate (fsname(&fs));
02119 
02120     setemptystring (bs);
02121     setemptystring (bs2);
02122 
02123     buflen = GetFileVersionInfoSize (stringbaseaddress(fsname(&fs)), &dummyhandle);
02124 
02125     if (buflen > 0) {
02126         buf = (char *) LocalAlloc (LPTR, buflen);
02127         
02128         if (buf != NULL) {
02129             if (GetFileVersionInfo (stringbaseaddress(fsname(&fs)), dummyhandle, buflen, buf)) {
02130                 buflen = sizeof(VS_FIXEDFILEINFO);
02131                 VerQueryValue (buf, "\\", &ffi, &buflen);
02132 
02133                 VerQueryValue (buf, "\\StringFileInfo\\040904E4\\FileVersion", &info, &buflen);
02134                 
02135                 if (buflen == 0) {
02136                     VerQueryValue (buf, "\\StringFileInfo\\040904B0\\FileVersion", &info, &buflen);
02137                     }
02138 
02139                 if (buflen != 0)
02140                     copyctopstring (info, bs);
02141 
02142                 VerQueryValue (buf, "\\StringFileInfo\\040904E4\\LegalCopyright", &info, &buflen);
02143                 
02144                 if (buflen == 0) {
02145                     VerQueryValue (buf, "\\StringFileInfo\\040904B0\\LegalCopyright", &info, &buflen);
02146                     }
02147 
02148                 if (buflen != 0)
02149                     copyctopstring (info, bs2);
02150 
02151                 if (stringlength(bs) > 0)
02152                     pushspace (bs);
02153 
02154                 pushstring (bs2, bs);
02155                 }
02156 
02157             LocalFree (buf);
02158             }
02159         }
02160 
02161     return (setstringvalue (bs, v));
02162     } /*getlongversionverb*/
02163 
02164 static boolean getcommentverb (hdltreenode hparam1, tyvaluerecord *v) {
02165     
02166     /*
02167     file.getversion (path): string; return the version number as 
02168     a string, e.g. "1.0b2".
02169     */
02170     
02171     tyfilespec fs;
02172     DWORD dummyhandle;
02173     bigstring bs;
02174     DWORD buflen;
02175     char * buf;
02176     VS_FIXEDFILEINFO * ffi;
02177     char * info;
02178     
02179     flnextparamislast = true;
02180     
02181     if (!getpathvalue (hparam1, 1, &fs)) 
02182         return (false);
02183     
02184     nullterminate (fsname(&fs));
02185 
02186     setemptystring (bs);
02187 
02188     buflen = GetFileVersionInfoSize (stringbaseaddress(fsname(&fs)), &dummyhandle);
02189 
02190     if (buflen > 0) {
02191         buf = (char *) LocalAlloc (LPTR, buflen);
02192         
02193         if (buf != NULL) {
02194             if (GetFileVersionInfo (stringbaseaddress(fsname(&fs)), dummyhandle, buflen, buf)) {
02195                 buflen = sizeof(VS_FIXEDFILEINFO);
02196                 VerQueryValue (buf, "\\", &ffi, &buflen);
02197 
02198                 VerQueryValue (buf, "\\StringFileInfo\\040904E4\\FileDescription", &info, &buflen);
02199                 
02200                 if (buflen == 0) {
02201                     VerQueryValue (buf, "\\StringFileInfo\\040904B0\\FileDescription", &info, &buflen);
02202                     }
02203 
02204                 if (buflen != 0)
02205                     copyctopstring (info, bs);
02206                 }
02207 
02208             LocalFree (buf);
02209             }
02210         }
02211 
02212     return (setstringvalue (bs, v));
02213     } /*getcommentverb*/
02214 
02215 #endif
02216 
02217 /*start of new verbs added by DW, 7/27/91*/
02218 
02219 static boolean findfileverb (hdltreenode hparam1, tyvaluerecord *v) {
02220     
02221     /*
02222     8/25/92 dmb: set return value to true or false, so glue isn't needed
02223     */
02224     
02225     tyfilespec fs;
02226     bigstring pattern;
02227     long idx;
02228     
02229     if (!getpathvalue (hparam1, 1, &fs))
02230         return (false);
02231     
02232     flnextparamislast = true;
02233     
02234     if (!getstringvalue (hparam1, 2, pattern))
02235         return (false);
02236         
02237     fiffindinfile (&fs, pattern, &idx);
02238     
02239     /*
02240     setlongvalue (idx, v);
02241     */
02242     
02243     setbooleanvalue ((boolean) (idx >= 0), v);
02244     
02245     return (true);
02246     } /*findfileverb*/
02247     
02248 
02249 static boolean countlinesverb (hdltreenode hparam1, tyvaluerecord *v) {
02250     
02251     tyfilespec fs;
02252     long ctlines;
02253     
02254     flnextparamislast = true;
02255     
02256     if (!getpathvalue (hparam1, 1, &fs))
02257         return (false);
02258         
02259     fifcharcounter (&fs, chreturn, &ctlines);
02260     
02261     setlongvalue (ctlines, v);
02262     
02263     return (true);
02264     } /*countlinesverb*/
02265     
02266 
02267 static boolean openfileverb (hdltreenode hparam1, tyvaluerecord *v) {
02268     
02269     /*
02270     5.0.1 dmb: removed incorrect case for W95
02271     */
02272 
02273     tyfilespec fs;
02274     
02275     flnextparamislast = true;
02276     
02277     if (!getpathvalue (hparam1, 1, &fs))
02278         return (false);
02279 
02280     (*v).data.flvalue = fifopenfile (&fs, (long) currentprocess);
02281     
02282     return (true);
02283     } /*openfileverb*/
02284     
02285 
02286 static boolean closefileverb (hdltreenode hparam1, tyvaluerecord *v) {
02287 
02288     tyfilespec fs;
02289     
02290     flnextparamislast = true;
02291     
02292     if (!getpathvalue (hparam1, 1, &fs))
02293         return (false);
02294         
02295     (*v).data.flvalue = fifclosefile (&fs);
02296     
02297     return (true);
02298     } /*closefileverb*/
02299 
02300 
02301 static boolean endoffileverb (hdltreenode hparam1, tyvaluerecord *v) {
02302 
02303     tyfilespec fs;
02304     
02305     flnextparamislast = true;
02306     
02307     if (!getpathvalue (hparam1, 1, &fs))
02308         return (false);
02309         
02310     (*v).data.flvalue = fifendoffile (&fs);
02311     
02312     return (true);
02313     } /*endoffileverb*/
02314     
02315 
02316 static boolean setendoffileverb (hdltreenode hparam1, tyvaluerecord *v) {
02317 
02318     tyfilespec fs;
02319     long eof;
02320     
02321     if (!getpathvalue (hparam1, 1, &fs))
02322         return (false);
02323     
02324     flnextparamislast = true;
02325     
02326     if (!getlongvalue (hparam1, 2, &eof))
02327         return (false);
02328     
02329     (*v).data.flvalue = fifsetendoffile (&fs, eof);
02330     
02331     return (true);
02332     } /*endoffileverb*/
02333     
02334 
02335 static boolean getendoffileverb (hdltreenode hparam1, tyvaluerecord *v) {
02336 
02337     tyfilespec fs;
02338     long eof;
02339     
02340     flnextparamislast = true;
02341     
02342     if (!getpathvalue (hparam1, 1, &fs))
02343         return (false);
02344     
02345     if (!fifgetendoffile (&fs, &eof))
02346         return (false);
02347     
02348     return (setlongvalue (eof, v));
02349     } /*endoffileverb*/
02350 
02351 
02352 static boolean setpositionverb (hdltreenode hparam1, tyvaluerecord *v) {
02353 
02354     tyfilespec fs;
02355     long pos;
02356     
02357     if (!getpathvalue (hparam1, 1, &fs))
02358         return (false);
02359     
02360     flnextparamislast = true;
02361     
02362     if (!getlongvalue (hparam1, 2, &pos))
02363         return (false);
02364     
02365     (*v).data.flvalue = fifsetposition (&fs, pos);
02366     
02367     return (true);
02368     } /*positionverb*/
02369     
02370 
02371 static boolean getpositionverb (hdltreenode hparam1, tyvaluerecord *v) {
02372 
02373     tyfilespec fs;
02374     long pos;
02375     
02376     flnextparamislast = true;
02377     
02378     if (!getpathvalue (hparam1, 1, &fs))
02379         return (false);
02380     
02381     if (!fifgetposition (&fs, &pos))
02382         return (false);
02383     
02384     return (setlongvalue (pos, v));
02385     } /*positionverb*/
02386     
02387 
02388 static boolean readlineverb (hdltreenode hparam1, tyvaluerecord *v) {
02389 
02390     tyfilespec fs;
02391     Handle linestring;
02392     
02393     flnextparamislast = true;
02394     
02395     if (!getpathvalue (hparam1, 1, &fs))
02396         return (false);
02397     
02398     fifreadline (&fs, &linestring);
02399     
02400     return (setheapvalue (linestring, stringvaluetype, v));
02401     } /*readlineverb*/
02402     
02403 
02404 static boolean writelineverb (hdltreenode hparam1, tyvaluerecord *v) {
02405 
02406     tyfilespec fs;
02407     Handle linestring;
02408     
02409     if (!getpathvalue (hparam1, 1, &fs))
02410         return (false);
02411     
02412     flnextparamislast = true;
02413     
02414     if (!gettextvalue (hparam1, 2, &linestring))
02415         return (false);
02416     
02417     (*v).data.flvalue = fifwriteline (&fs, linestring);
02418     
02419     return (true);
02420     } /*writelineverb*/
02421 
02422 
02423 static boolean readwholefileverb (hdltreenode hparam1, tyvaluerecord *v) {
02424     
02425     /*
02426     Read the whole file into memory and return the data to the caller.
02427     
02428     2006-04-11 aradke: Kernelized file.readWholeFile. Obsolete script code follows:
02429     
02430         on readWholeFile (f) {
02431             ę10/31/97 at 1:02:04 PM by DW -- moved from toys.readWholeFile
02432             local (s);
02433             file.open (f);
02434             s = file.read (f, infinity);
02435             file.close (f);
02436             return (s)}
02437     
02438     This kernel implementation is much more efficient than file.read because
02439     it pre-allocates a handle large enough for the whole file.
02440     */
02441 
02442     tyfilespec fs;
02443     Handle x;
02444     boolean fl;
02445     
02446     flnextparamislast = true;
02447     
02448     if (!getpathvalue (hparam1, 1, &fs))
02449         return (false);
02450 
02451     if (!fifopenfile (&fs, (long) currentprocess))
02452         return (false);
02453 
02454     fl = fifreadfile (&fs, &x);
02455         
02456     disablelangerror ();
02457         
02458     (void) fifclosefile (&fs);  /* ignore return value, we got what we wanted */
02459     
02460     enablelangerror ();
02461     
02462     return (fl && setbinaryvalue (x, '\?\?\?\?', v));
02463     } /*readwholefileverb*/
02464 
02465 
02466 static boolean readverb (hdltreenode hparam1, tyvaluerecord *v) {
02467     
02468     tyfilespec fs;
02469     Handle x;
02470     long ctbytes;
02471     
02472     if (!getpathvalue (hparam1, 1, &fs))
02473         return (false);
02474     
02475     flnextparamislast = true;
02476     
02477     if (!getlongvalue (hparam1, 2, &ctbytes))
02478         return (false);
02479     
02480     if (!fifreadhandle (&fs, ctbytes, &x))
02481         return (true);
02482     
02483     if ((ctbytes < longinfinity) && (ctbytes != gethandlesize (x))) { /*ran out of data*/
02484         
02485         disposehandle (x);
02486         
02487         return (true);
02488         }
02489     
02490     return (setbinaryvalue (x, '\?\?\?\?', v));
02491     } /*readverb*/
02492 
02493 
02494 static boolean writeverb (hdltreenode hparam1, tyvaluerecord *v) {
02495     
02496     /*
02497     5.0.2b17 dmb: use new getreadonlytextvalue
02498     */
02499     
02500     tyfilespec fs;
02501     //tyvaluerecord val;
02502     Handle hdata;
02503     
02504     if (!getpathvalue (hparam1, 1, &fs))
02505         return (false);
02506     
02507     flnextparamislast = true;
02508     
02509     /*
02510     if (!getbinaryparam (hparam1, 2, &val))
02511         return (false);
02512     
02513     if (!coercetostring (&val))
02514         return (false);
02515     
02516     (*v).data.flvalue = fifwritehandle (&fs, (Handle) val.data.stringvalue);
02517     */
02518     if (!getreadonlytextvalue (hparam1, 2, &hdata))
02519         return (false);
02520     
02521     (*v).data.flvalue = fifwritehandle (&fs, hdata);
02522     
02523     return (true);
02524     } /*writeverb*/
02525 
02526 
02527 #if 0
02528 
02529 static boolean writewholefileverb (hdltreenode hparam1, tyvaluerecord *v) {
02530 
02531     /*
02532     on writeWholeFile (f, s, type = nil, creator = nil, creationdate = clock.now ()) {
02533         «10/31/97 at 1:41:20 PM by DW -- moved from toys.writeWholeFile
02534         «Friday, July 18, 1997 at 10:22:07 AM by PBS
02535             «Conditionalized for multiple platforms, with optional parameters.
02536         file.new (f);
02537         file.open (f);
02538         if sys.os () == "MacOS" {
02539             if type != nil {
02540                 file.setType (f, type)};
02541             if creator != nil {
02542                 file.setCreator (f, creator)};
02543             file.setCreated (f, creationdate)};
02544         file.write (f, s);
02545         file.close (f);
02546         return (true)}
02547     */
02548     
02549     tyfilespec fs;
02550     tyvaluerecord val;
02551     
02552     if (!getpathvalue (hparam1, 1, &fs))
02553         return (false);
02554     
02555     flnextparamislast = true;
02556     
02557     if (!getbinaryparam (hparam1, 2, &val))
02558         return (false);
02559     
02560     if (!coercetostring (&val)) //strip binary type
02561         return (false);
02562     
02563     (*v).data.flvalue = fifwritehandle (&fs, (Handle) val.data.stringvalue);
02564     
02565     return (true);
02566     } /*writewholefileverb*/
02567 
02568 #endif
02569 
02570 
02571 static boolean comparefilesverb (hdltreenode hparam1, tyvaluerecord *v) {
02572 
02573     tyfilespec fs1, fs2;
02574     
02575     if (!getpathvalue (hparam1, 1, &fs1))
02576         return (false);
02577     
02578     flnextparamislast = true;
02579     
02580     if (!getpathvalue (hparam1, 2, &fs2))
02581         return (false);
02582         
02583     (*v).data.flvalue = fifcomparefiles (&fs1, &fs2);
02584     
02585     return (true);
02586     } /*comparefilesverb*/
02587     
02588 
02589 /*end of new verbs added by DW, 7/27/91*/
02590 
02591 #ifdef MACVERSION
02592 static boolean newaliasverb (hdltreenode hparam1, tyvaluerecord *vreturned) {
02593     
02594     /*
02595     6/2/92 dmb: make sure that destination path doesn't end in a colon; 
02596     otherwise pathtofilespec will fail
02597     */
02598     
02599     tyfilespec fs, fsalias;
02600     
02601     if (!langcanusealiases ())
02602         return (false);
02603     
02604     if (!getpathvalue (hparam1, 1, &fs)) /*bs holds the source file's path*/
02605         return (false);
02606     
02607     flnextparamislast = true;
02608     
02609     if (!getpathvalue (hparam1, 2, &fsalias)) /*bsalias holds the new alias's path*/
02610         return (false);
02611     
02612     if (!surefile (&fs)) /*make sure source file exists*/
02613         return (false);
02614     
02615     setoserrorparam ((ptrstring) fsalias.name); /*assume error will relate to new file*/
02616     
02617     setbooleanvalue (MakeAliasFile (&fs, &fsalias), vreturned);
02618     
02619     return (true);
02620     } /*newaliasverb*/
02621 
02622 
02623 static boolean followaliasverb (hdltreenode hparam1, tyvaluerecord *vreturned) {
02624     
02625     /*
02626     1/29/92 dmb: a kernel version of what used to be implemented in glue.  
02627     there a difference in the functionality as coded here:  ResolveAliasFile 
02628     is being asked to follow chains of aliases; it will follow an alias to an alias 
02629     to the original.  to match the original version & documentation, if the original 
02630     file is not an alias, the empty string is returned.
02631     also, we need to Gestalt aliases...
02632     */
02633     
02634     bigstring bs;
02635     FSSpec fs;
02636     boolean flfolder;
02637     Boolean flaliasfolder, flwasalias;
02638     OSErr errcode;
02639     
02640     if (!langcanusealiases ())
02641         return (false);
02642     
02643     flnextparamislast = true;
02644     
02645     if (!getpathvalue (hparam1, 1, &fs)) /*bs holds the file path*/
02646         return (false);
02647     
02648     if (!fileexists (&fs, &flfolder)) { /*make sure original*/
02649         
02650         setoserrorparam (bs);
02651         
02652         oserror (errorFileNotFound); /*file not found*/
02653         
02654         return (false);
02655         }
02656     
02657     errcode = ResolveAliasFile (&fs, true, &flaliasfolder, &flwasalias);
02658     
02659     switch (errcode) {
02660         
02661         case errorNone:
02662             if (flwasalias)
02663                 return (setfilespecvalue (&fs, vreturned));
02664             else
02665                 setemptystring (bs);
02666             
02667             break;
02668         
02669         case errorFileNotFound:
02670             setemptystring (bs);
02671             
02672             break;
02673         
02674         case userCanceledErr:
02675             return (false);
02676         
02677         default:
02678             oserror (errcode);
02679             
02680             return (false);
02681         }
02682     
02683     return (setstringvalue (bs, vreturned));
02684     } /*followaliasverb*/
02685 #endif
02686 
02687 
02688 #ifdef MACVERSION
02689 boolean filelaunchanythingverb (hdltreenode hparam1, tyvaluerecord *vreturned) {
02690     
02691     /*
02692     6/1/92 dmb: generate oserror if System7Open fails
02693     */
02694     
02695     tyfilespec fs;
02696     
02697     #ifdef flsystem6
02698     
02699     if (!langcanuseappleevents ())
02700         return (false);
02701     
02702     #endif
02703     
02704     flnextparamislast = true;
02705     
02706     if (!getpathvalue (hparam1, 1, &fs)) /*bs holds the file's path*/
02707         return (false);
02708     
02709     setoserrorparam (fs.name);
02710     
02711     if (oserror (System7Open (fs)))
02712         return (false);
02713     
02714     return (setbooleanvalue (true, vreturned));
02715     } /*filelaunchanythingverb*/
02716 #endif
02717 
02718 static boolean filefunctionvalue (short token, hdltreenode hparam1, tyvaluerecord *vreturned, bigstring bserror) {
02719     
02720     /*
02721     bridges file.c with the language.  the name of the verb is bs, its first parameter
02722     is hparam1, and we return a value in vreturned.
02723     
02724     we use a limited number of support routines from lang.c to get parameters and
02725     to return values. 
02726     
02727     return false only if the error is serious enough to halt the running of the script
02728     that called us, otherwise error values are returned through the valuerecord, which
02729     is available to the script.
02730     
02731     if we return false, we try to provide a descriptive error message in the 
02732     returned string bserror.
02733     
02734     10/15/91: file.setpath, file.folderfrompath now handle partial paths corectly
02735     
02736     2/13/92 dmb: re-hooked up hasbundle verb
02737     
02738     6/2/92 dmb: made filefrompath work as documented so that glue isn't needed
02739     
02740     6/9/92 dmb: added file.isvisible, file.setvisible
02741     
02742     8/25/92 dmb: made newfunc delete existing file, so glue isn't necessary
02743     
02744     9/26/92 dmb: use one bigstring instead of two for filefrompath and folderfrompath.
02745     also, dont allow getfullfilepath to generate an error in folderfrompath
02746     
02747     9/30/92 dmb: call new langcheckstackspace; most file functions chew up a good bit
02748     
02749     2.1b2 dmb: use filespecs everywhere. added volumeblocksize verb
02750     
02751     2.1b12 dmb: if mountservervolumefunc's volumepath is improperly formed, generate 
02752     informative message instead of failing silently
02753     
02754     5.0.2b16 dmb: added getpathcharfunc
02755     
02756     2006-04-11 aradke: added readwholefilefunc
02757     */
02758     
02759     register hdltreenode hp1 = hparam1;
02760     register tyvaluerecord *v = vreturned;
02761     
02762     setbooleanvalue (false, v); /*by default, file functions return false*/
02763     
02764     if (!langcheckstackspace ())
02765         return (false);
02766     
02767     switch (token) {
02768         
02769         case filecreatedfunc: {
02770             
02771             unsigned long datecreated, datetoss;
02772             boolean fl;
02773             tyfilespec fs;
02774             
02775             flnextparamislast = true;
02776             
02777             if (!getpathvalue (hp1, 1, &fs)) /*fs holds the file path*/
02778                 break;
02779             
02780             if (fileisvolume (&fs))
02781                 fl = volumecreated (&fs, &datecreated);
02782             else
02783                 fl = getfiledates (&fs, &datecreated, &datetoss);
02784             
02785             if (!fl)
02786                 break;
02787             
02788             return (setdatevalue (datecreated, v));
02789             }
02790             
02791         case filemodifiedfunc: {
02792             
02793             unsigned long datemodified, datetoss;
02794             tyfilespec fs;
02795             
02796             flnextparamislast = true;
02797             
02798             if (!getpathvalue (hp1, 1, &fs))
02799                 break;
02800             
02801             if (!getfiledates (&fs, &datetoss, &datemodified))
02802                 break;
02803             
02804             return (setdatevalue (datemodified, v));
02805             }
02806             
02807         case filetypefunc: {
02808             
02809             OSType type;
02810             tyfilespec fs;
02811             
02812             flnextparamislast = true;
02813             
02814             if (!getpathvalue (hp1, 1, &fs))
02815                 break;
02816             
02817             if (!getfiletype (&fs, &type))
02818                 break;
02819             
02820             return (setostypevalue (type, v));
02821             }
02822             
02823         case filecreatorfunc: {
02824             
02825             OSType creator;
02826             tyfilespec fs;
02827             
02828             flnextparamislast = true;
02829             
02830             if (!getpathvalue (hp1, 1, &fs))
02831                 break;
02832             
02833             if (!getfilecreator (&fs, &creator))
02834                 break;
02835             
02836             return (setostypevalue (creator, v));
02837             }
02838             
02839         case setfilecreatedfunc: {
02840             tyfilespec fs;
02841             unsigned long when;
02842             
02843             if (!getpathvalue (hp1, 1, &fs))
02844                 break;
02845             
02846             flnextparamislast = true;
02847             
02848             if (!getdatevalue (hp1, 2, &when))
02849                 break;
02850             
02851             if (!setfilecreated (&fs, when))
02852                 break;
02853             
02854             (*v).data.flvalue = true;
02855             
02856             return (true);
02857             }
02858         
02859         case setfilemodifiedfunc: {
02860             tyfilespec fs;
02861             unsigned long when;
02862             
02863             if (!getpathvalue (hp1, 1, &fs))
02864                 break;
02865             
02866             flnextparamislast = true;
02867             
02868             if (!getdatevalue (hp1, 2, &when))
02869                 break;
02870             
02871             if (!setfilemodified (&fs, when))
02872                 break;
02873             
02874             (*v).data.flvalue = true;
02875             
02876             return (true);
02877             }
02878         
02879         case fileisfolderfunc: {
02880             tyfilespec fs;
02881             
02882             flnextparamislast = true;
02883             
02884             if (!getpathvalue (hp1, 1, &fs))
02885                 break;
02886             
02887             if (!fileisfolder (&fs, &(*v).data.flvalue))
02888                 break;
02889             
02890             return (true);
02891             }
02892         
02893         case fileisvolumefunc: {
02894             tyfilespec fs;
02895             
02896             flnextparamislast = true;
02897             
02898             if (!getpathvalue (hp1, 1, &fs)) /*was getvolumevalue*/
02899                 break;
02900             
02901             (*v).data.flvalue = fileisvolume (&fs);
02902             
02903             return (true);
02904             }
02905         
02906         case fileislockedfunc: {
02907             boolean fl;
02908             tyfilespec fs;
02909             
02910             flnextparamislast = true;
02911             
02912             if (!getpathvalue (hp1, 1, &fs))
02913                 break;
02914             
02915             if (fileisvolume (&fs))
02916                 fl = isvolumelocked (&fs, &(*v).data.flvalue);
02917             else
02918                 fl = fileislocked (&fs, &(*v).data.flvalue);
02919             
02920             if (!fl)
02921                 break;
02922             
02923             return (true);
02924             }
02925         
02926         case fileisbusyfunc: {
02927             tyfilespec fs;
02928             
02929             flnextparamislast = true;
02930             
02931             if (!getpathvalue (hp1, 1, &fs))
02932                 break;
02933             
02934             if (!fileisbusy (&fs, &(*v).data.flvalue))
02935                 break;
02936             
02937             return (true);
02938             }
02939         
02940         case filehasbundlefunc: {
02941             tyfilespec fs;
02942             
02943             flnextparamislast = true;
02944             
02945             if (!getpathvalue (hp1, 1, &fs))
02946                 break;
02947             
02948             if (!filehasbundle (&fs, &(*v).data.flvalue))
02949                 break;
02950             
02951             return (true);
02952             }
02953         
02954         case filesetbundlefunc: {
02955             tyfilespec fs;
02956             boolean flbundle;
02957             boolean flfolder;
02958             
02959             if (!getpathvalue (hp1, 1, &fs))
02960                 break;
02961             
02962             flnextparamislast = true;
02963             
02964             if (!getbooleanvalue (hp1, 2, &flbundle))
02965                 break;
02966             
02967             if (!fileisfolder (&fs, &flfolder))
02968                 break;
02969             
02970             if (!flfolder) {
02971                 
02972                 if (!filesetbundle (&fs, flbundle))
02973                     break;
02974                 
02975                 (*v).data.flvalue = true;
02976                 }
02977             
02978             return (true);
02979             }
02980         
02981         case fileisaliasfunc: {
02982             tyfilespec fs;
02983             
02984             flnextparamislast = true;
02985             
02986             if (!getpathvalue (hp1, 1, &fs))
02987                 break;
02988             
02989             if (!fileisalias (&fs, &(*v).data.flvalue))
02990                 break;
02991             
02992             return (true);
02993             }
02994         
02995         case fileisvisiblefunc: {
02996             tyfilespec fs;
02997             
02998             flnextparamislast = true;
02999             
03000             if (!getpathvalue (hp1, 1, &fs))
03001                 break;
03002             
03003             if (!fileisvisible (&fs, &(*v).data.flvalue))
03004                 break;
03005             
03006             return (true);
03007             }
03008         
03009         case filesetvisiblefunc: {
03010             tyfilespec fs;
03011             boolean flvisible;
03012             
03013             if (!getpathvalue (hp1, 1, &fs))
03014                 break;
03015             
03016             flnextparamislast = true;
03017             
03018             if (!getbooleanvalue (hp1, 2, &flvisible))
03019                 break;
03020             
03021             if (!filesetvisible (&fs, flvisible))
03022                 break;
03023             
03024             (*v).data.flvalue = true;
03025             
03026             return (true);
03027             }
03028         
03029         case filesizefunc: {
03030             tyfilespec fs;
03031             long size;
03032             
03033             flnextparamislast = true;
03034             
03035             if (!getpathvalue (hp1, 1, &fs))
03036                 break;
03037             
03038             if (!filesize (&fs, &size))
03039                 break;
03040             
03041             return (setlongvalue (size, v));
03042             }
03043         
03044         case filelockfunc: {
03045             tyfilespec fs;
03046             boolean fl;
03047             
03048             flnextparamislast = true;
03049             
03050             if (!getpathvalue (hp1, 1, &fs))
03051                 break;
03052             
03053             if (fileisvolume (&fs))
03054                 fl = lockvolume (&fs, true);
03055             else
03056                 fl = lockfile (&fs);
03057             
03058             if (!fl)
03059                 break;
03060             
03061             (*v).data.flvalue = true;
03062             
03063             return (true);
03064             }
03065             
03066         case fileunlockfunc: {
03067             tyfilespec fs;
03068             boolean fl;
03069             
03070             flnextparamislast = true;
03071             
03072             if (!getpathvalue (hp1, 1, &fs))
03073                 break;
03074             
03075             if (fileisvolume (&fs))
03076                 fl = lockvolume (&fs, false);
03077             else
03078                 fl = unlockfile (&fs);
03079             
03080             if (!fl)
03081                 break;
03082             
03083             (*v).data.flvalue = true;
03084             
03085             return (true);
03086             }
03087             
03088         case filefullpathfunc: {
03089             tyfilespec fs;
03090             
03091             flnextparamislast = true;
03092             
03093             if (!getpathvalue (hp1, 1, &fs))
03094                 break;
03095             
03096             /*getfullfilepath*/
03097             
03098             return (setfilespecvalue (&fs, v));
03099             }
03100         
03101         case filecopyfunc:
03102             return (copyfileverb (true, true, hp1, v));
03103         
03104         case filecopydataforkfunc:
03105             return (copyfileverb (true, false, hp1, v));
03106         
03107         case filecopyresourceforkfunc:
03108             return (copyfileverb (false, true, hp1, v));
03109             
03110         case filedeletefunc: {
03111             tyfilespec fs;
03112             
03113             flnextparamislast = true;
03114             
03115             if (!getpathvalue (hp1, 1, &fs))
03116                 break;
03117             
03118             if (!deletefile (&fs))
03119                 break;
03120             
03121             (*v).data.flvalue = true;
03122             
03123             return (true);
03124             }
03125         
03126         case fileexistsfunc: {
03127             boolean fl;
03128             tyfilespec fs;
03129             boolean flfolder;
03130             
03131             if (!langcheckparamcount (hp1, 1))
03132                 break;
03133             
03134             disablelangerror ();
03135             
03136             fl = getpathvalue (hp1, 1, &fs);
03137             
03138             enablelangerror ();
03139             
03140             (*v).data.flvalue = fl && fileexists (&fs, &flfolder);
03141             
03142             return (true);
03143             }
03144         
03145         case filefrompathfunc:
03146             return (filefrompathverb (hp1, v));
03147         
03148         case filegetpathfunc: {
03149             tyfilespec fs;
03150             
03151             if (!langcheckparamcount (hp1, 0)) /*no parameters expected*/
03152                 break;
03153             
03154             if (!filegetdefaultpath (&fs))
03155                 break;
03156             
03157             return (setfilespecvalue (&fs, v));
03158             }
03159             
03160         case filesetpathfunc: {
03161             tyfilespec fs;
03162             
03163             flnextparamislast = true;
03164             
03165             if (!getpathvalue (hp1, 1, &fs))
03166                 break;
03167             
03168             if (!filesetdefaultpath (&fs))
03169                 break;
03170 
03171             (*v).data.flvalue = true;
03172             
03173             return (true);
03174             }
03175         
03176         case newfunc: {
03177             tyfilespec fs;
03178             boolean flfolder;
03179             
03180             flnextparamislast = true;
03181             
03182             if (!getpathvalue (hp1, 1, &fs))
03183                 break;
03184             
03185             if (fileexists (&fs, &flfolder)) { /*8/25/92 dmb*/
03186                 
03187                 if (!deletefile (&fs))
03188                     break;
03189                 }
03190             
03191             if (!newfile (&fs, '\?\?\?\?', '\?\?\?\?'))
03192                 break;
03193             
03194             (*v).data.flvalue = true;
03195             
03196             return (true);
03197             }
03198         
03199         case newfolderfunc: {
03200             tyfilespec fs;
03201             
03202             flnextparamislast = true;
03203             
03204             if (!getpathvalue (hp1, 1, &fs))
03205                 break;
03206             
03207             if (!newfolder (&fs))
03208                 break;
03209             
03210             (*v).data.flvalue = true;
03211             
03212             return (true);
03213             }
03214         
03215         case filerenamefunc: {
03216             tyfilespec fs;
03217             bigstring bs;
03218             
03219             if (!getpathvalue (hp1, 1, &fs)) /*bs1 holds the path*/
03220                 break;
03221             
03222             flnextparamislast = true;
03223             
03224             if (!getstringvalue (hp1, 2, bs)) /*bs2 holds the new name*/
03225                 break;
03226             
03227             /*
03228             if (fileisvolume (bs1))
03229                 (*v).data.flvalue = renamevolume (bs1, bs2);
03230             else
03231             */
03232             
03233             if (!renamefile (&fs, bs))
03234                 break;
03235             
03236             (*v).data.flvalue = true;
03237             
03238             return (true);
03239             }
03240         
03241         case filemovefunc: {
03242             tyfilespec fs1, fs2;
03243             
03244             if (!getpathvalue (hp1, 1, &fs1)) /*bs1 holds the path*/
03245                 break;
03246             
03247             flnextparamislast = true;
03248             
03249             if (!getpathvalue (hp1, 2, &fs2)) /*bs2 holds the new name*/
03250                 break;
03251             
03252             if (!movefile (&fs1, &fs2))
03253                 break;
03254             
03255             (*v).data.flvalue = true;
03256             
03257             return (true);
03258             }
03259         
03260         /*
03261         case filesinfolder: {
03262             tyfilespec fs;
03263             long ctfiles;
03264             
03265             flnextparamislast = true;
03266             
03267             if (!getpathvalue (hp1, 1, &fs))
03268                 break;
03269             
03270             if (!filesinfolder (&fs, &ctfiles))
03271                 break;
03272             
03273             return (setlongvalue (ctfiles, v));
03274             }
03275         */
03276         
03277         case sfgetfilefunc:
03278             return (filedialogverb (sfgetfileverb, hp1, v));
03279         
03280         case sfputfilefunc:
03281             return (filedialogverb (sfputfileverb, hp1, v));
03282         
03283         case sfgetfolderfunc:
03284             return (filedialogverb (sfgetfolderverb, hp1, v));
03285         
03286         case sfgetdiskfunc:
03287             return (filedialogverb (sfgetdiskverb, hp1, v));
03288         
03289         /*
03290         case fileeditlinefeedsfunc:
03291             return (editlinefeedsverb (hp1, v));
03292         */
03293         
03294         case volumeisejectablefunc: {
03295             tyfilespec fs;
03296             
03297             flnextparamislast = true;
03298             
03299             if (!getvolumevalue (hp1, 1, &fs))
03300                 break;
03301             
03302             return (isejectable (&fs, &(*v).data.flvalue)); 
03303             }
03304 
03305 
03306         case volumefreespacefunc: {
03307             tyfilespec fs;
03308             long ctbytes;
03309             
03310             flnextparamislast = true;
03311             
03312             if (!getvolumevalue (hp1, 1, &fs))
03313                 break;
03314             
03315             if (!getfreespace (&fs, &ctbytes))
03316                 break;
03317 
03318             return (setlongvalue (ctbytes, v));
03319             }
03320         
03321 
03322         case volumesizefunc: {
03323             tyfilespec fs;
03324             long ctbytes;
03325             
03326             flnextparamislast = true;
03327             
03328             if (!getvolumevalue (hp1, 1, &fs))
03329                 break;
03330 
03331             if (!getvolumesize (&fs, &ctbytes))
03332                 break;
03333             
03334             return (setlongvalue (ctbytes, v));
03335             }
03336         
03337 
03338         case volumefreespacedoublefunc: { /*6.1b16 AR*/
03339             tyfilespec fs;
03340             double totalbytes, freebytes;
03341             
03342             flnextparamislast = true;
03343             
03344             if (!getvolumevalue (hp1, 1, &fs))
03345                 break;
03346             
03347             if (!langgetextendedvolumeinfo (&fs, &totalbytes, &freebytes))
03348                 break;
03349 
03350             return (setdoublevalue (freebytes, v));
03351             }
03352         
03353 
03354         case volumesizedoublefunc: { /*6.1b16 AR*/
03355             tyfilespec fs;
03356             double totalbytes, freebytes;
03357             
03358             flnextparamislast = true;
03359             
03360             if (!getvolumevalue (hp1, 1, &fs))
03361                 break;
03362             
03363             if (!langgetextendedvolumeinfo (&fs, &totalbytes, &freebytes))
03364                 break;
03365 
03366             return (setdoublevalue (totalbytes, v));
03367             }
03368 
03369 
03370         case volumeblocksizefunc: {
03371             tyfilespec fs;
03372             long ctbytes;
03373             
03374             flnextparamislast = true;
03375             
03376             if (!getvolumevalue (hp1, 1, &fs))
03377                 break;
03378             
03379             if (!getvolumeblocksize (&fs, &ctbytes))
03380                 break;
03381             
03382             return (setlongvalue (ctbytes, v));
03383             }
03384         
03385         case filesonvolumefunc: {
03386             tyfilespec fs;
03387             long ctfiles;
03388             
03389             flnextparamislast = true;
03390             
03391             if (!getvolumevalue (hp1, 1, &fs))
03392                 break;
03393             
03394             if (!filesonvolume (&fs, &ctfiles))
03395                 break;
03396             
03397             return (setlongvalue (ctfiles, v));
03398             }   
03399         
03400         case foldersonvolumefunc: {
03401             tyfilespec fs;
03402             long ctfolders;
03403             
03404             flnextparamislast = true;
03405             
03406             if (!getvolumevalue (hp1, 1, &fs))
03407                 break;
03408             
03409             if (!foldersonvolume (&fs, &ctfolders))
03410                 break;
03411             
03412             return (setlongvalue (ctfolders, v));
03413             }
03414         
03415         
03416         /* 11/7/91 dmb: now called from shellsysverbs.c
03417         case filelaunchfunc:
03418             return (filelaunchanythingverb (hp1, v));
03419         */
03420         
03421         /*start of new verbs added by DW, 7/27/91*/
03422         
03423         case findinfilefunc:
03424             return (findfileverb (hp1, v));
03425         
03426         case countlinesfunc:
03427             return (countlinesverb (hp1, v));
03428         
03429         case openfilefunc:
03430             return (openfileverb (hp1, v));
03431         
03432         case closefilefunc:
03433             return (closefileverb (hp1, v));
03434         
03435         case endoffilefunc:
03436             return (endoffileverb (hp1, v));
03437         
03438         case setendoffilefunc:
03439             return (setendoffileverb (hp1, v));
03440         
03441         case getendoffilefunc:
03442             return (getendoffileverb (hp1, v));
03443 
03444         case setpositionfunc:
03445             return (setpositionverb (hp1, v));
03446 
03447         case getpositionfunc:
03448             return (getpositionverb (hp1, v));
03449 
03450         case readlinefunc:
03451             return (readlineverb (hp1, v));
03452         
03453         case writelinefunc:
03454             return (writelineverb (hp1, v));
03455         
03456         case readfunc:
03457             return (readverb (hp1, v));
03458         
03459         case writefunc:
03460             return (writeverb (hp1, v));
03461         
03462         case comparefunc:
03463             return (comparefilesverb (hp1, v));
03464     
03465         /*end of new verbs added by DW, 7/27/91*/
03466         
03467         //case writewholefilefunc:
03468         //  return (writewholefileverb (hp1, v));
03469         
03470         case getpathcharfunc:
03471             if (!langcheckparamcount (hp1, 0))
03472                 return (false);
03473             
03474             #ifdef MACVERSION
03475                 return (setstringvalue (BIGSTRING ("\x01" ":"), v));
03476             #endif
03477             #ifdef WIN95VERSION
03478                 return (setstringvalue (BIGSTRING ("\x01" "\\"), v));
03479             #endif
03480         
03481         case getshortversionfunc: 
03482             return (getshortversionverb (hp1, v));
03483 
03484         case getlongversionfunc: 
03485             return (getlongversionverb (hp1, v));
03486         
03487         case filegetcommentfunc:
03488             return (getcommentverb (hp1, v));
03489         
03490         case filefindappfunc:
03491             return (findapplicationverb (hp1, v));
03492 
03493         /* 3/20/97 - The following are MAC speciifc verbs and are therefore grouped
03494             together here for ease of ifdefing */
03495 
03496     #ifdef MACVERSION
03497         case newaliasfunc:
03498             return (newaliasverb (hp1, v));
03499         
03500         case filefollowaliasfunc:
03501             return (followaliasverb (hp1, v));
03502         
03503         case filegeticonposfunc:
03504             return (geticonposverb (hp1, v));
03505         
03506         case fileseticonposfunc: 
03507             return (seticonposverb (hp1, v));
03508                 
03509         case setshortversionfunc: 
03510             return (setshortversionverb (hp1, v));
03511         
03512         case setlongversionfunc: 
03513             return (setlongversionverb (hp1, v));
03514         
03515         case filesetcommentfunc:
03516             return (setcommentverb (hp1, v));
03517         
03518         case filegetlabelfunc:
03519             return (getlabelverb (hp1, v));
03520         
03521         case filesetlabelfunc:
03522             return (setlabelverb (hp1, v));
03523         
03524         case unmountvolumefunc: {
03525             tyfilespec fs;
03526             
03527             flnextparamislast = true;
03528             
03529             if (!getvolumevalue (hp1, 1, &fs))
03530                 break;
03531             
03532             if (!unmountvolume (&fs))
03533                 break;
03534             
03535             return (setbooleanvalue (true, v));
03536             }
03537         
03538         #if TARGET_API_MAC_CARBON != 1 /*7.0B59 PBS: not implemented in OS X yet*/
03539         
03540             case mountservervolumefunc: {
03541                 bigstring bsvol, bsuser, bspassword;
03542                 
03543                 if (!getstringvalue (hp1, 1, bsvol))
03544                     break;
03545                 
03546                 if (!getstringvalue (hp1, 2, bsuser))
03547                     break;
03548                 
03549                 flnextparamislast = true;
03550                 
03551                 if (!getstringvalue (hp1, 3, bspassword))
03552                     break;
03553                 
03554                 if (countwords (bsvol, chpathseparator) != 3) {
03555                     
03556                     langparamerror (badnetworkvolumespecificationerror, bsvol);
03557                     
03558                     return (false);
03559                     }
03560                 
03561                 if (!mountvolume (bsvol, bsuser, bspassword))
03562                     break;
03563                 
03564                 return (setbooleanvalue (true, v));
03565                 }
03566         #endif
03567         
03568         case volumeejectfunc: {
03569             tyfilespec fs;
03570             
03571             flnextparamislast = true;
03572             
03573             if (!getvolumevalue (hp1, 1, &fs))
03574                 break;
03575             
03576             (*v).data.flvalue = ejectvol (&fs);
03577             
03578             return (true);
03579             }
03580             
03581         case setfiletypefunc: {
03582             tyfilespec fs;
03583             OSType type;
03584             
03585             if (!getpathvalue (hp1, 1, &fs))
03586                 break;
03587             
03588             flnextparamislast = true;
03589             
03590             if (!getostypevalue (hp1, 2, &type))
03591                 break;
03592             
03593             if (!setfiletype (&fs, type))
03594                 break;
03595             
03596             (*v).data.flvalue = true;
03597             
03598             return (true);
03599             }
03600         
03601         case setfilecreatorfunc: {
03602             tyfilespec fs;
03603             OSType creator;
03604             
03605             if (!getpathvalue (hp1, 1, &fs))
03606                 break;
03607             
03608             flnextparamislast = true;
03609             
03610             if (!getostypevalue (hp1, 2, &creator))
03611                 break;
03612             
03613             if (!setfilecreator (&fs, creator))
03614                 break;
03615             
03616             (*v).data.flvalue = true;
03617             
03618             return (true);
03619             }
03620             
03621         case getlabelindexfunc: /* 2006-04-24 creedon */
03622             return (getlabelindexverb (hp1, v));
03623         
03624         case setlabelindexfunc: /* 2006-04-24 creedon */
03625             return (setlabelindexverb (hp1, v));
03626         
03627         case getlabelnamesfunc: /* 2006-04-24 creedon */
03628             return (getlabelnamesverb (hp1, v));
03629     #endif
03630 
03631         case folderfrompathfunc:
03632             return (folderfrompathverb (hp1, v));
03633         
03634 
03635         case getsystempathfunc: {
03636             byte bsvol [258];       /*2*/
03637             byte bsfolder [258]; /*6*/
03638             tyfilespec fs;
03639             
03640             if (!langcheckparamcount (hp1, 0)) /*no parameters expected*/
03641                 break;
03642             
03643             #ifdef flsystem6
03644                 filegetpath (filegetsystemvnum (), bs);
03645                 return (setstringvalue (bs, v));
03646             #else
03647             
03648             setemptystring (bsvol);
03649             
03650             #ifdef MACVERSION
03651             
03652                 #if TARGET_API_MAC_CARBON == 1
03653                     ostypetostring ('pref', bsfolder);
03654                 #else
03655                     ostypetostring ('macs', bsfolder);
03656                 #endif
03657                 
03658             #endif
03659                 
03660             #ifdef WIN95VERSION
03661                 copyctopstring ("SYSTEM", bsfolder);
03662             #endif
03663             
03664             if (!getspecialfolderpath (bsvol, bsfolder, false, &fs))
03665                 break;
03666             
03667             return (setfilespecvalue (&fs, v));
03668             
03669             #endif
03670             
03671             }
03672         
03673         case getspecialpathfunc: {
03674             bigstring bsvol, bsfolder;
03675             tyfilespec fs;
03676             boolean flcreate;
03677             
03678             if (!getstringvalue (hp1, 1, bsvol))
03679                 break;
03680             
03681             if (!getstringvalue (hp1, 2, bsfolder)) 
03682                 break;
03683             
03684             flnextparamislast = true;
03685             
03686             if (!getbooleanvalue (hp1, 3, &flcreate))
03687                 break;
03688             
03689             if (!getspecialfolderpath (bsvol, bsfolder, flcreate, &fs))
03690                 break;
03691             
03692             return (setfilespecvalue (&fs, v));
03693             }
03694         
03695         case getmp3infofunc: {
03696             
03697             long seconds, bitrate, frequency, offset;
03698             tyfilespec fs;
03699             boolean fl, flvariablebitrate;
03700             
03701             if (!langcheckparamcount (hparam1, 6)) /*preflight before changing values*/
03702                 return (false);
03703 
03704             if (!getpathvalue (hp1, 1, &fs))
03705                 return (false);
03706             
03707             if (!fifopenfile (&fs, (long) currentprocess))
03708                 return (false);
03709             
03710             fl = getmp3info (&fs, &seconds, &bitrate, &frequency, &offset, &flvariablebitrate);
03711 
03712             if (!fifclosefile (&fs))
03713                 return (false);
03714             
03715             if (!fl)
03716                 return (false);
03717             
03718             if (!langsetlongvarparam (hp1, 2, seconds))
03719                 return (false);
03720             
03721             if (!langsetlongvarparam (hp1, 3, bitrate))
03722                 return (false);
03723             
03724             if (!langsetlongvarparam (hp1, 4, frequency))
03725                 return (false);
03726             
03727             if (!langsetlongvarparam (hp1, 5, offset))
03728                 return (false);
03729             
03730             if (!langsetbooleanvarparam (hp1, 6, flvariablebitrate))
03731                 return (false);
03732             
03733             return (true);
03734             }
03735         
03736         case readwholefilefunc: /* 2006-04-11 aradke */
03737             return (readwholefileverb (hparam1, v));
03738     
03739         #ifdef WIN95VERSION
03740             case newaliasfunc:
03741             case filefollowaliasfunc:
03742             case filegeticonposfunc:
03743             case fileseticonposfunc: 
03744             case setshortversionfunc: 
03745             case setlongversionfunc: 
03746             case filesetcommentfunc:
03747             case filegetlabelfunc:
03748             case filesetlabelfunc:
03749             case unmountvolumefunc:     
03750             case mountservervolumefunc:
03751             case volumeejectfunc:
03752             case setfiletypefunc:
03753             case setfilecreatorfunc:
03754         #endif
03755         default:
03756             getstringlist (langerrorlist, unimplementedverberror, bserror);
03757             
03758             break;
03759         } /*switch*/
03760     
03761     return (false);
03762     } /*filefunctionvalue*/
03763 
03764 
03765 static boolean rezfunctionvalue (short token, hdltreenode hparam1, tyvaluerecord *vreturned, bigstring bserror) {
03766     
03767     register hdltreenode hp1 = hparam1;
03768     register tyvaluerecord *v = vreturned;
03769     
03770     setbooleanvalue (false, v); /*by default, rez functions return false*/
03771     
03772     switch (token) {
03773 #ifdef MACVERSION
03774         case rezgetresourcefunc: 
03775             return (getresourceverb (hp1, false, v));
03776         
03777         case rezputresourcefunc: 
03778             return (putresourceverb (hp1, false, v));
03779         
03780         case rezgetnamedresourcefunc: 
03781             return (getresourceverb (hp1, true, v));
03782         
03783         case rezputnamedresourcefunc: 
03784             return (putresourceverb (hp1, true, v));
03785         
03786         case rezcountrestypesfunc:
03787             return (countrestypesverb (hp1, v));
03788         
03789         case rezgetnthrestypefunc:
03790             return (getnthrestypeverb (hp1, v));
03791         
03792         case rezcountresourcesfunc:
03793             return (countresourcesverb (hp1, v));
03794         
03795         case rezgetnthresourcefunc:
03796             return (getnthresourceverb (hp1, v));
03797         
03798         case rezgetnthresinfofunc:
03799             return (getnthresinfoverb (hp1, v));
03800         
03801         case rezresourceexistsfunc:
03802             return (resourceexistsverb (hp1, false, v));
03803         
03804         case reznamedresourceexistsfunc:
03805             return (resourceexistsverb (hp1, true, v));
03806         
03807         case rezdeleteresourcefunc:
03808             return (deleteresourceverb (hp1, false, v));
03809         
03810         case rezdeletenamedresourcefunc:
03811             return (deleteresourceverb (hp1, true, v));
03812         
03813         case rezgetresourceattrsfunc:
03814             return (getresourceattrsverb (hp1, false, v));
03815         
03816         case rezsetresourceattrsfunc:
03817             return (setresourceattrsverb (hp1, false, v));
03818 #endif      
03819         default:
03820             getstringlist (langerrorlist, unimplementedverberror, bserror);
03821             
03822             break;
03823         } /*switch*/
03824     
03825     return (false);
03826     } /*rezfunctionvalue*/
03827 
03828 
03829 boolean fileinitverbs (void) {
03830     
03831     /*
03832     if you just changed or added some definitions in fileinitbuiltins, call
03833     fileinstallbuiltins here.  rebuild, run the program, come back and change
03834     it to fileloadbuiltins, rebuild and go on...
03835     
03836     12/18/90 dmb: no longer save hash tables in program file, so we just 
03837     initialize the builtins directly.
03838     
03839     10/2/91 dmb: broke out resource verb into rez table
03840     
03841     2.1b5 dmb: use new loadfunctionprocessor verb
03842     */
03843     
03844     if (!loadfunctionprocessor (idfileverbs, &filefunctionvalue))
03845         return (false);
03846     
03847     if (!loadfunctionprocessor (idrezverbs, &rezfunctionvalue))
03848         return (false);
03849     
03850     return (true);
03851     } /*fileinitverbs*/
03852 
03853 
03854 
03855 boolean filestart (void) {
03856 
03857     /*
03858     6.1b15 AR: Initialize flsupportslargevolumes.
03859 
03860     Windows 95 OSR2: The GetDiskFreeSpaceEx function is available on Windows 95 systems
03861     beginning with OEM Service Release 2 (OSR2). 
03862 
03863     To determine whether GetDiskFreeSpaceEx is available, call the LoadLibrary
03864     or LoadLibraryEx function to load the KERNEL32.DLL file, then call the
03865     GetProcAddress function to obtain an address for GetDiskFreeSpaceEx.
03866     If GetProcAddress fails, or if GetDiskFreeSpaceEx fails with the
03867     ERROR_CALL_NOT_IMPLEMENTED code, use the GetDiskFreeSpace function
03868     instead of GetDiskFreeSpaceEx
03869     */
03870     
03871 #ifdef WIN95VERSION
03872     
03873     HMODULE hmodule;
03874 
03875     char kerneldllname[] = "kernel32.dll\0";
03876     char procname[] = "GetDiskFreeSpaceExA\0";
03877 
03878     hmodule = GetModuleHandle (kerneldllname);
03879  
03880     if (hmodule != nil) {
03881     
03882         adrGetDiskFreeSpaceEx = (tyGetDiskFreeSpaceEx) GetProcAddress (hmodule, procname);
03883 
03884         if (adrGetDiskFreeSpaceEx != NULL)
03885             flsupportslargevolumes = true;
03886         }
03887 #endif
03888 
03889     return (true);
03890     }/*filestart*/

Generated on Wed May 31 18:19:47 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6