[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
- Re: [PATCH] OS X Resource Fork and FinderType support, (continued)
- Re: [PATCH] OS X Resource Fork and FinderType support, Dave Botsch, 2003/08/18
- Re: [PATCH] OS X Resource Fork and FinderType support, Daniel Pittman, 2003/08/18
- Message not available
- Re: [PATCH] OS X Resource Fork and FinderType support, Dave Botsch, 2003/08/18
- Re: [PATCH] OS X Resource Fork and FinderType support, John Valdes, 2003/08/19
- Re: [PATCH] OS X Resource Fork and FinderType support, Daniel Pittman, 2003/08/19
- Re: [PATCH] OS X Resource Fork and FinderType support, Mark . Burgess, 2003/08/19
- Re: [PATCH] OS X Resource Fork and FinderType support, David Douthitt, 2003/08/21
- Message not available
- Re: [PATCH] OS X Resource Fork and FinderType support, David Botsch, 2003/08/19
- Re: [PATCH] OS X Resource Fork and FinderType support, John Valdes, 2003/08/19
- Message not available
- Re: [PATCH] OS X Resource Fork and FinderType support, David Botsch, 2003/08/19
- Re: [PATCH] OS X Resource Fork and FinderType support,
David Botsch <=
Re: [PATCH] OS X Resource Fork and FinderType support, David Botsch, 2003/08/22
Re: [PATCH] OS X Resource Fork and FinderType support, Mark . Burgess, 2003/08/24
Re: [PATCH] OS X Resource Fork and FinderType support, Dave Botsch, 2003/08/26