예제 #1
0
int archwriter_remove(carchwriter *ai)
{
    char volpath[PATH_MAX];
    int count;
    int i;
    
    assert(ai);
    
    if (ai->archfd >= 0)
    {
        archwriter_close(ai);
    }
    
    if (ai->newarch==true)
    {
        count=strlist_count(&ai->vollist);
        for (i=0; i < count; i++)
        {
            if (strlist_getitem(&ai->vollist, i, volpath, sizeof(volpath))==0)
            {
                if (unlink(volpath)==0)
                    msgprintf(MSG_FORCE, "removed %s\n", volpath);
                else
                    errprintf("cannot remove %s\n", volpath);
            }
        }
    }
    return 0;
}
예제 #2
0
파일: path_split.c 프로젝트: rsenn/dirlist
int
path_split(const char* p, strlist* sl) {
  size_t len = str_len(p);
  char sep = ':';
#if WINDOWS
  if(len > 2 && isalnum(p[0]) && p[1] == ':' && path_issep(p[2]))
    sep = ';';
#endif
  strlist_froms(sl, p, sep);
  return strlist_count(sl) > 1;
}
예제 #3
0
파일: env.c 프로젝트: Alexander--/appjail
static void setup_environment_clean(char ***envp, strlist *keep_env, strlist *set_env) {
  size_t n, i;
  const char *key, *val;
  char *nkey, *pos;
  strlist_node *s;

  n = strlist_count(keep_env) + strlist_count(set_env);
  if( (*envp = (char **)malloc((n+1)*sizeof(char*))) == NULL )
    errExit("malloc");

  i = 0;

  for(s = strlist_first(set_env); s != NULL; s = strlist_next(s)) {
    val = strlist_val(s);
    if( (nkey = strdup(val)) == NULL )
      errExit("strdup");
    pos = index(nkey, '=');
    if(pos != NULL && pos != nkey) {
      *pos = '\0';
      strlist_remove(keep_env, nkey);
      *pos = '=';
      (*envp)[i++] = nkey;
    }
    else
      free(nkey);
  }

  for(s = strlist_first(keep_env); s != NULL; s = strlist_next(s)) {
    key = strlist_val(s);
    val = getenv(key);
    if( val != NULL) {
      if( ((*envp)[i] = (char*)malloc((strlen(key) + strlen(val) + 2)*sizeof(char))) == NULL )
        errExit("malloc");
      sprintf((*envp)[i++], "%s=%s", key, val);
    }
  }

  (*envp)[i] = NULL;
}
예제 #4
0
int extfs_mkfs(cdico *d, char *partition, int extfstype, char *fsoptions)
{
    cstrlist strfeatures;
    u64 features_tab[3];
    u64 fsextrevision;
    int origextfstype;
    char buffer[2048];
    char command[2048];
    char options[2048];
    char temp[1024];
    char progname[64];
    u64 e2fstoolsver;
    int compat_type;
    u64 temp64;
    int exitst;
    int ret=0;
    int res;
    int i;
    
    // init    
    memset(options, 0, sizeof(options));
    snprintf(progname, sizeof(progname), "mke2fs");
    strlist_init(&strfeatures);
    
    // ---- check that mkfs is installed and get its version
    if (exec_command(command, sizeof(command), NULL, NULL, 0, NULL, 0, "%s -V", progname)!=0)
    {   errprintf("%s not found. please install a recent e2fsprogs on your system or check the PATH.\n", progname);
        ret=-1;
        goto extfs_mkfs_cleanup;
    }
    e2fstoolsver=check_prog_version(progname);
    
    // ---- filesystem revision (good-old-rev or dynamic)
    if (dico_get_u64(d, 0, FSYSHEADKEY_FSEXTREVISION, &fsextrevision)!=0)
        fsextrevision=EXT2_DYNAMIC_REV; // don't fail (case of fs conversion to extfs)
    
    // "mke2fs -q" prevents problems in exec_command when too many output details printed
    strlcatf(options, sizeof(options), " -q ");
    
    // filesystem revision: good-old-rev or dynamic
    strlcatf(options, sizeof(options), " -r %d ", (int)fsextrevision);

    strlcatf(options, sizeof(options), " %s ", fsoptions);
    
    // ---- set the advanced filesystem settings from the dico
    if (dico_get_string(d, 0, FSYSHEADKEY_FSLABEL, buffer, sizeof(buffer))==0 && strlen(buffer)>0)
        strlcatf(options, sizeof(options), " -L '%.16s' ", buffer);
    
    if (dico_get_u64(d, 0, FSYSHEADKEY_FSEXTBLOCKSIZE, &temp64)==0)
        strlcatf(options, sizeof(options), " -b %ld ", (long)temp64);
    
    if (dico_get_u64(d, 0, FSYSHEADKEY_FSINODESIZE, &temp64)==0)
        strlcatf(options, sizeof(options), " -I %ld ", (long)temp64);
    
    // ---- get original filesystem features (if the original filesystem was an ext{2,3,4})
    if (dico_get_u64(d, 0, FSYSHEADKEY_FSEXTFEATURECOMPAT, &features_tab[E2P_FEATURE_COMPAT])!=0 ||
        dico_get_u64(d, 0, FSYSHEADKEY_FSEXTFEATUREINCOMPAT, &features_tab[E2P_FEATURE_INCOMPAT])!=0 ||
        dico_get_u64(d, 0, FSYSHEADKEY_FSEXTFEATUREROCOMPAT, &features_tab[E2P_FEATURE_RO_INCOMPAT])!=0)
    {   // dont fail the original filesystem may not be ext{2,3,4}. in that case set defaults features
        features_tab[E2P_FEATURE_COMPAT]=EXT2_FEATURE_COMPAT_RESIZE_INODE|EXT2_FEATURE_COMPAT_DIR_INDEX;
        features_tab[E2P_FEATURE_INCOMPAT]=EXT2_FEATURE_INCOMPAT_FILETYPE;
        features_tab[E2P_FEATURE_RO_INCOMPAT]=EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
    }
    
    // ---- check that fsarchiver is aware of all the filesystem features used on that filesystem
    if (extfs_check_compatibility(features_tab[E2P_FEATURE_COMPAT], features_tab[E2P_FEATURE_INCOMPAT], features_tab[E2P_FEATURE_RO_INCOMPAT])!=0)
    {   errprintf("this filesystem has ext{2,3,4} features which are not supported by this fsarchiver version.\n");
        return -1;
    }
    
    // ---- get original filesystem type
    origextfstype=extfs_get_fstype_from_compat_flags(features_tab[E2P_FEATURE_COMPAT], 
            features_tab[E2P_FEATURE_INCOMPAT], features_tab[E2P_FEATURE_RO_INCOMPAT]);
    msgprintf(MSG_VERB2, "the filesystem type determined by the original filesystem features is [%s]\n", format_fstype(origextfstype));
    
    // remove all the features not supported by the filesystem to create (conversion = downgrade fs)
    for (i=0; mkfeatures[i].name; i++)
    {
        compat_type=mkfeatures[i].compat;
        if (mkfeatures[i].firstfs > extfstype)
            features_tab[compat_type] &= ~mkfeatures[i].mask;
    }
    
    // add new features if the filesystem to create is newer than the filesystem type that was backed up
    // eg: user did a "savefs" of an ext3 and does a "restfs mkfs=ext4" --> add features to force ext4
    // it's a bit more difficult because we only want to add such a feature if no feature of the new
    // filesystem is currently enabled.
    msgprintf(MSG_VERB2, "the filesystem type to create considering the command options is [%s]\n", format_fstype(extfstype));
    if (origextfstype==EXTFSTYPE_EXT2 && extfstype>EXTFSTYPE_EXT2) // upgrade ext2 to ext{3,4}
    {   fsextrevision=EXT2_DYNAMIC_REV;
        features_tab[E2P_FEATURE_COMPAT]|=EXT3_FEATURE_COMPAT_HAS_JOURNAL;
    }
    if (origextfstype<EXTFSTYPE_EXT4 && extfstype>=EXTFSTYPE_EXT4) // upgrade ext{2,3} to ext4
    {   fsextrevision=EXT2_DYNAMIC_REV;
        features_tab[E2P_FEATURE_INCOMPAT]|=EXT3_FEATURE_INCOMPAT_EXTENTS;
    }
    
    // convert int features to string to be passed to mkfs
    for (i=0; mkfeatures[i].name; i++)
    {
        if (mkfeatures[i].firste2p<=e2fstoolsver) // don't pass an option to a program that does not support it
        {
            compat_type=mkfeatures[i].compat;
            if (features_tab[compat_type] & mkfeatures[i].mask)
            {   msgprintf(MSG_VERB2, "--> feature [%s]=YES\n", mkfeatures[i].name);
                strlist_add(&strfeatures, mkfeatures[i].name);
            }
            else
            {   msgprintf(MSG_VERB2, "--> feature [%s]=NO\n", mkfeatures[i].name);
                snprintf(temp, sizeof(temp), "^%s", mkfeatures[i].name); // exclude feature
                strlist_add(&strfeatures, temp);
            }
        }
    }
    
    // if extfs revision is dynamic and there are features in the list
    if (fsextrevision!=EXT2_GOOD_OLD_REV && strlist_count(&strfeatures)>0)
    {   strlist_merge(&strfeatures, temp, sizeof(temp), ',');
        strlcatf(options, sizeof(options), " -O %s ", temp);
        msgprintf(MSG_VERB2, "features: mkfs_options+=[-O %s]\n", temp);
    }
    
    // ---- check mke2fs version requirement
    msgprintf(MSG_VERB2, "mke2fs version detected: %s\n", format_prog_version(e2fstoolsver, temp, sizeof(temp)));
    msgprintf(MSG_VERB2, "mke2fs version required: %s\n", format_prog_version(e2fsprogs_minver[extfstype], temp, sizeof(temp)));
    if (e2fstoolsver < e2fsprogs_minver[extfstype])
    {   errprintf("mke2fs was found but is too old, please upgrade to a version %s or more recent.\n", 
            format_prog_version(e2fsprogs_minver[extfstype], temp, sizeof(temp)));
        ret=-1;
        goto extfs_mkfs_cleanup;
    }
    
    // ---- extended options
    if (dico_get_u64(d, 0, FSYSHEADKEY_FSEXTEOPTRAIDSTRIDE, &temp64)==0)
        strlcatf(options, sizeof(options), " -E stride=%ld ", (long)temp64);
    if ((dico_get_u64(d, 0, FSYSHEADKEY_FSEXTEOPTRAIDSTRIPEWIDTH, &temp64)==0) && e2fstoolsver>=PROGVER(1,40,7))
        strlcatf(options, sizeof(options), " -E stripe-width=%ld ", (long)temp64);
    
    // ---- execute mke2fs
    msgprintf(MSG_VERB2, "exec: %s\n", command);
    if (exec_command(command, sizeof(command), &exitst, NULL, 0, NULL, 0, "%s %s %s", progname, partition, options)!=0 || exitst!=0)
    {   errprintf("command [%s] failed with return status=%d\n", command, exitst);
        ret=-1;
        goto extfs_mkfs_cleanup;
    }
    
    // ---- use tune2fs to set the other advanced options
    memset(options, 0, sizeof(options));
    if (dico_get_string(d, 0, FSYSHEADKEY_FSUUID, buffer, sizeof(buffer))==0 && strlen(buffer)==36)
        strlcatf(options, sizeof(options), " -U %s ", buffer);
    
    if (dico_get_string(d, 0, FSYSHEADKEY_FSEXTDEFMNTOPT, buffer, sizeof(buffer))==0 && strlen(buffer)>0)
        strlcatf(options, sizeof(options), " -o %s ", buffer);
    
    if (dico_get_u64(d, 0, FSYSHEADKEY_FSEXTFSCKMAXMNTCOUNT, &temp64)==0)
        strlcatf(options, sizeof(options), " -c %ld ", (long)temp64);
    
    if (dico_get_u64(d, 0, FSYSHEADKEY_FSEXTFSCKCHECKINTERVAL, &temp64)==0)
        strlcatf(options, sizeof(options), " -i %ldd ", (long)(temp64/86400L));
    
    if (options[0])
    {
        if (exec_command(command, sizeof(command), &exitst, NULL, 0, NULL, 0, "tune2fs %s %s", partition, options)!=0 || exitst!=0)
        {   errprintf("command [%s] failed with return status=%d\n", command, exitst);
            ret=-1;
            goto extfs_mkfs_cleanup;
        }
        
        // run e2fsck to workaround an tune2fs bug in e2fsprogs < 1.41.4 on ext4
        // http://article.gmane.org/gmane.comp.file-systems.ext4/11181
        if (extfstype==EXTFSTYPE_EXT4 && e2fstoolsver<PROGVER(1,41,4))
        {
            if ( ((res=exec_command(command, sizeof(command), &exitst, NULL, 0, NULL, 0, "e2fsck -fy %s", partition))!=0) || ((exitst!=0) && (exitst!=1)) )
            {   errprintf("command [%s] failed with return status=%d\n", command, exitst);
                ret=-1;
                goto extfs_mkfs_cleanup;
            }
        }
    }
    
extfs_mkfs_cleanup:
    strlist_destroy(&strfeatures);
    return ret;
}