help-cfengine
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] OS X Resource Fork and FinderType support


From: David Botsch
Subject: [PATCH] OS X Resource Fork and FinderType support
Date: Wed, 09 Jul 2003 11:58:24 -0400
User-agent: Pan/0.11.2 (Unix)

I've created the following patch against cfengine-2.0.4 (the version we
are running here) to add support for OS X Resource Forks and for Finder
Type metadata on the HFS+ file system. Patch compiled under 10.2.6 and
tested under 10.2.6 and 10.2.5

Docs:

in the copy: section, you will need to have two separate entries. One
will be for the data fork of the file and one for the resource fork of
the file.

An example:

    $(masterfiles)/$(sys)/Applications/LaunchX11-datafork 
dest=/Applications/LaunchX11 type=sum mode=0755 owner=root group=admin 
findertype=APPL
    $(masterfiles)/$(sys)/Applications/LaunchX11-rsrcfork 
dest=/Applications/LaunchX11/..namedfork/rsrc type=sum mode=0755 owner=root 
group=admin

Two things are critical here:

1. The datafork must have already been copied over o.w. the resource fork
creation will fail. So, order is important.
2. The dest for the resource fork, as you see above, must be named
filename/..namedfork/rsrc (using the shortcut filename/rsrc will not work...
this is also deprecated from what I have read elsewhere).

To split the data forks and resource forks apart on the commandline:

cp file file-datafork
cp file/..namedfork/rsrc file-rsrcfork

You don't want to use the ._filename created when you copy a file to a non-HFS+
filesystem as this is not just the resource fork, but also the metadata. 

You will also notice in the above line the addition of a findertype=APPL line.
This allows specification of the finder metadata type code. This only works for
the data fork of a file. The type code is always 4 letters and I believe always
uppercase (I don't check case and don't if OS X cares about case of the type
code).

--------
Going on this model, adding support for finder creator codes would be
relatively easy if such a feature is requested. I don't think we need it here.

If anyone finds any bugs, let me know.

-------
the patch
--------


Common subdirectories: cfengine-2.0.4/src/.deps and cfengine-2.0.4.new/src/.deps
diff -U5 cfengine-2.0.4/src/cf.defs.h cfengine-2.0.4.new/src/cf.defs.h
--- cfengine-2.0.4/src/cf.defs.h        Tue Aug 20 10:27:39 2002
+++ cfengine-2.0.4.new/src/cf.defs.h    Mon Jun 30 16:12:00 2003
@@ -148,13 +148,17 @@
 #include <unistd.h>
 #endif
 
 #ifdef HAVE_MALLOC_H
 #ifndef OPENBSD
+#ifdef DARWIN
+#include <sys/malloc.h>
+#else
 #include <malloc.h>
 #endif
 #endif
+#endif
 
 #include <fcntl.h>
 
 #ifdef HAVE_VFS_H
 # include <sys/vfs.h>
@@ -609,10 +613,13 @@
 
 /*******************************************************************/
 
 enum fileattr  /* See COMMATTRIBUTES[] in globals.c  for matching entry */
    {
+#ifdef DARWIN
+   cffindertype,
+#endif
    cfrecurse,
    cfmode,
    cfowner,
    cfgroup,
    cfage,
@@ -1204,10 +1211,13 @@
 
 /*******************************************************************/
 
 struct Image
    {
+#ifdef DARWIN
+   char   *cf_findertype; /* Type info for Finder */
+#endif
    char   done;
    char   *path;
    char   *destination;
    char   *server;
    char   *repository;
diff -U5 cfengine-2.0.4/src/cf.extern.h cfengine-2.0.4.new/src/cf.extern.h
--- cfengine-2.0.4/src/cf.extern.h      Thu Aug 15 16:51:23 2002
+++ cfengine-2.0.4.new/src/cf.extern.h  Mon Jun 30 12:05:04 2003
@@ -109,10 +109,13 @@
 
 extern int LINENUMBER;
 extern mode_t DEFAULTMODE;
 extern mode_t DEFAULTSYSTEMMODE;
 extern int HAVEUID;
+#ifdef DARWIN
+extern char *FINDERTYPE;
+#endif
 extern char *VUIDNAME;
 extern char *VGIDNAME;
 extern char CFSERVER[];
 extern char *PROTOCOL[];
 extern char VIPADDRESS[];
Only in cfengine-2.0.4/src/: cflex.c
diff -U5 cfengine-2.0.4/src/filedir.c cfengine-2.0.4.new/src/filedir.c
--- cfengine-2.0.4/src/filedir.c        Sat Jun 22 03:37:32 2002
+++ cfengine-2.0.4.new/src/filedir.c    Mon Jul  7 16:35:09 2003
@@ -25,10 +25,14 @@
  
 
 #include "cf.defs.h"
 #include "cf.extern.h"
 
+#ifdef DARWIN
+#include <sys/attr.h>
+#endif
+
 
 /*********************************************************************/
 
 int IsHomeDir(name)
 
@@ -161,11 +165,15 @@
  
 if ((dirh = opendir(".")) == NULL)
    {
    if (lstat(name,&statbuf) != -1)
       {
+#ifdef DARWIN
+        
CheckExistingFile("*",name,plus,minus,action,uidlist,gidlist,&statbuf,ptr,ptr->acl_aliases);
+#else
       
CheckExistingFile(name,plus,minus,action,uidlist,gidlist,&statbuf,ptr,ptr->acl_aliases);
+#endif
       }
    return true;
    }
 
 for (dirp = readdir(dirh); dirp != NULL; dirp = readdir(dirh))
@@ -222,11 +230,16 @@
       }
 
 
    if (S_ISLNK(statbuf.st_mode))            /* should we ignore links? */
       {
+#ifdef DARWIN
+
+      CheckExistingFile("*", pcwd, plus, minus, action, uidlist, gidlist, 
&statbuf, ptr, ptr->acl_aliases);
+#else
       
CheckExistingFile(pcwd,plus,minus,action,uidlist,gidlist,&statbuf,ptr,ptr->acl_aliases);
+#endif
       continue;
       }
 
    if (S_ISDIR(statbuf.st_mode))
       {
@@ -236,43 +249,70 @@
          }
       else
          {
          if ((ptr->recurse > 1) || (ptr->recurse == INFINITERECURSE))
             {
+
+#ifdef DARWIN            
CheckExistingFile("*",pcwd,plus,minus,action,uidlist,gidlist,&statbuf,ptr,ptr->acl_aliases);
+#else
             
CheckExistingFile(pcwd,plus,minus,action,uidlist,gidlist,&statbuf,ptr,ptr->acl_aliases);
+#endif
             goback = 
RecursiveCheck(pcwd,plus,minus,action,uidlist,gidlist,recurse-1,rlevel+1,ptr,&statbuf);
            DirPop(goback,name,sb);
             }
          else
             {
-            
CheckExistingFile(pcwd,plus,minus,action,uidlist,gidlist,&statbuf,ptr,ptr->acl_aliases);
+
+#ifdef DARWIN            
CheckExistingFile("*",pcwd,plus,minus,action,uidlist,gidlist,&statbuf,ptr,ptr->acl_aliases);
+#else
+CheckExistingFile(pcwd,plus,minus,action,uidlist,gidlist,&statbuf,ptr,ptr->acl_aliases);
+#endif
             }
          }
       }
    else
       {
+#ifdef DARWIN
+      
CheckExistingFile("*",pcwd,plus,minus,action,uidlist,gidlist,&statbuf,ptr,ptr->acl_aliases);
+#else
       
CheckExistingFile(pcwd,plus,minus,action,uidlist,gidlist,&statbuf,ptr,ptr->acl_aliases);
+#endif
       }
    }
 
 closedir(dirh);
 return true; 
 }
 
 
 /*********************************************************************/
