help-cfengine
[Top][All Lists]
Advanced

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

Re: [PATCH] OS X Resource Fork and FinderType support


From: David Botsch
Subject: Re: [PATCH] OS X Resource Fork and FinderType support
Date: Thu, 21 Aug 2003 15:45:10 -0400
User-agent: Pan/0.11.2 (Unix)

I just finished doing #1.

Any ideas for 2a?

Also have the str functions replaced with strn functions (except for strdup,
which under OS X doesn't seem to have a strndup equivalent.. weird).

Here's my updated patch against 2.0.4:


diff -U5 -r 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    Thu Aug 21 14:39:53 2003
@@ -148,13 +148,18 @@
 #include <unistd.h>
 #endif
 
 #ifdef HAVE_MALLOC_H
 #ifndef OPENBSD
+#ifdef DARWIN
+#include <sys/malloc.h>
+#include <sys/paths.h>
+#else
 #include <malloc.h>
 #endif
 #endif
+#endif
 
 #include <fcntl.h>
 
 #ifdef HAVE_VFS_H
 # include <sys/vfs.h>
@@ -609,10 +614,13 @@
 
 /*******************************************************************/
 
 enum fileattr  /* See COMMATTRIBUTES[] in globals.c  for matching entry */
    {
+#ifdef DARWIN
+   cffindertype,
+#endif
    cfrecurse,
    cfmode,
    cfowner,
    cfgroup,
    cfage,
@@ -1204,10 +1212,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 -r 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  Thu Aug 21 14:35:51 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[];
diff -U5 -r 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    Thu Aug 21 14:35:51 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 (strncmp(cf_findertype, "*", bufsize) == 0 || strncmp(cf_findertype, 
"", bufsize) == 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 -r 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  Thu Aug 21 14:55:52 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, _PATH_RSRCFORKSPEC) != NULL) {
+    rsrcfork = 1;
+}
+#endif
+
 /* skip link name */
 sp = LastFileSeparator(pathbuf);
 if (sp == NULL)
    {
    sp = pathbuf;
@@ -477,10 +494,32 @@
          }
       else
          {
          if (! S_ISDIR(statbuf.st_mode))
             {
+            
+#ifdef DARWIN
+            /*Ck if resource fork */
+            if (rsrcfork) {
+                tmpstr = malloc(bufsize);
+                strncpy(tmpstr, currentpath, bufsize);
+                strncat(tmpstr, _PATH_FORKSPECIFIER, bufsize);
+               
+
+               /* Cfengine removed terminating slashes */
+               DeleteSlash(tmpstr);
+ 
+                if (strncmp(tmpstr, pathbuf, bufsize) == 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 -r 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    Thu Aug 21 14:35:51 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 -r 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 Aug 21 14:57:40 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, _PATH_RSRCFORKSPEC)) { /* Need to munge the "new" name */
+        rsrcfork = 1;
+
+        tmpstr = malloc(bufsize);
+        
+        /* Drop _PATH_RSRCFORKSPEC */
+        strncpy(tmpstr, dest, bufsize);
+        forkpointer = strstr(tmpstr, _PATH_RSRCFORKSPEC);
+        *forkpointer = '\0'; 
+        
+        strncpy(new, tmpstr, bufsize);
+
+        free(tmpstr);
+
+    }
+    
+    else {
+#endif
+
 strcpy(new,dest);
-strcat(new,CF_NEW);
+
+#ifdef DARWIN
+    }
+#endif
+
+strncat(new, CF_NEW, bufsize);
 
 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 -r 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    Thu Aug 21 14:35:51 2003
@@ -573,10 +573,21 @@
 
 Debug1("HandleOptionalImageAttribute(%s)\n",value);
 
 switch(GetCommAttribute(item))
    {
+#ifdef DARWIN
+   case cffindertype: 
+       if (strlen(value) == 4 ) {
+               strncpy(FINDERTYPE,value,bufsize);
+       }
+        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 -r 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 Aug 21 14:35:51 2003
@@ -227,10 +227,14 @@
 
 void NewParser()
 
 {
  Debug("New Parser Object::");
+#ifdef DARWIN
+ FINDERTYPE = (char *) malloc(bufsize);
+ strncpy(FINDERTYPE, "*", bufsize); /* 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
+ strncpy(FINDERTYPE,"*", bufsize);
+#endif
  strcpy(VUIDNAME,"*");
  strcpy(VGIDNAME,"*");
  HAVE_RESTART = 0;
  FILEACTION=warnall;
 
diff -U5 -r 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 Aug 21 14:35:51 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));
diff -U5 -r 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 Aug 21 14:35:51 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(); 
 }
 

On Tue, 19 Aug 2003 18:28:16 -0400, David Botsch wrote:

> We should probably come up with a todo list for this. I would propose:
> 
> 1. replace in code references to ../namedfork/rsrc with the constants
> from /usr/include/sys/paths.h
> 
> 2. decide on what to use to specify (copy the resource fork over also)
> which initially, will copy over the split data and resource forks and
> later on copy over forks split into other formats as well, possibly with
> formats that also include metadata.
> 
> 2a. what should the split resource fork be named? Could be something
> like filename-..namedfork.rsrc or just filename-rsrc or filename.rsrc (I
> would prefer not to use . to prepend the file as in ._ b.c. this should
> not be a hidden file)
> 
> 2b. Decide what order in which to try different file types for when this
> support is included
> 
> I don't think #2 will be that bad remembering what I do from the
> structure of the code.
> 
> I have already slightly modified the patch file to use strn functions
> instead of str functions (but have not yet applied and tested).
> 
> On Tue, 19 Aug 2003 15:32:49 -0400, John Valdes wrote:
> 
>> On Tue, Aug 19, 2003 at 10:44:30AM -0400, David Botsch wrote:
>>> 
>>> But, it is documented on Apple's Developer Connection web site. Also
>>> defined in /usr/include/sys/paths.h
>> 
>> I missed those; I had originally read about the /rsrc trick in a USENIX
>> 2000 paper (http://www.mit.edu/people/wsanchez/papers/USENIX_2000/)
>> which referred to the old path, but learned the new path
>> (..namedfork/rsrc) by running "strings" on /mach_kernel. :)
>> 
>>> We've said OS X all along, but in reality, this needs to work properly
>>> on Darwin, I think... is Carbon available on Darwin? Or, maybe we
>>> don't care for actual Darwin?
>> 
>> That's a good point.  Personally, I'm only interested in OS X, but if
>> we could generalize to just Darwin, then I think we should.  I don't
>> know for sure, but I would guess that Carbon's not available for
>> Darwin, which means we probably shouldn't use the Carbon APIs.  Anyone
>> know if Apple's implemented any system calls that allow access to
>> forks?  I looked for a little, but couldn't find anything.  If not,
>> then since ../namedfork/rsrc is #define'd in paths.h, I have no
>> objection to using that in the Cfengine code.  Using that will indeed
>> be simpler than the Carbon APIs, as you say.
>> 
>>> So, someone needs to decide how to modify the copy statement to say,
>>> also include the resource fork.
>> 
>> I need to think about this more (and look at the code... :) ).
>> 
>>> > 3) I don't like the idea of storing the raw data & resource forks
>>> > for
>>> >    the master.  There are already too many Mac file formats in use:
>>> >    binhex, macbinary, applesingle & appledouble; this is yet
>>> >    another. While admittedly this is the easiest one to generate (as
>>> >    long as ..namedfork/rsrc continues to work),
>>> 
>>> Ease is a very good thing.
>>> 
>>> Perhaps starting with this and then adding support for other split the
>>> fork format types... volunteers?
>> 
>> That would be agreeable.  I can lend a hand with this.
>> 
>> John


reply via email to

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