Exemple #1
0
int IgnoredOrExcluded(enum actions action,char *file,struct Item *inclusions,struct Item *exclusions)

{ char *lastnode;

Debug("IgnoredOrExcluded(%s)\n",file);

if (strstr(file,"/"))
   {
   for (lastnode = file+strlen(file); *lastnode != '/'; lastnode--)
      {
      }

   lastnode++;
   }
else
   {
   lastnode = file;
   }

if ((inclusions != NULL) && !IsWildItemIn(inclusions,lastnode))
   {
   Debug("cfengine: skipping non-included pattern %s\n",file);
   return true;
   }

switch(action)
   {
   case image:
              if (IsWildItemIn(VEXCLUDECOPY,lastnode) || IsWildItemIn(exclusions,lastnode))
                 {
                 Debug("Skipping excluded pattern %s\n",file);
                 return true;
                 }
              break;
              
   case links:
              if (IsWildItemIn(VEXCLUDELINK,lastnode) || IsWildItemIn(exclusions,lastnode))
                 {
                 Debug("Skipping excluded pattern %s\n",file);
                 return true;
                 }
              
              break;
   default:
              if (IsWildItemIn(exclusions,lastnode))
                 {
                 Debug("Skipping excluded pattern %s\n",file);
                 return true;
                 }       
   }

return false;
}
Exemple #2
0
/* should return true if 'to' found */
int
HardLinkFiles(char *from, char *to,
    struct Item *inclusions, struct Item *exclusions, struct Item *copy,
    short nofile, struct Link *ptr)
{

    struct stat frombuf,tobuf;
    char saved[CF_BUFSIZE], *lastnode;
    struct UidList fakeuid;
    struct Image ip;
    char stamp[CF_BUFSIZE];
    time_t STAMPNOW;
    STAMPNOW = time((time_t *)NULL);

    for (lastnode = from+strlen(from); *lastnode != '/'; lastnode--) { }

    lastnode++;

    if (inclusions != NULL && !IsWildItemIn(inclusions,lastnode)) {
        Verbose("%s: Skipping non-included pattern %s\n",g_vprefix,from);
        return true;
    }

    if (IsWildItemIn(g_vexcludelink,lastnode) ||
            IsWildItemIn(exclusions,lastnode)) {

        Verbose("%s: Skipping excluded pattern %s\n",g_vprefix,from);
        return true;
    }

    if (IsWildItemIn(g_vcopylinks,lastnode) || IsWildItemIn(copy,lastnode)) {
        fakeuid.uid = CF_SAME_OWNER;
        fakeuid.next = NULL;
        ip.plus = CF_SAMEMODE;
        ip.minus = CF_SAMEMODE;
        ip.uid = &fakeuid;
        ip.gid = (struct GidList *) &fakeuid;
        ip.action = "do";
        ip.recurse = 0;
        ip.type = 't';
        ip.backup = true;
        ip.plus_flags = 0;
        ip.minus_flags = 0;
        ip.exclusions = NULL;
        ip.symlink = NULL;
        Verbose("%s: Link item %s marked for copying instead\n",
                g_vprefix, from);
        CheckImage(to,from,&ip);
        return true;
    }

    if (stat(to,&tobuf) == -1) {
        /* no error warning, since the higher level routine uses this */
        return(false);
    }

    if (! S_ISREG(tobuf.st_mode)) {

        snprintf(g_output, CF_BUFSIZE*2,
                "%s: will only hard link regular files "
                "and %s is not regular\n", g_vprefix, to);

        CfLog(cfsilent,g_output,"");
        return true;
    }

    Debug2("Trying to (hard) link %s -> %s\n",from,to);

    if (stat(from,&frombuf) == -1) {
        DoHardLink(from,to,ptr->defines);
        return true;
    }

    /* 
     * Both files exist, but are they the same file? POSIX says the
     * files could be on different devices, but unix doesn't allow this
     * behaviour so the tests below are theoretical...
     */

    if (frombuf.st_ino != tobuf.st_ino && frombuf.st_dev != frombuf.st_dev) {
        Verbose("If this is POSIX, unable to determine if %s is "
                "hard link is correct\n", from);
        Verbose("since it points to a different filesystem!\n");

        if (frombuf.st_mode == tobuf.st_mode &&
                frombuf.st_size == tobuf.st_size) {

            snprintf(g_output,CF_BUFSIZE*2,
                    "Hard link (%s->%s) on different device APPEARS okay\n",
                    from,to);

            CfLog(cfverbose,g_output,"");
            AddMultipleClasses(ptr->elsedef);
            return true;
        }
    }

    if (frombuf.st_ino == tobuf.st_ino && frombuf.st_dev == frombuf.st_dev) {

        snprintf(g_output,CF_BUFSIZE*2,
                "Hard link (%s->%s) exists and is okay.\n",from,to);

        CfLog(cfverbose,g_output,"");
        AddMultipleClasses(ptr->elsedef);
        return true;
    }

    snprintf(g_output,CF_BUFSIZE*2,
            "%s does not appear to be a hard link to %s\n",from,to);

    CfLog(cfinform,g_output,"");

    if (g_enforcelinks) {
        snprintf(g_output, CF_BUFSIZE*2, 
                "Moving %s to %s.%s\n", from, from, CF_SAVED);
        CfLog(cfinform,g_output,"");

        if (g_dontdo) {
            return true;
        }

        saved[0] = '\0';
        strcpy(saved,from);

        sprintf(stamp, "_%d_%s", g_cfstarttime, 
                CanonifyName(ctime(&STAMPNOW)));
        strcat(saved,stamp);

        strcat(saved,CF_SAVED);

        if (rename(from,saved) == -1) {
            perror("rename");
            return(true);
        }

        DoHardLink(from,to,ptr->defines);
    }

    return(true);
}
Exemple #3
0
/* should return true if 'to' found */
int
LinkFiles(char *from,char *to_tmp,
        struct Item *inclusions,struct Item *exclusions,struct Item *copy,
        short nofile,struct Link *ptr)
{
    struct stat buf,savebuf;
    char to[CF_BUFSIZE], linkbuf[CF_BUFSIZE];
    char saved[CF_BUFSIZE],absto[CF_BUFSIZE],*lastnode;
    struct UidList fakeuid;
    struct Image ip;
    char stamp[CF_BUFSIZE];
    time_t STAMPNOW;
    STAMPNOW = time((time_t *)NULL);

    memset(to,0,CF_BUFSIZE);
    memset(&ip,0, sizeof(ip));

    /* links without a directory reference */
    if ((*to_tmp != '/') && (*to_tmp != '.')) {
        strcpy(to,"./");
    }

    if (strlen(to_tmp)+3 > CF_BUFSIZE) {
        printf("%s: CF_BUFSIZE boundaries exceeded in LinkFiles(%s->%s)\n",
                g_vprefix,from,to_tmp);
        return false;
    }

    strcat(to,to_tmp);

    Debug2("Linkfiles(%s,%s)\n",from,to);

    for (lastnode = from+strlen(from); *lastnode != '/'; lastnode--) { }

    lastnode++;

    if (IgnoredOrExcluded(links,lastnode,inclusions,exclusions)) {
        Verbose("%s: Skipping non-included pattern %s\n",g_vprefix,from);
        return true;
    }

    if (IsWildItemIn(g_vcopylinks,lastnode) || IsWildItemIn(copy,lastnode)) {
        fakeuid.uid = CF_SAME_OWNER;
        fakeuid.next = NULL;
        ip.plus = CF_SAMEMODE;
        ip.minus = CF_SAMEMODE;
        ip.uid = &fakeuid;
        ip.gid = (struct GidList *) &fakeuid;
        ip.action = "do";
        ip.recurse = 0;
        ip.type = 't';
        ip.defines = ptr->defines;
        ip.elsedef = ptr->elsedef;
        ip.backup = true;
        ip.exclusions = NULL;
        ip.inclusions = NULL;
        ip.symlink = NULL;
        ip.classes = NULL;
        ip.plus_flags = 0;
        ip.size = CF_NOSIZE;
        ip.linktype = 's';
        ip.minus_flags = 0;
        ip.server = strdup("localhost");
        Verbose("%s: Link item %s marked for copying instead\n", 
                g_vprefix, from);
        MakeDirectoriesFor(to,'n');
        CheckImage(to,from,&ip);
        free(ip.server);
        return true;
    }

    /* relative path, must still check if exists */
    if (*to != '/') {
        Debug("Relative link destination detected: %s\n",to);
        strcpy(absto,AbsLinkPath(from,to));
        Debug("Absolute path to relative link = %s, from %s\n",absto,from);
    } else {
        strcpy(absto,to);
    }

    if (!nofile) {
        if (stat(absto,&buf) == -1) {
            /* no error warning, since the higher level routine uses this */
            return(false);
        }
    }

    Debug2("Trying to link %s -> %s (%s)\n",from,to,absto);

    if (lstat(from,&buf) == 0) {
        if (! S_ISLNK(buf.st_mode) && ! g_enforcelinks) {
            snprintf(g_output,CF_BUFSIZE*2,"Error linking %s -> %s\n",from,to);
            CfLog(cfsilent,g_output,"");

            snprintf(g_output, CF_BUFSIZE*2,
                    "Cannot make link: %s exists and is not a link! "
                    "(uid %d)\n", from, buf.st_uid);

            CfLog(cfsilent,g_output,"");
            return(true);
        }

        if (S_ISREG(buf.st_mode) && g_enforcelinks) {
            snprintf(g_output, CF_BUFSIZE*2, "Moving %s to %s%s\n",
                    from, from, CF_SAVED);
            CfLog(cfsilent,g_output,"");

            if (g_dontdo) {
                return true;
            }

            saved[0] = '\0';
            strcpy(saved,from);

            sprintf(stamp, "_%d_%s",
                    g_cfstarttime, CanonifyName(ctime(&STAMPNOW)));
            strcat(saved,stamp);

            strcat(saved,CF_SAVED);

            if (rename(from,saved) == -1) {
                snprintf(g_output, CF_BUFSIZE*2,
                        "Can't rename %s to %s\n", from,saved);
                CfLog(cferror,g_output,"rename");
                return(true);
            }

            if (Repository(saved,g_vrepository)) {
                unlink(saved);
            }
        }

        if (S_ISDIR(buf.st_mode) && g_enforcelinks) {
            snprintf(g_output,CF_BUFSIZE*2,"Moving directory %s to %s%s.dir\n",
                    from,from,CF_SAVED);
            CfLog(cfsilent,g_output,"");

            if (g_dontdo) {
                return true;
            }

            saved[0] = '\0';
            strcpy(saved,from);

            sprintf(stamp, "_%d_%s",
                    g_cfstarttime, CanonifyName(ctime(&STAMPNOW)));
            strcat(saved,stamp);

            strcat(saved,CF_SAVED);
            strcat(saved,".dir");

            if (stat(saved,&savebuf) != -1) {

                snprintf(g_output,CF_BUFSIZE*2,
                        "Couldn't save directory %s, "
                        "since %s exists already\n",
                        from,saved);

                CfLog(cferror,g_output,"");

                snprintf(g_output,CF_BUFSIZE*2,
                        "Unable to force link to "
                        "existing directory %s\n",from);

                CfLog(cferror,g_output,"");
                return true;
            }

            if (rename(from,saved) == -1) {
                snprintf(g_output, CF_BUFSIZE*2, 
                        "Can't rename %s to %s\n", from,saved);
                CfLog(cferror,g_output,"rename");
                return(true);
            }
        }
    }

    memset(linkbuf,0,CF_BUFSIZE);

    if (readlink(from,linkbuf,CF_BUFSIZE-1) == -1) {
        /* link doesn't exist */
        if (! MakeDirectoriesFor(from,'n')) {

            snprintf(g_output,CF_BUFSIZE*2,
                    "Couldn't build directory tree up to %s!\n",from);

            CfLog(cfsilent,g_output,"");

            snprintf(g_output,CF_BUFSIZE*2,
                    "One element was a plain file, not a directory!\n");

            CfLog(cfsilent,g_output,"");
            return(true);
        }
    } else {
        int off1 = 0, off2 = 0;

        DeleteSlash(linkbuf);

        /* Ignore ./ at beginning */
        if (strncmp(linkbuf,"./",2) == 0) {
            off1 = 2;
        }

        if (strncmp(to,"./",2) == 0) {
            off2 = 2;
        }

        if (strcmp(linkbuf+off1,to+off2) != 0) {
            if (g_enforcelinks) {
                snprintf(g_output,CF_BUFSIZE*2,"Removing link %s\n",from);
                CfLog(cfinform,g_output,"");

                if (!g_dontdo) {
                    if (unlink(from) == -1) {
                        perror("unlink");
                        return true;
                    }

                    return DoLink(from,to,ptr->defines);
                }
            } else {

                snprintf(g_output,CF_BUFSIZE*2,
                        "Old link %s points somewhere else. Doing nothing!\n",
                        from);

                CfLog(cfsilent,g_output,"");

                snprintf(g_output, CF_BUFSIZE*2,
                        "(Link points to %s not %s)\n\n",
                        linkbuf,to);

                CfLog(cfsilent,g_output,"");
                return(true);
            }
        } else {
            snprintf(g_output, CF_BUFSIZE*2,
                    "Link (%s->%s) exists.\n", from, to_tmp);
            CfLog(cfverbose,g_output,"");

            if (!nofile) {

                /* Check whether link points somewhere */
                KillOldLink(from,ptr->defines);

                return true;
            }

            AddMultipleClasses(ptr->elsedef);
            return(true);
        }
    }

    return DoLink(from,to,ptr->defines);
}