+#ifdef DARWIN
+void 
CheckExistingFile(cf_findertype,file,plus,minus,action,uidlist,gidlist,dstat,ptr,acl_aliases)
 
+char *cf_findertype;
+char *file;
+mode_t plus,minus;
+struct UidList *uidlist;
+struct GidList *gidlist;
+enum fileactions action;
+struct stat *dstat;
+struct File *ptr;
+struct Item *acl_aliases;
+
+#else
 void 
CheckExistingFile(file,plus,minus,action,uidlist,gidlist,dstat,ptr,acl_aliases)
 
 char *file;
 mode_t plus,minus;
 struct UidList *uidlist;
 struct GidList *gidlist;
 enum fileactions action;
 struct stat *dstat;
 struct File *ptr;
 struct Item *acl_aliases;
+
+#endif
  
 { mode_t newperm = dstat->st_mode, maskvalue;
   int amroot = true, fixmode = true, docompress=false;
   unsigned char digest[EVP_MAX_MD_SIZE+1];
 
@@ -460,10 +500,18 @@
          default:        break;
          }
       }
    }
 
+#ifdef DARWIN
+if (CheckFinderType(file, action, cf_findertype,dstat)) {
+    if (ptr != NULL) {
+        AddMultipleClasses(ptr->defines);
+    }
+}
+#endif
+
 if (CheckOwner(file,action,uidlist,gidlist,dstat))
    {
    if (ptr != NULL)
       {
       AddMultipleClasses(ptr->defines);
@@ -811,11 +859,25 @@
 umask(maskvalue);  
 Debug("CheckExistingFile(Done)\n"); 
 }
 
 /*********************************************************************/
+#ifdef DARWIN
+void 
CheckCopiedFile(cf_findertype,file,plus,minus,action,uidlist,gidlist,dstat,sstat,ptr,acl_aliases)
 
+char *cf_findertype;
+char *file;
+mode_t plus,minus;
+struct UidList *uidlist;
+struct GidList *gidlist;
+enum fileactions action;
+struct stat *dstat;
+struct stat *sstat;
+struct File *ptr;
+struct Item *acl_aliases;
+
+#else
 void 
CheckCopiedFile(file,plus,minus,action,uidlist,gidlist,dstat,sstat,ptr,acl_aliases)
 
 char *file;
 mode_t plus,minus;
 struct UidList *uidlist;
@@ -824,10 +886,12 @@
 struct stat *dstat;
 struct stat *sstat;
 struct File *ptr;
 struct Item *acl_aliases;
 
+#endif
+
 { mode_t newplus,newminus;
 
  /* plus/minus must be relative to source file, not to
     perms of newly created file! */
 
@@ -835,18 +899,144 @@
 
 if ((plus == 0) && (minus == 0))
     {
     newplus = sstat->st_mode & 07777 | plus;
     newminus = ~(sstat->st_mode & 07777 & ~minus) & 07777;
-    
CheckExistingFile(file,newplus,newminus,fixall,uidlist,gidlist,dstat,NULL,acl_aliases);
+
+#ifdef DARWIN
+CheckExistingFile(cf_findertype,file,newplus,newminus,fixall,uidlist,gidlist,dstat,NULL,acl_aliases);
+#else
+CheckExistingFile(file,newplus,newminus,fixall,uidlist,gidlist,dstat,NULL,acl_aliases);
+#endif
+
     }
  else
     {
-    
CheckExistingFile(file,plus,minus,fixall,uidlist,gidlist,dstat,NULL,acl_aliases);
+
+#ifdef DARWIN 
CheckExistingFile(cf_findertype,file,plus,minus,fixall,uidlist,gidlist,dstat,NULL,acl_aliases);
+#else
+CheckExistingFile(file,plus,minus,fixall,uidlist,gidlist,dstat,NULL,acl_aliases);
+#endif
     }
 }
 
+/*********************************************************************/
+#ifdef DARWIN
+int CheckFinderType(char * file,enum fileactions action,char * cf_findertype, 
struct stat * statbuf) {
+
+    /* Code modeled after hfstar's extract.c */
+    typedef struct t_fndrinfo {
+        long fdType;
+        long fdCreator;
+        short fdFlags;
+        short fdLocationV;
+        short fdLocationH;
+        short fdFldr;
+        short fdIconID;
+        short fdUnused[3];
+        char fdScript;
+        char fdXFlags;
+        short fdComment;
+        long fdPutAway;
+    } FInfo;
+
+    struct attrlist attrs;
+    struct {
+        long ssize;
+        struct timespec created;
+        struct timespec modified;
+        struct timespec changed;
+        struct timespec backup;
+        FInfo fi;
+    } fndrInfo;
+    
+    int retval;
+    
+    Debug("CheckFinderType of %s for %s\n", file, cf_findertype);
+
+    if (strcmp(cf_findertype, "*") == 0 || strcmp(cf_findertype, "") == 0) { 
/* No checking - no action */
+        Debug("CheckFinderType not needed\n");
+        return 0;
+    }
+    
+    attrs.bitmapcount = ATTR_BIT_MAP_COUNT;
+    attrs.reserved = 0;
+    attrs.commonattr = ATTR_CMN_CRTIME | ATTR_CMN_MODTIME | ATTR_CMN_CHGTIME | 
ATTR_CMN_BKUPTIME | ATTR_CMN_FNDRINFO;
+    attrs.volattr = 0;
+    attrs.dirattr = 0;
+    attrs.fileattr = 0;
+    attrs.forkattr = 0;
+    
+    memset(&fndrInfo, 0, sizeof(fndrInfo));
+
+    getattrlist(file, &attrs, &fndrInfo, sizeof(fndrInfo),0);
+    
+    if (fndrInfo.fi.fdType != *(long *)cf_findertype) { /* Need to update 
Finder Type field */
+        fndrInfo.fi.fdType = *(long *)cf_findertype;
+
+        /* Determine action to take */
+        
+        if (S_ISLNK(statbuf->st_mode) || S_ISDIR(statbuf->st_mode)) {
+            printf("CheckFinderType: Wrong file type for %s -- skipping\n", 
file);
+            return 0;
+        }
+        
+        if (S_ISREG(statbuf->st_mode) && action == fixdirs) {
+            printf("CheckFinderType: Wrong file type for %s -- skipping\n", 
file);
+            return 0;
+        }
+        
+        switch (action)
+        {
+        
+            /* Fix it */
+            case fixplain:
+            case fixdirs:
+            case fixall: 
+            case touch:
+
+
+                if (DONTDO) { /* well, unless we shouldn't fix it */
+                    printf("CheckFinderType: Dry run. No action taken.\n");
+                    return 0;
+                }
+
+                /* setattrlist does not take back in the long ssize */        
+                retval = setattrlist(file, &attrs, &fndrInfo.created, 
4*sizeof(struct timespec) + sizeof(FInfo), 0);
+        
+                Debug("CheckFinderType setattrlist returned %d\n", retval);
+
+                if (retval >= 0) {
+                    printf("Setting Finder Type code of %s to %s\n", file, 
cf_findertype);
+                }
+                else {
+                    printf("Setting Finder Type code of %s to %s failed!!\n", 
file, cf_findertype);
+                }
+        
+                return retval;
+            
+            /* Just warn */
+            case linkchildren:
+            case warnall: 
+            case warndirs:
+            case warnplain:
+                printf("Warning: FinderType does not match -- not fixing.\n");
+                return 0;
+
+            default:
+                printf("Should never get here. Aroo?\n");
+                return 0;
+        }
+    }
+    
+    else {
+        Debug("CheckFinderType matched\n");
+        return 0;
+    }
+}
+
+#endif
 /*********************************************************************/
 
 int CheckOwner(file,action,uidlist,gidlist,statbuf)
 
 char *file;
diff -U5 cfengine-2.0.4/src/filenames.c cfengine-2.0.4.new/src/filenames.c
--- cfengine-2.0.4/src/filenames.c      Mon Jun 17 09:28:26 2002
+++ cfengine-2.0.4.new/src/filenames.c  Fri Jun 27 15:59:21 2003
@@ -323,19 +323,36 @@
   struct stat statbuf;
   mode_t mask;
   int rootlen;
   char Path_File_Separator;
     
+#ifdef DARWIN 
+  /* Keeps track of if we are dealing w. a resource fork */
+  int rsrcfork;
+  rsrcfork = 0;
+  
+  char * tmpstr;
+  
+#endif
+   
+    
 if (!IsAbsoluteFileName(file))
    {
    snprintf(OUTPUT,bufsize*2,"Will not create directories for a relative 
filename %s\nHas no invariant meaning\n",file);
    CfLog(cferror,OUTPUT,"");
    return false;
    }
 
 strncpy(pathbuf,file,bufsize-1);                                      /* local 
copy */
 
+#ifdef DARWIN
+/* Determine if we are dealing w. a rsrc fork */
+if (strstr(pathbuf, "/..namedfork/rsrc") != NULL) {
+    rsrcfork = 1;
+}
+#endif
+
 /* skip link name */
 sp = LastFileSeparator(pathbuf);
 if (sp == NULL)
    {
    sp = pathbuf;
@@ -477,10 +494,28 @@
          }
       else
          {
          if (! S_ISDIR(statbuf.st_mode))
             {
+            
+#ifdef DARWIN
+            /*Ck if resource fork */
+            if (rsrcfork) {
+                tmpstr = malloc(bufsize);
+                strcpy(tmpstr, currentpath);
+                strcat(tmpstr, "/..namedfork");
+                
+                if (strcmp(tmpstr, pathbuf) == 0) {
+                    free(tmpstr);
+                    return(true);
+                }
+                
+                free(tmpstr);
+            }
+            
+#endif            
+            
             snprintf(OUTPUT,bufsize*2,"Cannot make %s - %s is not a directory! 
(use forcedirs=true)\n",pathbuf,currentpath);
            CfLog(cferror,OUTPUT,"");
             return(false);
             }
          }
diff -U5 cfengine-2.0.4/src/globals.c cfengine-2.0.4.new/src/globals.c
--- cfengine-2.0.4/src/globals.c        Thu Aug 15 16:53:14 2002
+++ cfengine-2.0.4.new/src/globals.c    Mon Jun 30 12:04:20 2003
@@ -572,10 +572,14 @@
   PRIVATE char FORCEDIRS = 'n';
   PRIVATE char STEALTH = 'n';
   PRIVATE char CHECKSUM = 'n'; /* n,m,s */
   PRIVATE char COMPRESS = 'n';
 
+#ifdef DARWIN
+  PRIVATE char *FINDERTYPE;
+#endif
+
   PRIVATE char *VUIDNAME;
   PRIVATE char *VGIDNAME;
   PRIVATE char *FILTERNAME;
   PRIVATE char *STRATEGYNAME;
   PRIVATE char *CURRENTITEM;
@@ -647,10 +651,13 @@
   */
   PRIVATE flag MOUNT_RO = false;
 
   PRIVATE char *COMMATTRIBUTES[] =
      {
+#ifdef DARWIN
+     "findertype",
+#endif
      "recurse",
      "mode",
      "owner",
      "group",
      "age",
diff -U5 cfengine-2.0.4/src/image.c cfengine-2.0.4.new/src/image.c
--- cfengine-2.0.4/src/image.c  Thu Aug 15 17:06:33 2002
+++ cfengine-2.0.4.new/src/image.c      Thu Jul  3 14:55:01 2003
@@ -184,12 +184,15 @@
       if (stat(newto,&deststatbuf) == -1)
         {
         mkdir(newto,statbuf.st_mode);
         }
 
+#ifdef DARWIN
+      
CheckCopiedFile(ip->cf_findertype,newto,ip->plus,ip->minus,fixall,ip->uid,ip->gid,&deststatbuf,&statbuf,NULL,ip->acl_aliases);
+#else
       
CheckCopiedFile(newto,ip->plus,ip->minus,fixall,ip->uid,ip->gid,&deststatbuf,&statbuf,NULL,ip->acl_aliases);
-
+#endif
       (ip->uid)->uid = save_uid;
       (ip->gid)->gid = save_gid;
       
       RecursiveImage(ip,newfrom,newto,maxrecurse-1);
       }
@@ -424,11 +427,15 @@
       return;
       }
 
    /* Now check any overrides */
 
+#ifdef DARWIN
+   
CheckCopiedFile(ip->cf_findertype,destdir,ip->plus,ip->minus,fixall,ip->uid,ip->gid,&deststatbuf,&sourcestatbuf,NULL,ip->acl_aliases);
+#else
    
CheckCopiedFile(destdir,ip->plus,ip->minus,fixall,ip->uid,ip->gid,&deststatbuf,&sourcestatbuf,NULL,ip->acl_aliases);
+#endif
    
    for (dirp = cfreaddir(dirh,ip); dirp != NULL; dirp = cfreaddir(dirh,ip))
       {
       if (!SensibleFile(dirp->d_name,sourcedir,ip))
          {
@@ -665,11 +672,15 @@
 
       if (succeed)
         {
         ENFORCELINKS = enforcelinks;
         lstat(destfile,&deststatbuf);
+#ifdef DARWIN
+        
CheckCopiedFile(ip->cf_findertype,destfile,ip->plus,ip->minus,fixall,ip->uid,ip->gid,&deststatbuf,&sourcestatbuf,NULL,ip->acl_aliases);
+#else
         
CheckCopiedFile(destfile,ip->plus,ip->minus,fixall,ip->uid,ip->gid,&deststatbuf,&sourcestatbuf,NULL,ip->acl_aliases);
+#endif
         }
       
       return;
       }
    }
@@ -769,11 +780,15 @@
       CfLog(cfinform,OUTPUT,"");
 
       if (CopyReg(sourcefile,destfile,sourcestatbuf,deststatbuf,ip))
          {
         stat(destfile,&deststatbuf);
+#ifdef DARWIN
+        CheckCopiedFile(ip->cf_findertype, 
destfile,ip->plus,ip->minus,fixall,ip->uid,ip->gid,&deststatbuf,&sourcestatbuf,NULL,ip->acl_aliases);
+#else
         
CheckCopiedFile(destfile,ip->plus,ip->minus,fixall,ip->uid,ip->gid,&deststatbuf,&sourcestatbuf,NULL,ip->acl_aliases);
+#endif
         AddMultipleClasses(ip->defines);
          }
       else
         {
         AddMultipleClasses(ip->failover);
@@ -865,11 +880,17 @@
         }
 
       if (succeed)
         {
         lstat(destfile,&deststatbuf);
+#ifdef DARWIN
+        
CheckCopiedFile(ip->cf_findertype,destfile,ip->plus,ip->minus,fixall,ip->uid,ip->gid,&deststatbuf,&sourcestatbuf,NULL,ip->acl_aliases);
+
+#else
         
CheckCopiedFile(destfile,ip->plus,ip->minus,fixall,ip->uid,ip->gid,&deststatbuf,&sourcestatbuf,NULL,ip->acl_aliases);
+
+#endif
         AddMultipleClasses(ip->defines);
         }
       }
    }
 else
