home *** CD-ROM | disk | FTP | other *** search
/ MacGames Sampler / PHT MacGames Bundle.iso / MacSource Folder / Samples from the CD / Editors / emacs / Emacs-1.14b1-sources / sources / unix-emulation-src / files.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-30  |  9.3 KB  |  376 lines  |  [TEXT/EMAC]

  1. /*
  2.  * Copyright (C) 1993, 1994 Marc Parmet.
  3.  * This file is part of the Macintosh port of GNU Emacs.
  4.  *
  5.  * GNU Emacs is distributed in the hope that it will be useful,
  6.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  8.  * GNU General Public License for more details.
  9.  */
  10.  
  11. #if defined(THINK_C)
  12. #include <MacHeaders>
  13. #else
  14. #include <Types.h>
  15. #include <Memory.h>
  16. #include <Quickdraw.h>
  17. #include <Windows.h>
  18. #include <Errors.h>
  19. #endif
  20.  
  21. #include <AppleEvents.h>
  22. #include <AERegistry.h>
  23. #include <Aliases.h>
  24. #include <Script.h>
  25. #include <Folders.h>
  26. #include "sys/unistd.h"
  27. #include "sys/file.h"
  28. #include "sys/stat.h"
  29. #include "errno.h"
  30. #include "utime.h"
  31.  
  32. static int
  33. rename_specs(FSSpec *old_spec,FSSpec *new_spec)
  34. {
  35.     short err;
  36.     FSSpec temp_spec;
  37.     static unsigned char tempname[] = "\p##temp##";
  38.  
  39.     if (old_spec->vRefNum != new_spec->vRefNum) return diffVolErr;
  40.     if (old_spec->parID == new_spec->parID) {
  41.         err = FSpRename(old_spec,new_spec->name);
  42.         return err;
  43.     }
  44.     else {
  45.         err = FSpRename(old_spec,tempname);
  46.         if (err) return err;
  47.         err = FSMakeFSSpec(old_spec->vRefNum,old_spec->parID,tempname,&temp_spec);
  48.         if (err) return err;
  49.         err = CatMove(temp_spec.vRefNum,temp_spec.parID,temp_spec.name,new_spec->parID,(ConstStr255Param)"\p");
  50.         if (err) return err;
  51.         err = FSMakeFSSpec(new_spec->vRefNum,new_spec->parID,tempname,&temp_spec);
  52.         if (err) return err;
  53.         err = FSpRename(&temp_spec,new_spec->name);
  54.         return err;
  55.     }
  56. }
  57.  
  58. int
  59. symlink_internal(char *target,char *linkname)
  60. {
  61.     unsigned char s[256];
  62.     CInfoPBRec pb;
  63.     long desk_dirID;
  64.     int retcode = -1;
  65.     AEDesc targetAppl;
  66.     short err,desk_vRefNum;
  67.     AppleEvent event,reply;
  68.     AEDescList selectionList;
  69.     extern pascal short ae_send_idle_function();
  70.     static AEIdleUPP ae_send_idle_function_upp;
  71.     AliasHandle target_alias = 0L,target_parent_alias = 0L;
  72.     int have_targetAppl = 0,have_event = 0,have_selectionList = 0;
  73.     FSSpec target_spec,linkname_spec,target_parent_spec,alias_spec;
  74.     
  75.     if (ae_send_idle_function_upp == 0L)
  76.         ae_send_idle_function_upp = NewAEIdleProc(ae_send_idle_function);
  77.     
  78.     err = unixfn2FSSpec_internal(target,&target_spec,0);
  79.     if (err) goto error;
  80.     if (target_spec.parID == fsRtParID)
  81.         target_parent_spec = target_spec;
  82.     else {
  83.         pb.dirInfo.ioNamePtr = s;
  84.         pb.dirInfo.ioFDirIndex = -1;
  85.         pb.dirInfo.ioVRefNum = target_spec.vRefNum;
  86.         pb.dirInfo.ioDrDirID = target_spec.parID;
  87.         err = PBGetCatInfo(&pb,0);
  88.         if (err) goto error;
  89.         err = FSMakeFSSpec(target_spec.vRefNum,pb.dirInfo.ioDrParID,s,&target_parent_spec);
  90.         if (err) goto error;
  91.     }
  92.     err = unixfn2FSSpec_internal(linkname,&linkname_spec,0);
  93.     if (err && err != fnfErr) goto error;
  94.     if (err == noErr) { set_errno(EEXIST); return -1; }
  95.  
  96.     // Create the alias.
  97.     err = NewAlias(0L,&target_parent_spec,&target_parent_alias);
  98.     if (err) goto error;
  99.     err = NewAliasMinimal(&target_spec,&target_alias);
  100.     if (err) goto error;
  101.     
  102.     err = AECreateDesc(typeApplSignature,"MACS",sizeof(long),&targetAppl);
  103.     if (err) goto error;
  104.     have_targetAppl = 1;
  105.     err = AECreateAppleEvent(kAEFinderEvents,kAEAliasSelection,&targetAppl,
  106.                              kAutoGenerateReturnID,kAnyTransactionID,&event);
  107.     if (err) goto error;
  108.     have_event = 1;
  109.     HLock((Handle)target_parent_alias);
  110.     err = AEPutParamPtr(&event,keyDirectObject,typeAlias,*target_parent_alias,
  111.                         (**target_parent_alias).aliasSize);
  112.     if (err) goto error;
  113.     err = AECreateList(0,0,0,&selectionList);
  114.     if (err) goto error;
  115.     have_selectionList = 1;
  116.     HLock((Handle)target_alias);
  117.     err = AEPutPtr(&selectionList,0,typeAlias,*target_alias,(**target_alias).aliasSize);
  118.     if (err) goto error;
  119.     err = AEPutParamDesc(&event,keySelection,&selectionList);
  120.     if (err) goto error;
  121.     err = AESend(&event,&reply,kAENeverInteract | kAEWaitReply,kAENormalPriority,
  122.                  kAEDefaultTimeout,ae_send_idle_function_upp,0L);
  123.     if (err) goto error;
  124.     
  125.     // Have the alias, now move it and rename it.
  126.     // We have to guess where the new alias is and what it's called.
  127.     if (target_spec.parID == fsRtParID) {
  128.         err = FindFolder(target_spec.vRefNum,'desk',0,&desk_vRefNum,&desk_dirID);
  129.         if (err) goto error;
  130.         pstrcpy(s,target_spec.name);
  131.         pstrcat(s,"\p alias");
  132.         err = FSMakeFSSpec(desk_vRefNum,desk_dirID,s,&alias_spec);
  133.         if (err) goto error;
  134.     }
  135.     else {
  136.         pstrcpy(s,target_spec.name);
  137.         pstrcat(s,"\p alias");
  138.         err = FSMakeFSSpec(target_spec.vRefNum,target_spec.parID,s,&alias_spec);
  139.         if (err) goto error;
  140.     }
  141.  
  142.     err = rename_specs(&alias_spec,&linkname_spec);
  143.     if (err) goto error;
  144.  
  145.     retcode = 0;
  146.  
  147.     error:
  148.     if (target_alias != 0L) DisposHandle((Handle)target_alias);
  149.     if (target_parent_alias != 0L) DisposHandle((Handle)target_parent_alias);
  150.     if (have_targetAppl) AEDisposeDesc(&targetAppl);
  151.     if (have_event) AEDisposeDesc(&event);
  152.     if (have_selectionList) AEDisposeDesc(&selectionList);
  153.     set_errno(err);
  154.     return retcode;
  155. }
  156.  
  157. int
  158. access_internal(char *filename,int mode)
  159. {
  160.     struct stat st;
  161.     int err,check_lock;
  162.     
  163.     switch (mode) {
  164.     case F_OK:
  165.     case R_OK:
  166.     case X_OK:
  167.         check_lock = 0;
  168.         break;
  169.     case W_OK:
  170.         check_lock = 1;
  171.         break;
  172.     default:
  173.         set_errno(EINVAL);
  174.         return -1;
  175.     }
  176.  
  177.     err = stat_internal(filename,&st,0);
  178.     if (err) return err;
  179.     if (!check_lock) return 0;
  180.     if (st.st_mode & 0200) return 0;
  181.     set_errno(EACCES);
  182.     return -1;
  183. }
  184.  
  185. int
  186. unlink_internal(char *s)
  187. {
  188.     short err;
  189.     FSSpec spec;
  190.  
  191.     // This works for files and empty folders, and fortunately fails for volumes.
  192.     err = unixfn2FSSpec_internal(s,&spec,1);
  193.     if (err) { set_errno(err); return -1; }
  194.     err = FSpDelete(&spec);
  195.     if (err) { set_errno(err); return -1; }
  196.     return 0;
  197. }
  198.  
  199. int
  200. rename_internal(char *old,char *new)
  201. {
  202.     short err;
  203.     FSSpec old_spec,new_spec;
  204.     
  205.     err = unixfn2FSSpec_internal(old,&old_spec,1);
  206.     if (err) { set_errno(err); return -1; }
  207.     err = unixfn2FSSpec_internal(new,&new_spec,0);
  208.     if (err && err != fnfErr) { set_errno(err); return -1; }
  209.     err = rename_specs(&old_spec,&new_spec);
  210.     if (err) { set_errno(err); return -1; }
  211.     return 0;
  212. }
  213.  
  214. int
  215. readlink_internal(char *linkname,char *target,int n)
  216. {
  217.     int err,len;
  218.     FSSpec spec;
  219.     static Handle s;
  220.     Boolean isFolder,wasAliased;
  221.     
  222.     if (s) { DisposHandle(s); s = 0L; }
  223.     
  224.     // If the filename is not a link, return -1.
  225.     err = unixfn2FSSpec_internal(linkname,&spec,1);
  226.     if (err) { set_errno(err); return -1; }
  227.     err = ResolveAliasFile(&spec,0,&isFolder,&wasAliased);
  228.     if (err) { set_errno(err); return -1; }
  229.     if (!wasAliased) { set_errno(EUNDOC); return -1; }
  230.  
  231.     err = unixfn2FSSpec_internal(linkname,&spec,0);
  232.     if (err) { set_errno(err); return -1; }
  233.     err = FSSpec2unixfn_internal(&spec,&s);
  234.     if (err) { set_errno(err); return -1; }
  235.     HLock(s);
  236.     len = strlen(*s);
  237.     if (len >= n) {
  238.         memcpy(target,*s,n-1);
  239.         target[n-1] = '\0';
  240.     }
  241.     else {
  242.         memcpy(target,*s,len);
  243.         target[len] = '\0';
  244.     }
  245.     HUnlock(s);
  246.     return strlen(target);
  247. }
  248.  
  249. int
  250. mkdir_internal(char *name,int mode)
  251. {
  252.     short err;
  253.     FSSpec spec;
  254.     long newDirID;
  255.  
  256.     err = unixfn2FSSpec_internal(name,&spec,0);
  257.     if (err == noErr) { set_errno(EEXIST); return -1; }
  258.     if (err != fnfErr) { set_errno(err); return -1; }
  259.     
  260.     err = FSpDirCreate(&spec,smSystemScript,&newDirID);
  261.     if (err) { set_errno(err); return -1; }
  262.     return 0;
  263. }
  264.  
  265. int
  266. rmdir_internal(char *name)
  267. {
  268.     short err;
  269.     FSSpec spec;
  270.     CInfoPBRec pb;
  271.  
  272.     err = unixfn2FSSpec_internal(name,&spec,0);
  273.     if (err) { set_errno(err); return -1; }
  274.  
  275.     // Make sure it's a directory.
  276.     pb.dirInfo.ioFDirIndex = 0;
  277.     pb.dirInfo.ioNamePtr = spec.name;
  278.     pb.dirInfo.ioVRefNum = spec.vRefNum;
  279.     pb.dirInfo.ioDrDirID = spec.parID;
  280.     err = PBGetCatInfo(&pb,0);
  281.     if (err) { set_errno(err); return -1; }
  282.     if (!(pb.dirInfo.ioFlAttrib & 0x10)) { set_errno(ENOTDIR); return -1; }
  283.     
  284.     err = FSpDelete(&spec);
  285.     if (err == fBsyErr) { set_errno(EDIRNE); return -1; }
  286.     if (err) { set_errno(err); return -1; }
  287.     return 0;
  288. }
  289.  
  290. int
  291. utime_internal(char *name,struct utimbuf *time)
  292. {
  293.     short err;
  294.     FSSpec spec;
  295.     CInfoPBRec pb;
  296.     unsigned long modtime;
  297.     long actime;
  298.  
  299.     if (time != 0L) {
  300.         modtime = time->modtime;
  301.         actime = time->actime;
  302.     }
  303.     else {
  304.         GetDateTime(&modtime);
  305.         actime = modtime;
  306.     }
  307.  
  308.     err = unixfn2FSSpec_internal(name,&spec,1);
  309.     if (err) { set_errno(err); return -1; }
  310.  
  311.     pb.dirInfo.ioVRefNum = spec.vRefNum;
  312.     pb.dirInfo.ioDrDirID = spec.parID;
  313.     pb.dirInfo.ioNamePtr = spec.name;
  314.     pb.dirInfo.ioFDirIndex = 0;
  315.     err = PBGetCatInfo(&pb,0);
  316.     if (err) { set_errno(err); return -1; }
  317.  
  318.     pb.dirInfo.ioDrDirID = spec.parID;
  319.     if (modtime != 0) pb.dirInfo.ioDrMdDat = modtime;
  320.     if (actime != 0) pb.dirInfo.ioDrCrDat = actime;
  321.     err = PBSetCatInfo(&pb,0);
  322.     if (err) { set_errno(err); return -1; }
  323.  
  324.     return 0;
  325. }
  326.  
  327. int
  328. chmod_internal(char *filename,int mode)
  329. {
  330.     short err;
  331.     FSSpec spec;
  332.  
  333.     err = unixfn2FSSpec_internal(filename,&spec,0);
  334.     if (err) { set_errno(err); return -1; }
  335.     if (mode & 0200)
  336.         err = FSpRstFLock(&spec);
  337.     else
  338.         err = FSpSetFLock(&spec);
  339.     if (err) { set_errno(err); return -1; }
  340.     return 0;
  341. }
  342.  
  343. int
  344. chown_internal(char *filename,int own)
  345. {
  346.     short err;
  347.     FSSpec spec;
  348.     FInfo info;
  349.  
  350.     err = unixfn2FSSpec_internal(filename,&spec,0);
  351.     if (err) { set_errno(err); return -1; }
  352.     err = FSpGetFInfo(&spec,&info);
  353.     if (err) { set_errno(err); return -1; }
  354.     info.fdCreator = own;
  355.     err = FSpSetFInfo(&spec,&info);
  356.     if (err) { set_errno(err); return -1; }
  357.     return 0;
  358. }
  359.  
  360. int
  361. chgrp_internal(char *filename,int grp)
  362. {
  363.     short err;
  364.     FSSpec spec;
  365.     FInfo info;
  366.  
  367.     err = unixfn2FSSpec_internal(filename,&spec,0);
  368.     if (err) { set_errno(err); return -1; }
  369.     err = FSpGetFInfo(&spec,&info);
  370.     if (err) { set_errno(err); return -1; }
  371.     info.fdType = grp;
  372.     err = FSpSetFInfo(&spec,&info);
  373.     if (err) { set_errno(err); return -1; }
  374.     return 0;
  375. }
  376.