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: Mark Burgess
Subject: Re: [PATCH] OS X Resource Fork and FinderType support
Date: Mon, 18 Aug 2003 14:28:02 +0200 (MEST)

David - thanks for your comprehensive patch. Can you tell me what
Resource FOrks means? 

This looks like a lot of work that I appreciate, but I would like to
know some more about it. In particular, I would like to have
some documentation before including it in the cfengine source tree.
Otherwise it is of no use to anyone except you!!


Mark


On  9 Jul, David Botsch wrote:
> 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(); 
>  }
> _______________________________________________
> Help-cfengine mailing list
> Help-cfengine@gnu.org
> http://mail.gnu.org/mailman/listinfo/help-cfengine

-- 


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Work: +47 22453272            Email:  Mark.Burgess@iu.hio.no
Fax : +47 22453205            WWW  :  http://www.iu.hio.no/~mark
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~





reply via email to

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