@@ -977,11 +998,16 @@
         AddMultipleClasses(ip->defines);
 
          if (CopyReg(sourcefile,destfile,sourcestatbuf,deststatbuf,ip))
             {
             stat(destfile,&deststatbuf);
+#ifdef DARWIN            
+           
CheckCopiedFile(ip->cf_findertype,destfile,ip->plus,ip->minus,fixall,ip->uid,ip->gid,&deststatbuf,&sourcestatbuf,NULL,ip->acl_aliases);
+#else
            
CheckCopiedFile(destfile,ip->plus,ip->minus,fixall,ip->uid,ip->gid,&deststatbuf,&sourcestatbuf,NULL,ip->acl_aliases);
+
+#endif
             }
         else
            {
            AddMultipleClasses(ip->failover);
            }
@@ -1027,19 +1053,27 @@
                return;
            }
 
         if (succeed)
            {
+#ifdef DARWIN
+           
CheckCopiedFile(ip->cf_findertype,destfile,ip->plus,ip->minus,fixall,ip->uid,ip->gid,&deststatbuf,&sourcestatbuf,NULL,ip->acl_aliases);
+#else
            
CheckCopiedFile(destfile,ip->plus,ip->minus,fixall,ip->uid,ip->gid,&deststatbuf,&sourcestatbuf,NULL,ip->acl_aliases);
+
+#endif
            }
         ENFORCELINKS = enforcelinks;
          }
       }
    else
       {
+#ifdef DARWIN
+      
CheckCopiedFile(ip->cf_findertype,destfile,ip->plus,ip->minus,fixall,ip->uid,ip->gid,&deststatbuf,&sourcestatbuf,NULL,ip->acl_aliases);
+#else
       
CheckCopiedFile(destfile,ip->plus,ip->minus,fixall,ip->uid,ip->gid,&deststatbuf,&sourcestatbuf,NULL,ip->acl_aliases);
-
+#endif
       Debug("cfengine: image file is up to date: %s\n",destfile);
       AddMultipleClasses(ip->elsedef);
       }
    }
 }
@@ -1258,10 +1292,28 @@
   struct stat s;
 #ifdef HAVE_UTIME_H
   struct utimbuf timebuf;
 #endif  
 
+#ifdef DARWIN
+    /* For later copy from new to dest */
+    char * rsrcbuf;
+    int rsrcbytesr; /* read */
+    int rsrcbytesw; /* written */
+    int rsrcbytesl; /* to read */
+    int rsrcrd;
+    int rsrcwd;
+
+    /* Keep track of if a resource fork */
+    char *tmpstr;
+    char *forkpointer;
+    
+    int rsrcfork;
+    rsrcfork=0;
+        
+#endif
+
 Debug2("CopyReg(%s,%s)\n",source,dest);
 
 if (DONTDO)
    {
    printf("%s: copy from %s to %s\n",VPREFIX,source,dest);
@@ -1292,12 +1344,37 @@
    {
    Debug("This is a remote copy from server: %s\n",ip->server);
    remote = true;
    }
 
+#ifdef DARWIN
+    if (strstr(dest, "/..namedfork/rsrc")) { /* Need to munge the "new" name */
+        rsrcfork = 1;
+
+        tmpstr = malloc(bufsize);
+        
+        /* Drop /..namedfork/rsrc */
+        strcpy(tmpstr, dest);
+        forkpointer = strstr(tmpstr, "/..namedfork/rsrc");
+        *forkpointer = '\0'; 
+        
+        strcpy(new, tmpstr);
+
+        free(tmpstr);
+
+    }
+    
+    else {
+#endif
+
 strcpy(new,dest);
-strcat(new,CF_NEW);
+
+#ifdef DARWIN
+    }
+#endif
+
+strcat(new, CF_NEW);
 
 if (remote)
    {
    if (CONN->error)
       {
@@ -1396,17 +1473,95 @@
         }
       return false;
       }
    }
 
+#ifdef DARWIN
+if (rsrcfork) { /* Can't just "mv" the resource fork, unfortunately */
+
+    rsrcrd = open(new, O_RDONLY|O_BINARY);
+    rsrcwd = open(dest, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0600);
+    
+    if (rsrcrd == -1 || rsrcwd == -1) {
+        snprintf(OUTPUT, bufsize, "Open of rsrcrd/rsrcwd failed\n");
+        CfLog(cfinform,OUTPUT,"open");
+        close(rsrcrd);
+        close(rsrcwd);
+        return(false);
+    }
+    
+    rsrcbuf = malloc(bufsize);
+    
+    rsrcbytesr = 0;
+    
+    while(1) {
+        rsrcbytesr = read(rsrcrd, rsrcbuf, bufsize);
+        
+        if (rsrcbytesr == -1) { /* Ck error */
+            if (errno == EINTR) continue;
+            
+            else {
+            snprintf(OUTPUT, bufsize, "Read of rsrcrd failed\n");
+            CfLog(cfinform,OUTPUT,"read");
+                close(rsrcrd);
+                close(rsrcwd);
+                free(rsrcbuf);
+                return(false);
+            }
+        }
+        
+        else if (rsrcbytesr == 0) { /* Reached EOF */
+            close(rsrcrd);
+            close(rsrcwd);
+            free(rsrcbuf);
+            
+            unlink(new); /* Go ahead and unlink .cfnew */
+            
+            break;
+        }
+        
+        rsrcbytesl = rsrcbytesr;
+        rsrcbytesw = 0;
+        
+        while (rsrcbytesl > 0) {
+        
+            rsrcbytesw += write(rsrcwd, rsrcbuf, rsrcbytesl);
+            
+            if (rsrcbytesw == -1) { /* Ck error */
+                if (errno == EINTR) continue;
+                else {
+                    snprintf(OUTPUT, bufsize, "Write of rsrcwd failed\n");
+                    CfLog(cfinform,OUTPUT,"write");
+               
+                    close(rsrcrd);
+                    close(rsrcwd);
+                    free(rsrcbuf);
+                    return(false);
+                }
+            }
+            
+            rsrcbytesl = rsrcbytesr - rsrcbytesw;
+        
+        }
+    }
+    
+}
+
+else {
+#endif
+
 if (rename(new,dest) == -1)
    {
    snprintf(OUTPUT,bufsize*2,"Problem: could not install copy file as %s, 
directory in the way?\n",dest);
    CfLog(cferror,OUTPUT,"rename");
    rename(backup,dest);
    return false;
    }
+
+#ifdef DARWIN
+}
+#endif
 
 if ((IMAGEBACKUP == 'y') && backupisdir)
    {
    snprintf(OUTPUT,bufsize,"Cannot move a directory to repository, leaving at 
%s",backup);
    CfLog(cfinform,OUTPUT,"");
diff -U5 cfengine-2.0.4/src/install.c cfengine-2.0.4.new/src/install.c
--- cfengine-2.0.4/src/install.c        Thu Aug 15 17:09:39 2002
+++ cfengine-2.0.4.new/src/install.c    Mon Jul  7 15:47:09 2003
@@ -573,10 +573,21 @@
 
 Debug1("HandleOptionalImageAttribute(%s)\n",value);
 
 switch(GetCommAttribute(item))
    {
+#ifdef DARWIN
+   case cffindertype: 
+       if (strlen(value) == 4 ) {
+               strcpy(FINDERTYPE,value);
+       }
+        else {
+               yyerror("Attribute findertype must be 4 letter code");
+
+       }
+        break;
+#endif
    case cfmode:    ParseModeString(value,&PLUSMASK,&MINUSMASK);
                    break;
    case cfflags:   ParseFlagString(value,&PLUSFLAG,&MINUSFLAG);
                    break;
    case cfowner:   strcpy(VUIDNAME,value);
@@ -2173,13 +2184,19 @@
 
    case processes: InstallProcessItem(EXPR,RESTART,PROMATCHES,PROCOMP,
                                      
PROSIGNAL,PROACTION,CLASSBUFF,USESHELL,VUIDNAME,VGIDNAME);
                    break;
    case image:
+#ifdef DARWIN
+                  InstallImageItem(FINDERTYPE, CURRENTPATH, PLUSMASK, 
MINUSMASK, DESTINATION,
+                                  
IMAGEACTION,VUIDNAME,VGIDNAME,IMGSIZE,IMGCOMP,
+                                  VRECURSE,COPYTYPE,LINKTYPE,CFSERVER);
+#else
                   InstallImageItem(CURRENTPATH,PLUSMASK,MINUSMASK,DESTINATION,
                                   
IMAGEACTION,VUIDNAME,VGIDNAME,IMGSIZE,IMGCOMP,
                                   VRECURSE,COPYTYPE,LINKTYPE,CFSERVER);
+#endif
                   break;
 
    case tidy:     if (VAGE >= 99999)
                      {
                      yyerror("Must specify an age for tidy actions");
@@ -3858,20 +3875,33 @@
 AddInstallable(ptr->defines);
 AddInstallable(ptr->elsedef);  
 }
 
 /*******************************************************************/
+#ifdef DARWIN
+void InstallImageItem(cf_findertype, 
path,plus,minus,destination,action,uidnames,gidnames,
+                size,comp,rec,type,lntype,server)
 
+char *cf_findertype;
+char *path, *destination, *action, *server;
+mode_t plus,minus;
+char *uidnames;
+char *gidnames;
+char type, lntype, comp;
+int rec, size;
+
+#else
 void InstallImageItem(path,plus,minus,destination,action,uidnames,gidnames,
                 size,comp,rec,type,lntype,server)
 
 char *path, *destination, *action, *server;
 mode_t plus,minus;
 char *uidnames;
 char *gidnames;
 char type, lntype, comp;
 int rec, size;
+#endif
 
 { struct Image *ptr;
   char *spl; 
   char buf1[bufsize], buf2[bufsize], buf3[bufsize], buf4[bufsize];
   struct TwoDimList *tp = NULL;
@@ -4023,10 +4053,15 @@
    else
       {
       VIMAGETOP->next = ptr;
       }
 
+#ifdef DARWIN
+   if ((ptr->cf_findertype = strdup(cf_findertype)) == NULL) {
+        FatalError("Memory Allocation failed for cf_findertype ptr in 
InstallImageItem()");
+    }
+#endif
    ptr->plus = plus;
    ptr->minus = minus;
    ptr->uid = MakeUidList(uidnames);
    ptr->gid = MakeGidList(gidnames);
    ptr->force = FORCE;
diff -U5 cfengine-2.0.4/src/parse.c cfengine-2.0.4.new/src/parse.c
--- cfengine-2.0.4/src/parse.c  Mon Aug 12 05:04:45 2002
+++ cfengine-2.0.4.new/src/parse.c      Thu Jul  3 12:31:51 2003
@@ -227,10 +227,14 @@
 
 void NewParser()
 
 {
  Debug("New Parser Object::");
+#ifdef DARWIN
+ FINDERTYPE = (char *) malloc(bufsize);
+ strcpy(FINDERTYPE, "*"); /* How we determine if no findertype set */
+#endif
  VUIDNAME = (char *) malloc(bufsize);
  VGIDNAME = (char *) malloc(bufsize);
  FILTERNAME = (char *) malloc(bufsize);
  STRATEGYNAME = (char *) malloc(bufsize);
  CURRENTITEM = (char *) malloc(bufsize);
@@ -264,10 +268,13 @@
 
 void DeleteParser()
 
 { Debug("Delete Parser Object::");
 
+#ifdef DARWIN
+free(FINDERTYPE);
+#endif
 free(VUIDNAME);
 free(VGIDNAME);
 free(FILTERNAME);
 free(STRATEGYNAME);
 free(CURRENTITEM);
@@ -1359,10 +1366,13 @@
  MINUSMASK = (mode_t)0;
  PLUSFLAG = (u_long)0;
  MINUSFLAG = (u_long)0;
  VRECURSE = 0;
  VAGE = 99999;
+#ifdef DARWIN
+ strcpy(FINDERTYPE,"*");
+#endif
  strcpy(VUIDNAME,"*");
  strcpy(VGIDNAME,"*");
  HAVE_RESTART = 0;
  FILEACTION=warnall;
 
diff -U5 cfengine-2.0.4/src/prototypes.h cfengine-2.0.4.new/src/prototypes.h
--- cfengine-2.0.4/src/prototypes.h     Wed Aug 21 04:14:20 2002
+++ cfengine-2.0.4.new/src/prototypes.h Thu Jul  3 15:37:57 2003
@@ -280,12 +280,21 @@
 /* filedir.c */
 
 int IsHomeDir ARGLIST((char *name));
 int EmptyDir ARGLIST((char *path));
 int RecursiveCheck ARGLIST((char *name, mode_t plus, mode_t minus, enum 
fileactions action, struct UidList *uidlist, struct GidList *gidlist, int 
recurse, int rlevel, struct File *ptr,struct stat *sb));
+#ifdef DARWIN
+int CheckFinderType ARGLIST((char *file, enum fileactions action, char * 
cf_findertype, struct stat * statbuf));
+void CheckExistingFile ARGLIST((char *cf_findertype, char *file, mode_t plus, 
mode_t minus, enum fileactions action, struct UidList *uidlist, struct GidList 
*gidlist, struct stat *dstat, struct File *ptr, struct Item *acl_aliases));
+#else
 void CheckExistingFile ARGLIST((char *file, mode_t plus, mode_t minus, enum 
fileactions action, struct UidList *uidlist, struct GidList *gidlist, struct 
stat *dstat, struct File *ptr, struct Item *acl_aliases));
+#endif
+#ifdef DARWIN
+void CheckCopiedFile ARGLIST((char *cf_findertype, char *file, mode_t plus, 
mode_t minus, enum fileactions action, struct UidList *uidlist, struct GidList 
*gidlist, struct stat *dstat, struct stat *sstat, struct File *ptr, struct Item 
*acl_aliases));
+#else
 void CheckCopiedFile ARGLIST((char *file, mode_t plus, mode_t minus, enum 
fileactions action, struct UidList *uidlist, struct GidList *gidlist, struct 
stat *dstat, struct stat *sstat, struct File *ptr, struct Item *acl_aliases));
+#endif
 int CheckOwner ARGLIST((char *file, enum fileactions action, struct UidList 
*uidlist, struct GidList *gidlist, struct stat *statbuf));
 int CheckHomeSubDir ARGLIST((char *testpath, char *tidypath, int recurse));
 int FileIsNewer ARGLIST((char *file1, char *file2));
 int IgnoreFile  ARGLIST((char *pathto, char *name, struct Item *ignores));
 void CompressFile ARGLIST((char *file));
@@ -434,11 +443,15 @@
 void HandleChecksum ARGLIST((char *value));
 void HandleTimeStamps ARGLIST((char *value));
 int GetFileAction ARGLIST((char *action));
 void InstallFileListItem ARGLIST((char *path, mode_t plus, mode_t minus, enum 
fileactions action, char *uidnames, char *gidnames, int recurse, char 
travlinks, char chksum));
 void InstallProcessItem ARGLIST((char *expr, char *restart, short int matches, 
char comp, short int signal, char action, char *classes, char useshell, char 
*uidname, char *gidname));
+#ifdef DARWIN
+void InstallImageItem ARGLIST((char * cf_findertype, char *path, mode_t plus, 
mode_t minus, char *destination, char *action, char *uidnames, char *gidnames, 
int size, char comp, int rec, char type, char lntype, char *server));
+#else
 void InstallImageItem ARGLIST((char *path, mode_t plus, mode_t minus, char 
*destination, char *action, char *uidnames, char *gidnames, int size, char 
comp, int rec, char type, char lntype, char *server));
+#endif
 void InstallAuthItem ARGLIST((char *path, char *attribute, struct Auth **list, 
struct Auth **listtop, char *classes));
 int GetCommAttribute ARGLIST((char *s));
 void HandleRecurse ARGLIST((char *value));
 void HandleCopyType ARGLIST((char *value));
 void HandleDisableFileType ARGLIST((char *value));
Only in cfengine-2.0.4.new/src/: testfile
diff -U5 cfengine-2.0.4/src/wrapper.c cfengine-2.0.4.new/src/wrapper.c
--- cfengine-2.0.4/src/wrapper.c        Mon Jul  8 16:19:11 2002
+++ cfengine-2.0.4.new/src/wrapper.c    Thu Jul  3 14:52:52 2003
@@ -177,11 +177,15 @@
    if (TouchDirectory(ptr))                /* files ending in /. */
       {
       MakeDirectoriesFor(startpath,'n');
       ptr->action = fixall;
       *(startpath+strlen(ptr->path)-2) = '\0';       /* trunc /. */
+#ifdef DARWIN
+      
CheckExistingFile("*",startpath,ptr->plus,ptr->minus,ptr->action,ptr->uid,ptr->gid,&statbuf,ptr,ptr->acl_aliases);
+#else
       
CheckExistingFile(startpath,ptr->plus,ptr->minus,ptr->action,ptr->uid,ptr->gid,&statbuf,ptr,ptr->acl_aliases);
+#endif
       ReleaseCurrentLock();
       return;
       }
 
    filemode = DEFAULTMODE;      /* Decide the mode for filecreation */
@@ -205,11 +209,15 @@
                          {
                          AddMultipleClasses(ptr->defines);
                          close(fd);
                          }
 
+#ifdef DARWIN
+                      
CheckExistingFile("*",startpath,ptr->plus,ptr->minus,fixall,ptr->uid,ptr->gid,&statbuf,ptr,ptr->acl_aliases);
+#else
                       
CheckExistingFile(startpath,ptr->plus,ptr->minus,fixall,ptr->uid,ptr->gid,&statbuf,ptr,ptr->acl_aliases);
+#endif
                        }
 
                     snprintf(OUTPUT,bufsize*2,"Creating file %s, mode = 
%o\n",ptr->path,filemode);
                    CfLog(cfinform,OUTPUT,"");
                     break;
@@ -262,18 +270,27 @@
    if (S_ISDIR(statbuf.st_mode) && (ptr->recurse != 0))
       {
       if (!IgnoreFile(startpath,ReadLastNode(startpath),ptr->ignores))
         {
         Verbose("%s: Skipping ignored directory %s\n",VPREFIX,startpath);
+#ifdef DARWIN
+
+        
CheckExistingFile("*",startpath,ptr->plus,ptr->minus,ptr->action,ptr->uid,ptr->gid,&statbuf,ptr,ptr->acl_aliases);
+#else
         
CheckExistingFile(startpath,ptr->plus,ptr->minus,ptr->action,ptr->uid,ptr->gid,&statbuf,ptr,ptr->acl_aliases);
+#endif
         }
           
       
RecursiveCheck(startpath,ptr->plus,ptr->minus,ptr->action,ptr->uid,ptr->gid,ptr->recurse,0,ptr,&statbuf);
       }
    else
       {
+#ifdef DARWIN
+      
CheckExistingFile("*",startpath,ptr->plus,ptr->minus,ptr->action,ptr->uid,ptr->gid,&statbuf,ptr,ptr->acl_aliases);
+#else
       
CheckExistingFile(startpath,ptr->plus,ptr->minus,ptr->action,ptr->uid,ptr->gid,&statbuf,ptr,ptr->acl_aliases);
+#endif
       }
    }
 
 ReleaseCurrentLock();
 }
@@ -316,9 +333,13 @@
 if 
(!GetLock(ASUniqueName("directories"),CanonifyName(directory),VIFELAPSED,VEXPIREAFTER,VUQNAME,CFSTARTTIME))
    {
    return;
    }
 
+#ifdef DARWIN
+CheckExistingFile("*",dir,ptr->plus,ptr->minus,ptr->action,ptr->uid,ptr->gid,&statbuf,ptr,ptr->acl_aliases);
+#else
 
CheckExistingFile(dir,ptr->plus,ptr->minus,ptr->action,ptr->uid,ptr->gid,&statbuf,ptr,ptr->acl_aliases);
+#endif
 ReleaseCurrentLock(); 
 }


reply via email to

[Prev in Thread] Current Thread [Next in Thread]