Example #1
0
void Table::ajouter(unsigned int sock, std::string nom)
{
  ENTER("ajouter(unsigned int sock, std::string nom)");
  ADD_ARG("sock", sock);
  ADD_ARG("nom", nom);
  unsigned int i = 0;
  while(i < joueurs.size() && joueurs[i] >= 0) i++;
  if(i < joueurs.size())
    {
      joueurs[i] = sock;
      noms[i] = nom;
      //Si on est complet, on lance la partie
      i = 0 ;
      while(i < joueurs.size() && joueurs[i] >= 0) i++;
      if(i >= joueurs.size())
	{
	  DEBUG<<"La partie commence..."<<std::endl;
	  doit_recommencer();
	  emit complet(this);
	}
    }
  else
    {
      //En fait, la table était déjà pleine !
      ERROR<<"Erreur : la table est pleine."<<std::endl;
      emit complet(this);
      emit doit_deconnecter(sock);
      //Sinon, la socket sera perdue
    }
  DEBUG<<"Joueurs : "<<joueurs<<std::endl;
  DEBUG<<"Noms : "<<noms<<std::endl;
  DEBUG<<"Ordres : "<<ordre<<std::endl;
}
Example #2
0
int
do_wipefs (const char *device)
{
  int force;
  int r;
  CLEANUP_FREE char *err = NULL;
  const size_t MAX_ARGS = 16;
  const char *argv[MAX_ARGS];
  size_t i = 0;

  force = wipefs_has_force_option ();
  if (force == -1)
    return -1;

  ADD_ARG (argv, i, str_wipefs);
  ADD_ARG (argv, i, "-a");
  if (force)
    ADD_ARG (argv, i, "--force");
  ADD_ARG (argv, i, device);
  ADD_ARG (argv, i, NULL);

  r = commandv (NULL, &err, argv);
  if (r == -1) {
    reply_with_error ("%s", err);
    return -1;
  }

  return 0;
}
Example #3
0
/* Takes optional arguments, consult optargs_bitmask. */
int
do_ntfsfix (const char *device, int clearbadsectors)
{
  const char *argv[MAX_ARGS];
  size_t i = 0;
  int r;
  CLEANUP_FREE char *err = NULL;

  ADD_ARG (argv, i, str_ntfsfix);

  if ((optargs_bitmask & GUESTFS_NTFSFIX_CLEARBADSECTORS_BITMASK) &&
      clearbadsectors)
    ADD_ARG (argv, i, "-b");

  ADD_ARG (argv, i, device);
  ADD_ARG (argv, i, NULL);

  r = commandv (NULL, &err, argv);
  if (r == -1) {
    reply_with_error ("%s: %s", device, err);
    return -1;
  }

  return 0;
}
Example #4
0
void Table::comprendre(unsigned int sock, Protocole::Message m)
{
  ENTER("comprendre(unsigned int sock, Message m)");
  ADD_ARG("sock", sock);
  ADD_ARG("m", m);
  //Attention : je ne suis pas sûr que sock fasse partie de la table !
  for(unsigned int i = 0 ; i < joueurs.size() ; i++)
    {
      if(joueurs[ordre[i]] == (int)sock)
	{
	  Protocole::Message reponse;
	  switch(partie.tester(i, m))
	    {
	    case 1 :
	      reponse.type = Protocole::ERREUR_PROTOCOLE;
	      DEBUG<<"Erreur de protocole détectée."<<std::endl;
	      emit doit_emettre(sock, reponse);
	      break;
	    case 2 :
	      reponse.type = Protocole::REFUSE;
	      emit doit_emettre(sock, reponse);
	      break;
	    default :
	      partie.assimiler(m);
	    }
	  i = joueurs.size();
	}
    }
}
Example #5
0
/* Internal function used to wipe disks before we do 'mkfs'-type
 * operations on them.  For the rationale see RHBZ#889888 and
 * RHBZ#907554.
 *
 * Note this is really destructive, so only call it just before doing
 * the 'mkfs' operation (ie. after doing as much pre-checking as
 * possible).  Otherwise you could end up with a 'mkfs' operation
 * failing with an error but still wiping data.
 */
void
wipe_device_before_mkfs (const char *device)
{
  int force;
  const size_t MAX_ARGS = 16;
  const char *argv[MAX_ARGS];
  size_t i = 0;

  force = wipefs_has_force_option ();
  if (force == -1)
    return;

  ADD_ARG (argv, i, str_wipefs);
  ADD_ARG (argv, i, "-a");
  if (force)
    ADD_ARG (argv, i, "--force");
  ADD_ARG (argv, i, device);
  ADD_ARG (argv, i, NULL);

  ignore_value (commandv (NULL, NULL, argv));

  /* XXX We could fall back to overwriting bits of disk here, but if
   * they don't have working wipefs, it seems unlikely they are using
   * btrfs which is what mostly causes this problem.  See:
   * http://www.spinics.net/lists/linux-btrfs/msg21197.html
   */
}
Example #6
0
int
do_luks_kill_slot (const char *device, const char *key, int keyslot)
{
  char *tempfile = write_key_to_temp (key);
  if (!tempfile)
    return -1;

  const char *argv[MAX_ARGS];
  char keyslot_s[16];
  size_t i = 0;

  ADD_ARG (argv, i, str_cryptsetup);
  ADD_ARG (argv, i, "-q");
  ADD_ARG (argv, i, "-d");
  ADD_ARG (argv, i, tempfile);
  ADD_ARG (argv, i, "luksKillSlot");
  ADD_ARG (argv, i, device);
  snprintf (keyslot_s, sizeof keyslot_s, "%d", keyslot);
  ADD_ARG (argv, i, keyslot_s);
  ADD_ARG (argv, i, NULL);

  char *err;
  int r = commandv (NULL, &err, (const char * const *) argv);
  remove_temp (tempfile);

  if (r == -1) {
    reply_with_error ("%s", err);
    free (err);
    return -1;
  }

  free (err);

  return 0;
}
Example #7
0
void Table::doit_transmettre(unsigned int j, Protocole::Message m,
			     bool analyser)
{
  ENTER("doit_transmettre(unsigned int j, Protocole::Message m, bool analyser)");
  ADD_ARG("j", j);
  ADD_ARG("m", m);
  ADD_ARG("analyser", analyser);
  DEBUG<<"Transmission à "<<j<<std::endl;
  DEBUG<<"Joueurs : "<<joueurs<<std::endl;
  DEBUG<<"Noms : "<<noms<<std::endl;
  DEBUG<<"Ordres : "<<ordre<<std::endl;
  emit doit_emettre(joueurs[ordre[j]], m);
  if(analyser)
    partie.assimiler(m);
}
Example #8
0
void libpd_add_symbol(const char *s) {
  t_symbol *x;
  sys_lock();
  x = gensym(s);
  sys_unlock();
  ADD_ARG(SETSYMBOL);
}
Example #9
0
void Table::enlever(unsigned int sock)
{
  ENTER("enlever(unsigned int sock)");
  ADD_ARG("sock", sock);
  //Attention : sock ne fait peut-être pas partie de la table !
  unsigned int i = 0 ;
  while(i < joueurs.size() && 
	(joueurs[i] < 0 || (unsigned int)joueurs[i] != sock)) i++;
  if(i < joueurs.size())
    {
      joueurs[i] = -1 ;
      noms[i] = "";
      //Comptons les joueurs restants. S'ils sont 4, il faut envoyer
      //le signal incomplet.
      unsigned int j = 0 ;
      for(unsigned int k = 0 ; k < joueurs.size() ; k++)
	if(joueurs[k]>=0) j++;
      if(j == 4)
	{
	  //On vire tout le monde. Ça fait un paquet d'appels
	  //récursifs, mais tant pis.
	  for(unsigned int i = 0 ; i < joueurs.size() ; i++)
	    {
	      if(joueurs[i]>=0)
		{
		  DEBUG<<"Déconnexion de "<<joueurs[i]<<std::endl;
		  emit doit_deconnecter(joueurs[i]);
		}
	    }
	  DEBUG<<"Émission de Table::incomplet(Table *)..."<<std::endl;
	  emit incomplet(this);
	}
    } 
}
Example #10
0
Table::Table(QObject * parent) : QObject(parent)
{
  ENTER("Table(QObject * parent)");
  ADD_ARG("parent", parent);
  //Création des ordres :
  for(int i = 0 ; i < 5 ; i++)
    {
      joueurs.push_back(-1); // -1 : pas de joueur
      ordre.push_back(i);
      noms.push_back("");
    }
  //Mélange de ordre :
  int r = 0 ;
  int tmp;
  for(unsigned int i = 1 ; i < ordre.size() ; i++)
    {
      r = rand() % (i + 1) ;
      //échange des cases i et r
      tmp = ordre[r];
      ordre[r] = ordre[i];
      ordre[i] = tmp;
    }
  QObject::connect(&partie, SIGNAL(doit_emettre
				   (unsigned int, Protocole::Message, bool)),
		   this, SLOT(doit_transmettre
			      (unsigned int, Protocole::Message, bool)));
  QObject::connect(&partie, SIGNAL(termine()), this, SLOT(doit_recommencer()));
  nombre_tables++;
  DEBUG<<"Il y a maintenant "<<nombre_tables<<" table(s)."<<std::endl;
}
Example #11
0
static int
luks_format (const char *device, const char *key, int keyslot,
             const char *cipher)
{
  char *tempfile = write_key_to_temp (key);
  if (!tempfile)
    return -1;

  const char *argv[MAX_ARGS];
  char keyslot_s[16];
  size_t i = 0;

  ADD_ARG (argv, i, str_cryptsetup);
  ADD_ARG (argv, i, "-q");
  if (cipher) {
    ADD_ARG (argv, i, "--cipher");
    ADD_ARG (argv, i, cipher);
  }
  ADD_ARG (argv, i, "--key-slot");
  snprintf (keyslot_s, sizeof keyslot_s, "%d", keyslot);
  ADD_ARG (argv, i, keyslot_s);
  ADD_ARG (argv, i, "luksFormat");
  ADD_ARG (argv, i, device);
  ADD_ARG (argv, i, tempfile);
  ADD_ARG (argv, i, NULL);

  char *err;
  int r = commandv (NULL, &err, (const char * const *) argv);
  remove_temp (tempfile);

  if (r == -1) {
    reply_with_error ("%s", err);
    free (err);
    return -1;
  }

  free (err);

  udev_settle ();

  return 0;
}
Example #12
0
static int
rsync (const char *src, const char *src_orig,
       const char *dest, const char *dest_orig,
       int archive, int deletedest)
{
  const char *argv[MAX_ARGS];
  size_t i = 0;
  int r;
  CLEANUP_FREE char *err = NULL;

  ADD_ARG (argv, i, str_rsync);

  if (archive)
    ADD_ARG (argv, i, "--archive");

  if (deletedest)
    ADD_ARG (argv, i, "--delete");

  ADD_ARG (argv, i, src);
  ADD_ARG (argv, i, dest);
  ADD_ARG (argv, i, NULL);

  r = commandv (NULL, &err, argv);
  if (r == -1) {
    reply_with_error ("'%s' to '%s': %s", src_orig, dest_orig, err);
    return -1;
  }

  return 0;
}
Example #13
0
static int
luks_open (const char *device, const char *key, const char *mapname,
           int readonly)
{
  /* Sanity check: /dev/mapper/mapname must not exist already.  Note
   * that the device-mapper control device (/dev/mapper/control) is
   * always there, so you can't ever have mapname == "control".
   */
  size_t len = strlen (mapname);
  char devmapper[len+32];
  snprintf (devmapper, len+32, "/dev/mapper/%s", mapname);
  if (access (devmapper, F_OK) == 0) {
    reply_with_error ("%s: device already exists", devmapper);
    return -1;
  }

  char *tempfile = write_key_to_temp (key);
  if (!tempfile)
    return -1;

  const char *argv[MAX_ARGS];
  size_t i = 0;

  ADD_ARG (argv, i, str_cryptsetup);
  ADD_ARG (argv, i, "-d");
  ADD_ARG (argv, i, tempfile);
  if (readonly) ADD_ARG (argv, i, "--readonly");
  ADD_ARG (argv, i, "luksOpen");
  ADD_ARG (argv, i, device);
  ADD_ARG (argv, i, mapname);
  ADD_ARG (argv, i, NULL);

  char *err;
  int r = commandv (NULL, &err, (const char * const *) argv);
  remove_temp (tempfile);

  if (r == -1) {
    reply_with_error ("%s", err);
    free (err);
    return -1;
  }

  free (err);

  udev_settle ();

  return 0;
}
Example #14
0
/* Takes optional arguments, consult optargs_bitmask. */
int
do_mkswap (const char *device, const char *label, const char *uuid)
{
  const size_t MAX_ARGS = 64;
  const char *argv[MAX_ARGS];
  size_t i = 0;
  int r;
  CLEANUP_FREE char *err = NULL;

  ADD_ARG (argv, i, "mkswap");
  ADD_ARG (argv, i, "-f");

  if (optargs_bitmask & GUESTFS_MKSWAP_LABEL_BITMASK) {
    assert (label != NULL); /* suppress a warning with -O3 */
    if (strlen (label) > SWAP_LABEL_MAX) {
      reply_with_error ("%s: Linux swap labels are limited to %d bytes",
                        label, SWAP_LABEL_MAX);
      return -1;
    }

    ADD_ARG (argv, i, "-L");
    ADD_ARG (argv, i, label);
  }

  if (optargs_bitmask & GUESTFS_MKSWAP_UUID_BITMASK) {
    ADD_ARG (argv, i, "-U");
    ADD_ARG (argv, i, uuid);
  }

  ADD_ARG (argv, i, device);
  ADD_ARG (argv, i, NULL);

  wipe_device_before_mkfs (device);

  r = commandv (NULL, &err, argv);
  if (r == -1) {
    reply_with_error ("%s: %s", device, err);
    return -1;
  }

  udev_settle ();

  return 0;
}
Example #15
0
/* Takes optional arguments, consult optargs_bitmask. */
int
do_e2fsck (const char *device,
           int correct,
           int forceall)
{
    const char *argv[MAX_ARGS];
    CLEANUP_FREE char *err = NULL;
    size_t i = 0;
    int r;

    /* Default if not selected. */
    if (!(optargs_bitmask & GUESTFS_E2FSCK_CORRECT_BITMASK))
        correct = 0;
    if (!(optargs_bitmask & GUESTFS_E2FSCK_FORCEALL_BITMASK))
        forceall = 0;

    if (correct && forceall) {
        reply_with_error ("only one of the options 'correct', 'forceall' may be specified");
        return -1;
    }

    ADD_ARG (argv, i, str_e2fsck);
    ADD_ARG (argv, i, "-f");

    if (correct)
        ADD_ARG (argv, i, "-p");

    if (forceall)
        ADD_ARG (argv, i, "-y");

    ADD_ARG (argv, i, device);
    ADD_ARG (argv, i, NULL);

    r = commandrvf (NULL, &err,
                    COMMAND_FLAG_FOLD_STDOUT_ON_STDERR,
                    argv);
    /* 0 = no errors, 1 = errors corrected.
     *
     * >= 4 means uncorrected or other errors.
     *
     * 2, 3 means errors were corrected and we require a reboot.  This is
     * a difficult corner case.
     */
    if (r == -1 || r >= 2) {
        reply_with_error ("%s", err);
        return -1;
    }

    return 0;
}
Example #16
0
/* Takes optional arguments, consult optargs_bitmask. */
int
do_ntfsresize (const char *device, int64_t size, int force)
{
  char *err;
  int r;
  const char *argv[MAX_ARGS];
  size_t i = 0;
  char size_str[32];

  ADD_ARG (argv, i, str_ntfsresize);
  ADD_ARG (argv, i, "-P");

  if (optargs_bitmask & GUESTFS_NTFSRESIZE_SIZE_BITMASK) {
    if (size <= 0) {
      reply_with_error ("size is zero or negative");
      return -1;
    }

    snprintf (size_str, sizeof size_str, "%" PRIi64, size);
    ADD_ARG (argv, i, "--size");
    ADD_ARG (argv, i, size_str);
  }

  if (optargs_bitmask & GUESTFS_NTFSRESIZE_FORCE_BITMASK && force)
    ADD_ARG (argv, i, "--force");

  ADD_ARG (argv, i, device);
  ADD_ARG (argv, i, NULL);

  r = commandv (NULL, &err, argv);
  if (r == -1) {
    reply_with_error ("%s: %s", device, err);
    free (err);
    return -1;
  }

  free (err);
  return 0;
}
Example #17
0
/* generate arguments to create OpenVZ container
   return -1 - error
           0 - OK
*/
static int
openvzDomainDefineCmd(const char *args[],
                      int maxarg, virDomainDefPtr vmdef)
{
    int narg;

    for (narg = 0; narg < maxarg; narg++)
        args[narg] = NULL;

    if (vmdef == NULL) {
        openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
                    _("Container is not defined"));
        return -1;
    }

#define ADD_ARG(thisarg)                                                \
    do {                                                                \
        if (narg >= maxarg)                                             \
                 goto no_memory;                                        \
        args[narg++] = thisarg;                                         \
    } while (0)

#define ADD_ARG_LIT(thisarg)                                            \
    do {                                                                \
        if (narg >= maxarg)                                             \
                 goto no_memory;                                        \
        if ((args[narg++] = strdup(thisarg)) == NULL)                   \
            goto no_memory;                                             \
    } while (0)

    narg = 0;
    ADD_ARG_LIT(VZCTL);
    ADD_ARG_LIT("--quiet");
    ADD_ARG_LIT("create");

    ADD_ARG_LIT(vmdef->name);
    ADD_ARG_LIT("--name");
    ADD_ARG_LIT(vmdef->name);

    if (vmdef->nfss == 1 &&
        vmdef->fss[0]->type == VIR_DOMAIN_FS_TYPE_TEMPLATE) {
        ADD_ARG_LIT("--ostemplate");
        ADD_ARG_LIT(vmdef->fss[0]->src);
    }
#if 0
    if ((vmdef->profile && *(vmdef->profile))) {
        ADD_ARG_LIT("--config");
        ADD_ARG_LIT(vmdef->profile);
    }
#endif

    ADD_ARG(NULL);
    return 0;

no_memory:
    openvzError(VIR_ERR_INTERNAL_ERROR,
                _("Could not put argument to %s"), VZCTL);
    return -1;

#undef ADD_ARG
#undef ADD_ARG_LIT
}
Example #18
0
static int
mount_fstype(fsu_fs_t *fs, const char *fsdev, char *mntopts, char *puffsexec,
    char *specopts, struct mount_data_s *mntdp, int verbose)
{
	int argvlen;

	mntdp->mntd_fs = fs;
	mntdp->mntd_argc = mntdp->mntd_flags = 0;

	argvlen = 7;
	if (specopts != NULL)
		argvlen += fsu_str2argc(specopts);

	if (argvlen > mntdp->mntd_argv_size) {
		char **tmp;

		tmp = realloc(mntdp->mntd_argv, argvlen * sizeof(char *));
		if (tmp == NULL) {
			if (mntdp->mntd_argv != NULL)
				free(mntdp->mntd_argv);
			return -1;
		}
		mntdp->mntd_argv = tmp;
		mntdp->mntd_argv_size = argvlen;
	}

	/* setting up the argv array */
	ADD_ARG(mntdp, __UNCONST(getprogname()));

#ifdef WITH_SYSPUFFS
	if (puffsexec != NULL && fs->fs_name == MOUNT_PUFFS)
		ADD_ARG(mntdp, puffsexec);
#endif

	if (mntopts != NULL) {
		ADD_ARG(mntdp, __UNCONST("-o"));
		ADD_ARG(mntdp, mntopts);
	}
	if (specopts != NULL) {
		int tmpargc;

		fsu_str2arg(specopts, &tmpargc,
		    mntdp->mntd_argv + mntdp->mntd_argc, argvlen - 6);
		mntdp->mntd_argc += tmpargc;
	}
	ADD_ARG(mntdp, __UNCONST(fsdev));
	ADD_ARG(mntdp, __UNCONST("/"));
	mntdp->mntd_argv[mntdp->mntd_argc] = NULL;

	/* filesystem given */
	if (fs != NULL)
		return mount_struct(verbose, mntdp);

	/* filesystem not given (auto detection) */
	for (fs = fslist; fs->fs_name != NULL; ++fs) {
		if (verbose)
			printf("Trying with fs %s\n", fs->fs_name);
		if (fs->fs_flags & FS_NO_AUTO)
			continue;
		mntdp->mntd_flags = 0;
		mntdp->mntd_fs = fs;
		if (mount_struct(verbose > 1, mntdp) == 0)
			return 0;
	}
	return -1;
}
Example #19
0
/* Takes optional arguments, consult optargs_bitmask. */
int
do_mkfs_opts (const char *fstype, const char *device, int blocksize,
              const char *features, int inode, int sectorsize)
{
  const char *argv[MAX_ARGS];
  size_t i = 0;
  char blocksize_str[32];
  char inode_str[32];
  char sectorsize_str[32];
  int r;
  char *err;
  char mke2fs[] = "mke2fs";
  int extfs = 0;

  if (STREQ (fstype, "ext2") || STREQ (fstype, "ext3") ||
      STREQ (fstype, "ext4"))
    extfs = 1;

  /* For ext2/3/4 run the mke2fs program directly.  This is because
   * the mkfs program "eats" some options, in particular the -F
   * option.
   */
  if (extfs) {
    if (e2prog (mke2fs) == -1)
      return -1;
    ADD_ARG (argv, i, mke2fs);
  }
  else
    ADD_ARG (argv, i, "mkfs");

  ADD_ARG (argv, i, "-t");
  ADD_ARG (argv, i, fstype);

  /* Force mke2fs to create a filesystem, even if it thinks it
   * shouldn't (RHBZ#690819).
   */
  if (extfs)
    ADD_ARG (argv, i, "-F");

  /* mkfs.ntfs requires the -Q argument otherwise it writes zeroes
   * to every block and does bad block detection, neither of which
   * are useful behaviour for virtual devices.
   */
  if (STREQ (fstype, "ntfs"))
    ADD_ARG (argv, i, "-Q");

  /* mkfs.reiserfs produces annoying interactive prompts unless you
   * tell it to be quiet.
   * mkfs.jfs is the same
   * mkfs.xfs must force to make xfs filesystem when the device already
   * has a filesystem on it
   */
  if (STREQ (fstype, "reiserfs") || STREQ (fstype, "jfs") ||
      STREQ (fstype, "xfs"))
    ADD_ARG(argv, i, "-f");

  /* For GFS, GFS2, assume a single node. */
  if (STREQ (fstype, "gfs") || STREQ (fstype, "gfs2")) {
    ADD_ARG (argv, i, "-p");
    ADD_ARG (argv, i, "lock_nolock");
    /* The man page says this is default, but it doesn't seem to be: */
    ADD_ARG (argv, i, "-j");
    ADD_ARG (argv, i, "1");
    /* Don't ask questions: */
    ADD_ARG (argv, i, "-O");
  }

  /* Process blocksize parameter if set. */
  if (optargs_bitmask & GUESTFS_MKFS_OPTS_BLOCKSIZE_BITMASK) {
    if (blocksize <= 0 || !is_power_of_2 (blocksize)) {
      reply_with_error ("block size must be > 0 and a power of 2");
      return -1;
    }

    if (STREQ (fstype, "vfat") ||
        STREQ (fstype, "msdos")) {
      /* For VFAT map the blocksize into a cluster size.  However we
       * have to determine the block device sector size in order to do
       * this.
       */
      int sectorsize = do_blockdev_getss (device);
      if (sectorsize == -1)
        return -1;

      int sectors_per_cluster = blocksize / sectorsize;
      if (sectors_per_cluster < 1 || sectors_per_cluster > 128) {
        reply_with_error ("unsupported cluster size for %s filesystem (requested cluster size = %d, sector size = %d, trying sectors per cluster = %d)",
                          fstype, blocksize, sectorsize, sectors_per_cluster);
        return -1;
      }

      snprintf (blocksize_str, sizeof blocksize_str, "%d", sectors_per_cluster);
      ADD_ARG (argv, i, "-s");
      ADD_ARG (argv, i, blocksize_str);
    }
    else if (STREQ (fstype, "ntfs")) {
      /* For NTFS map the blocksize into a cluster size. */
      snprintf (blocksize_str, sizeof blocksize_str, "%d", blocksize);
      ADD_ARG (argv, i, "-c");
      ADD_ARG (argv, i, blocksize_str);
    }
    else {
      /* For all other filesystem types, try the -b option. */
      snprintf (blocksize_str, sizeof blocksize_str, "%d", blocksize);
      ADD_ARG (argv, i, "-b");
      ADD_ARG (argv, i, blocksize_str);
    }
  }

  if (optargs_bitmask & GUESTFS_MKFS_OPTS_FEATURES_BITMASK) {
    ADD_ARG (argv, i, "-O");
    ADD_ARG (argv, i, features);
  }

  if (optargs_bitmask & GUESTFS_MKFS_OPTS_INODE_BITMASK) {
    if (!extfs) {
      reply_with_error ("inode size (-I) can only be set on ext2/3/4 filesystems");
      return -1;
    }

    if (inode <= 0) {
      reply_with_error ("inode size must be larger than zero");
      return -1;
    }

    snprintf (inode_str, sizeof inode_str, "%d", inode);
    ADD_ARG (argv, i, "-I");
    ADD_ARG (argv, i, inode_str);
  }

  if (optargs_bitmask & GUESTFS_MKFS_OPTS_SECTORSIZE_BITMASK) {
    if (!STREQ (fstype, "ufs")) {
      reply_with_error ("sector size (-S) can only be set on ufs filesystems");
      return -1;
    }

    if (sectorsize <= 0) {
      reply_with_error ("sector size must be larger than zero");
      return -1;
    }

    snprintf (sectorsize_str, sizeof sectorsize_str, "%d", sectorsize);
    ADD_ARG (argv, i, "-S");
    ADD_ARG (argv, i, sectorsize_str);
  }

  ADD_ARG (argv, i, device);
  ADD_ARG (argv, i, NULL);

  r = commandv (NULL, &err, argv);
  if (r == -1) {
    reply_with_error ("%s: %s: %s", fstype, device, err);
    free (err);
    return -1;
  }

  free (err);
  return 0;
}
Example #20
0
int
do_xfs_admin (const char *device,
              int extunwritten, int imgfile, int v2log,
              int projid32bit,
              int lazycounter, const char *label, const char *uuid)
{
  int r;
  CLEANUP_FREE char *err = NULL;
  const char *argv[MAX_ARGS];
  size_t i = 0;

  ADD_ARG (argv, i, str_xfs_admin);

  /* Optional arguments */
  if (!(optargs_bitmask & GUESTFS_XFS_ADMIN_EXTUNWRITTEN_BITMASK))
    extunwritten = 0;
  if (!(optargs_bitmask & GUESTFS_XFS_ADMIN_IMGFILE_BITMASK))
    imgfile = 0;
  if (!(optargs_bitmask & GUESTFS_XFS_ADMIN_V2LOG_BITMASK))
    v2log = 0;
  if (!(optargs_bitmask & GUESTFS_XFS_ADMIN_PROJID32BIT_BITMASK))
    projid32bit = 0;

  if (extunwritten)
    ADD_ARG (argv, i, "-e");
  if (imgfile)
    ADD_ARG (argv, i, "-f");
  if (v2log)
    ADD_ARG (argv, i, "-j");
  if (projid32bit)
    ADD_ARG (argv, i, "-p");

  if (optargs_bitmask & GUESTFS_XFS_ADMIN_LAZYCOUNTER_BITMASK) {
    if (lazycounter) {
      ADD_ARG (argv, i, "-c");
      ADD_ARG (argv, i, "1");
    } else {
      ADD_ARG (argv, i, "-c");
      ADD_ARG (argv, i, "0");
    }
  }

  if (optargs_bitmask & GUESTFS_XFS_ADMIN_LABEL_BITMASK) {
    if (strlen (label) > XFS_LABEL_MAX) {
      reply_with_error ("%s: xfs labels are limited to %d bytes",
                        label, XFS_LABEL_MAX);
      return -1;
    }

    ADD_ARG (argv, i, "-L");
    ADD_ARG (argv, i, label);
  }

  if (optargs_bitmask & GUESTFS_XFS_ADMIN_UUID_BITMASK) {
    ADD_ARG (argv, i, "-U");
    ADD_ARG (argv, i, uuid);
  }

  ADD_ARG (argv, i, device);
  ADD_ARG (argv, i, NULL);

  r = commandv (NULL, &err, argv);
  if (r == -1) {
    reply_with_error ("%s: %s", device, err);
    return -1;
  }

  return 0;
}
Example #21
0
static int
mount_alias(struct fsu_fsalias_s *al, char *mntopts, char *specopts,
    struct mount_data_s *mntdp, int verbose)
{
	fsu_fs_t *cur;
	int argvlen;

	mntdp->mntd_argc = mntdp->mntd_flags = 0;

	argvlen = 9;
	if (specopts != NULL)
		argvlen += fsu_str2argc(specopts);

	if (argvlen > mntdp->mntd_argv_size) {
		char **tmp;

		tmp = realloc(mntdp->mntd_argv, argvlen * sizeof(char *));
		if (tmp == NULL) {
			free(mntdp->mntd_argv);
			return -1;
		}
		mntdp->mntd_argv = tmp;
		mntdp->mntd_argv_size = argvlen;
	}

	ADD_ARG(mntdp, __UNCONST(getprogname()));

#ifdef WITH_SYSPUFFS
	if (al->fsa_puffsexec != NULL)
		ADD_ARG(mntdp, al->fsa_puffsexec);
#endif

	if (al->fsa_mntopt != NULL) {
		ADD_ARG(mntdp, __UNCONST("-o"));
		ADD_ARG(mntdp, al->fsa_mntopt);
		setenv("FSU_MNTOPTS", al->fsa_mntopt, 1);
	}
	if (mntopts != NULL) {
		ADD_ARG(mntdp, __UNCONST("-o"));
		ADD_ARG(mntdp, mntopts);
		setenv("FSU_MNTOPTS", mntopts, 1);
	}
	if (specopts != NULL) {
		int tmpargc;

		fsu_str2arg(specopts, &tmpargc,
		    mntdp->mntd_argv + mntdp->mntd_argc, argvlen - 8);
		mntdp->mntd_argc += tmpargc;
	}
	ADD_ARG(mntdp, al->fsa_path);
	ADD_ARG(mntdp, __UNCONST("/"));
	mntdp->mntd_argv[mntdp->mntd_argc] = NULL;

	for (cur = fslist; cur->fs_name != NULL; ++cur)
		if (strcmp(cur->fs_name, al->fsa_type) == 0)
			break;

	if (cur->fs_name == NULL)
		return -1;

	mntdp->mntd_fs = cur;

	return mount_struct(verbose, mntdp);
}
Example #22
0
int
do_xfs_repair (const char *device,
               int forcelogzero, int nomodify,
               int noprefetch, int forcegeometry,
               int64_t maxmem, int64_t ihashsize,
               int64_t bhashsize, int64_t agstride,
               const char *logdev, const char *rtdev)
{
  int r;
  CLEANUP_FREE char *err = NULL, *buf = NULL;
  const char *argv[MAX_ARGS];
  char maxmem_s[64];
  char ihashsize_s[70];
  char bhashsize_s[70];
  char agstride_s[74];
  size_t i = 0;
  int is_device;

  ADD_ARG (argv, i, str_xfs_repair);

  /* Optional arguments */
  if (optargs_bitmask & GUESTFS_XFS_REPAIR_FORCELOGZERO_BITMASK) {
    if (forcelogzero)
      ADD_ARG (argv, i, "-L");
  }
  if (optargs_bitmask & GUESTFS_XFS_REPAIR_NOMODIFY_BITMASK) {
    if (nomodify)
      ADD_ARG (argv, i, "-n");
  }
  if (optargs_bitmask & GUESTFS_XFS_REPAIR_NOPREFETCH_BITMASK) {
    if (noprefetch)
      ADD_ARG (argv, i, "-P");
  }
  if (optargs_bitmask & GUESTFS_XFS_REPAIR_FORCEGEOMETRY_BITMASK) {
    if (forcegeometry) {
      ADD_ARG (argv, i, "-o");
      ADD_ARG (argv, i, "force_geometry");
    }
  }

  if (optargs_bitmask & GUESTFS_XFS_REPAIR_MAXMEM_BITMASK) {
    if (maxmem < 0) {
      reply_with_error ("maxmem must be >= 0");
      return -1;
    }
    snprintf (maxmem_s, sizeof maxmem_s, "%" PRIi64, maxmem);
    ADD_ARG (argv, i, "-m");
    ADD_ARG (argv, i, maxmem_s);
  }

  if (optargs_bitmask & GUESTFS_XFS_REPAIR_IHASHSIZE_BITMASK) {
    if (ihashsize < 0) {
      reply_with_error ("ihashsize must be >= 0");
      return -1;
    }
    snprintf (ihashsize_s, sizeof ihashsize_s, "ihash=" "%" PRIi64, ihashsize);
    ADD_ARG (argv, i, "-o");
    ADD_ARG (argv, i, ihashsize_s);
  }

  if (optargs_bitmask & GUESTFS_XFS_REPAIR_BHASHSIZE_BITMASK) {
    if (bhashsize < 0) {
      reply_with_error ("bhashsize must be >= 0");
      return -1;
    }
    snprintf (bhashsize_s, sizeof bhashsize_s, "bhash=" "%" PRIi64, bhashsize);
    ADD_ARG (argv, i, "-o");
    ADD_ARG (argv, i, bhashsize_s);
  }

  if (optargs_bitmask & GUESTFS_XFS_REPAIR_AGSTRIDE_BITMASK) {
    if (agstride < 0) {
      reply_with_error ("agstride must be >= 0");
      return -1;
    }
    snprintf (agstride_s, sizeof agstride_s, "ag_stride=" "%" PRIi64, agstride);
    ADD_ARG (argv, i, "-o");
    ADD_ARG (argv, i, agstride_s);
  }


  if (optargs_bitmask & GUESTFS_XFS_REPAIR_LOGDEV_BITMASK) {
    ADD_ARG (argv, i, "-l");
    ADD_ARG (argv, i, logdev);
  }

  if (optargs_bitmask & GUESTFS_XFS_REPAIR_RTDEV_BITMASK) {
    ADD_ARG (argv, i, "-r");
    ADD_ARG (argv, i, rtdev);
  }

  is_device = STREQLEN (device, "/dev/", 5);
  if (!is_device) {
    buf = sysroot_path (device);
    if (buf == NULL) {
      reply_with_perror ("malloc");
      return -1;
    }
    ADD_ARG (argv, i, "-f");
    ADD_ARG (argv, i, buf);
  } else {
    ADD_ARG (argv, i, device);
  }

  ADD_ARG (argv, i, NULL);

  r = commandrv (NULL, &err, argv);
  if (r == -1) {
    reply_with_error ("%s: %s", device, err);
    return -1;
  }

  return r;
}
Example #23
0
static void get_client_info(char *info, const struct device *d)
{
  int l = 0;
  struct group *g = d->group;
  struct db_device *dd = d->db_data;
  struct db_group *dg = g->db_data;

  struct db_discuss *dsc = g->discuss.current;

  struct db_vote *dvt = d->vote.v ? g->vote.current : NULL;

  const char *ver = get_client_version();

#define ADD_ARG(fmt, a...) SEP_ADD(info, l, ":", fmt, ##a)

  ADD_ARG("client_version=%s", ver[0]? ver:"0");

  ADD_ARG("user_id=%s", dd->user_id);
  ADD_ARG("user_name=%s", dd->user_name);
  ADD_ARG("user_gender=%d", dd->user_gender);
  ADD_ARG("tag=%d", dd->tagid);
  ADD_ARG("sub=%d,%d", dd->sub1, dd->sub2);

  ADD_ARG("discuss_mode=%d", dg->discuss_mode);
  ADD_ARG("discuss_num=%d", dsc? g->discuss.curr_num : -1);
  ADD_ARG("discuss_name=%s", dsc? dsc->name : "0");
  ADD_ARG("discuss_nmembers=%d", g->discuss.nmembers);
  ADD_ARG("discuss_idlist=%s", dsc? dsc->members : "0");
  ADD_ARG("discuss_userlist=%s", dsc? g->discuss.membernames : "0");
  ADD_ARG("discuss_chair=%d", dd->discuss_chair);
  ADD_ARG("discuss_open=%d", dd->discuss_open);

  ADD_ARG("regist_start=%d", dg->regist_start);
  ADD_ARG("regist_master=%d", dd->regist_master);
  ADD_ARG("regist_mode=%d", dg->regist_mode);
  ADD_ARG("regist_reg=%d", d->regist.reg);

  ADD_ARG("vote_num=%d", dvt? g->vote.curr_num : -1);
  ADD_ARG("vote_nmembers=%d", g->vote.nmembers);
  ADD_ARG("vote_idlist=%s", dvt? dvt->members : "0");
  ADD_ARG("vote_userlist=%s", dvt? g->vote.membernames : "0");
  ADD_ARG("vote_master=%d", dvt? dd->vote_master:0);
  ADD_ARG("vote_name=%s", dvt? dvt->name:"0");
  ADD_ARG("vote_type=%d", dvt? dvt->type:0);
  ADD_ARG("vote_options=%s", dvt? dvt->options:"0");
  ADD_ARG("vote_total=%d", d->vote.v? d->vote.v->n_members:0);
  ADD_ARG("vote_results=%s", dg->vote_results);
  ADD_ARG("vote_choice=%d", dd->vote_choice);
}
Example #24
0
int
do_xfs_growfs (const char *path,
               int datasec, int logsec, int rtsec,
               int64_t datasize, int64_t logsize, int64_t rtsize,
               int64_t rtextsize, int32_t maxpct)
{
  int r;
  CLEANUP_FREE char *buf = NULL, *err = NULL;
  const char *argv[MAX_ARGS];
  char datasize_s[64];
  char logsize_s[64];
  char rtsize_s[64];
  char rtextsize_s[64];
  char maxpct_s[32];
  size_t i = 0;

  buf = sysroot_path (path);
  if (buf == NULL) {
    reply_with_perror ("malloc");
    return -1;
  }

  ADD_ARG (argv, i, str_xfs_growfs);

  /* Optional arguments */
  if (!(optargs_bitmask & GUESTFS_XFS_GROWFS_DATASEC_BITMASK))
    datasec = 0;
  if (!(optargs_bitmask & GUESTFS_XFS_GROWFS_LOGSEC_BITMASK))
    logsec = 0;
  if (!(optargs_bitmask & GUESTFS_XFS_GROWFS_RTSEC_BITMASK))
    rtsec = 0;

  if (datasec)
    ADD_ARG (argv, i, "-d");
  if (logsec)
    ADD_ARG (argv, i, "-l");
  if (rtsec)
    ADD_ARG (argv, i, "-r");

  if (optargs_bitmask & GUESTFS_XFS_GROWFS_DATASIZE_BITMASK) {
    if (datasize < 0) {
      reply_with_error ("datasize must be >= 0");
      return -1;
    }
    snprintf (datasize_s, sizeof datasize_s, "%" PRIi64, datasize);
    ADD_ARG (argv, i, "-D");
    ADD_ARG (argv, i, datasize_s);
  }

  if (optargs_bitmask & GUESTFS_XFS_GROWFS_LOGSIZE_BITMASK) {
    if (logsize < 0) {
      reply_with_error ("logsize must be >= 0");
      return -1;
    }
    snprintf (logsize_s, sizeof logsize_s, "%" PRIi64, logsize);
    ADD_ARG (argv, i, "-L");
    ADD_ARG (argv, i, logsize_s);
  }

  if (optargs_bitmask & GUESTFS_XFS_GROWFS_RTSIZE_BITMASK) {
    if (rtsize < 0) {
      reply_with_error ("rtsize must be >= 0");
      return -1;
    }
    snprintf (rtsize_s, sizeof rtsize_s, "%" PRIi64, rtsize);
    ADD_ARG (argv, i, "-R");
    ADD_ARG (argv, i, rtsize_s);
  }

  if (optargs_bitmask & GUESTFS_XFS_GROWFS_RTEXTSIZE_BITMASK) {
    if (rtextsize < 0) {
      reply_with_error ("rtextsize must be >= 0");
      return -1;
    }
    snprintf (rtextsize_s, sizeof rtextsize_s, "%" PRIi64, rtextsize);
    ADD_ARG (argv, i, "-e");
    ADD_ARG (argv, i, rtextsize_s);
  }

  if (optargs_bitmask & GUESTFS_XFS_GROWFS_MAXPCT_BITMASK) {
    if (maxpct < 0) {
      reply_with_error ("maxpct must be >= 0");
      return -1;
    }
    snprintf (maxpct_s, sizeof maxpct_s, "%" PRIi32, maxpct);
    ADD_ARG (argv, i, "-m");
    ADD_ARG (argv, i, maxpct_s);
  }

  ADD_ARG (argv, i, buf);
  ADD_ARG (argv, i, NULL);

  r = commandv (NULL, &err, argv);
  if (r == -1) {
    reply_with_error ("%s: %s", path, err);
    return -1;
  }

  return 0;
}
Example #25
0
/* Takes optional arguments, consult optargs_bitmask. */
int
do_tune2fs (const char *device, /* only required parameter */
            int force,
            int maxmountcount,
            int mountcount,
            const char *errorbehavior,
            int64_t group,
            int intervalbetweenchecks,
            int reservedblockspercentage,
            const char *lastmounteddirectory,
            int64_t reservedblockscount,
            int64_t user)
{
    const char *argv[MAX_ARGS];
    size_t i = 0;
    int r;
    CLEANUP_FREE char *err = NULL;
    char maxmountcount_s[64];
    char mountcount_s[64];
    char group_s[64];
    char intervalbetweenchecks_s[64];
    char reservedblockspercentage_s[64];
    char reservedblockscount_s[64];
    char user_s[64];

    ADD_ARG (argv, i, str_tune2fs);

    if (optargs_bitmask & GUESTFS_TUNE2FS_FORCE_BITMASK) {
        if (force)
            ADD_ARG (argv, i, "-f");
    }

    if (optargs_bitmask & GUESTFS_TUNE2FS_MAXMOUNTCOUNT_BITMASK) {
        if (maxmountcount < 0) {
            reply_with_error ("maxmountcount cannot be negative");
            return -1;
        }
        ADD_ARG (argv, i, "-c");
        snprintf (maxmountcount_s, sizeof maxmountcount_s, "%d", maxmountcount);
        ADD_ARG (argv, i, maxmountcount_s);
    }

    if (optargs_bitmask & GUESTFS_TUNE2FS_MOUNTCOUNT_BITMASK) {
        if (mountcount < 0) {
            reply_with_error ("mountcount cannot be negative");
            return -1;
        }
        ADD_ARG (argv, i, "-C");
        snprintf (mountcount_s, sizeof mountcount_s, "%d", mountcount);
        ADD_ARG (argv, i, mountcount_s);
    }

    if (optargs_bitmask & GUESTFS_TUNE2FS_ERRORBEHAVIOR_BITMASK) {
        if (STRNEQ (errorbehavior, "continue") &&
                STRNEQ (errorbehavior, "remount-ro") &&
                STRNEQ (errorbehavior, "panic")) {
            reply_with_error ("invalid errorbehavior parameter: %s", errorbehavior);
            return -1;
        }
        ADD_ARG (argv, i, "-e");
        ADD_ARG (argv, i, errorbehavior);
    }

    if (optargs_bitmask & GUESTFS_TUNE2FS_GROUP_BITMASK) {
        if (group < 0) {
            reply_with_error ("group cannot be negative");
            return -1;
        }
        ADD_ARG (argv, i, "-g");
        snprintf (group_s, sizeof group_s, "%" PRIi64, group);
        ADD_ARG (argv, i, group_s);
    }

    if (optargs_bitmask & GUESTFS_TUNE2FS_INTERVALBETWEENCHECKS_BITMASK) {
        if (intervalbetweenchecks < 0) {
            reply_with_error ("intervalbetweenchecks cannot be negative");
            return -1;
        }
        ADD_ARG (argv, i, "-i");
        if (intervalbetweenchecks > 0) {
            /* -i <NN>s is not documented in the man page, but has been
             * supported in tune2fs for several years.
             */
            snprintf (intervalbetweenchecks_s, sizeof intervalbetweenchecks_s,
                      "%ds", intervalbetweenchecks);
            ADD_ARG (argv, i, intervalbetweenchecks_s);
        }
        else
            ADD_ARG (argv, i, "0");
    }

    if (optargs_bitmask & GUESTFS_TUNE2FS_RESERVEDBLOCKSPERCENTAGE_BITMASK) {
        if (reservedblockspercentage < 0) {
            reply_with_error ("reservedblockspercentage cannot be negative");
            return -1;
        }
        ADD_ARG (argv, i, "-m");
        snprintf (reservedblockspercentage_s, sizeof reservedblockspercentage_s,
                  "%d", reservedblockspercentage);
        ADD_ARG (argv, i, reservedblockspercentage_s);
    }

    if (optargs_bitmask & GUESTFS_TUNE2FS_LASTMOUNTEDDIRECTORY_BITMASK) {
        ADD_ARG (argv, i, "-M");
        ADD_ARG (argv, i, lastmounteddirectory);
    }

    if (optargs_bitmask & GUESTFS_TUNE2FS_RESERVEDBLOCKSCOUNT_BITMASK) {
        if (reservedblockscount < 0) {
            reply_with_error ("reservedblockscount cannot be negative");
            return -1;
        }
        ADD_ARG (argv, i, "-r");
        snprintf (reservedblockscount_s, sizeof reservedblockscount_s,
                  "%" PRIi64, reservedblockscount);
        ADD_ARG (argv, i, reservedblockscount_s);
    }

    if (optargs_bitmask & GUESTFS_TUNE2FS_USER_BITMASK) {
        if (user < 0) {
            reply_with_error ("user cannot be negative");
            return -1;
        }
        ADD_ARG (argv, i, "-u");
        snprintf (user_s, sizeof user_s, "%" PRIi64, user);
        ADD_ARG (argv, i, user_s);
    }

    ADD_ARG (argv, i, device);
    ADD_ARG (argv, i, NULL);

    r = commandv (NULL, &err, argv);
    if (r == -1) {
        reply_with_error ("%s: %s", device, err);
        return -1;
    }

    return 0;
}
Example #26
0
void libpd_add_float(float x) {
  ADD_ARG(SETFLOAT);
}
Example #27
0
int
do_mke2fs (const char *device,               /* 0 */
           int64_t blockscount,
           int64_t blocksize,
           int64_t fragsize,
           int64_t blockspergroup,
           int64_t numberofgroups,           /* 5 */
           int64_t bytesperinode,
           int64_t inodesize,
           int64_t journalsize,
           int64_t numberofinodes,
           int64_t stridesize,               /* 10 */
           int64_t stripewidth,
           int64_t maxonlineresize,
           int reservedblockspercentage,
           int mmpupdateinterval,
           const char *journaldevice,        /* 15 */
           const char *label,
           const char *lastmounteddir,
           const char *creatoros,
           const char *fstype,
           const char *usagetype,            /* 20 */
           const char *uuid,
           int forcecreate,
           int writesbandgrouponly,
           int lazyitableinit,
           int lazyjournalinit,              /* 25 */
           int testfs,
           int discard,
           int quotatype,
           int extent,
           int filetype,                     /* 30 */
           int flexbg,
           int hasjournal,
           int journaldev,
           int largefile,
           int quota,                        /* 35 */
           int resizeinode,
           int sparsesuper,
           int uninitbg)
{
    int r;
    CLEANUP_FREE char *err = NULL;
    const char *argv[MAX_ARGS];
    char blockscount_s[64];
    char blocksize_s[64];
    char fragsize_s[64];
    char blockspergroup_s[64];
    char numberofgroups_s[64];
    char bytesperinode_s[64];
    char inodesize_s[64];
    char journalsize_s[64];
    CLEANUP_FREE char *journaldevice_translated = NULL;
    CLEANUP_FREE char *journaldevice_s = NULL;
    char reservedblockspercentage_s[64];
    char numberofinodes_s[64];
    char mmpupdateinterval_s[84];
    char stridesize_s[74];
    char stripewidth_s[84];
    char maxonlineresize_s[74];
    size_t i = 0;

    ADD_ARG (argv, i, str_mke2fs);

    if (optargs_bitmask & GUESTFS_MKE2FS_BLOCKSIZE_BITMASK) {
        if (blocksize < 0) {
            reply_with_error ("blocksize must be >= 0");
            return -1;
        }
        snprintf (blocksize_s, sizeof blocksize_s, "%" PRIi64, blocksize);
        ADD_ARG (argv, i, "-b");
        ADD_ARG (argv, i, blocksize_s);
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_FRAGSIZE_BITMASK) {
        if (fragsize < 0) {
            reply_with_error ("fragsize must be >= 0");
            return -1;
        }
        snprintf (fragsize_s, sizeof fragsize_s, "%" PRIi64, fragsize);
        ADD_ARG (argv, i, "-f");
        ADD_ARG (argv, i, fragsize_s);
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_FORCECREATE_BITMASK) {
        if (forcecreate)
            ADD_ARG (argv, i, "-F");
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_BLOCKSPERGROUP_BITMASK) {
        if (blockspergroup < 0) {
            reply_with_error ("blockspergroup must be >= 0");
            return -1;
        }
        snprintf (blockspergroup_s, sizeof blockspergroup_s,
                  "%" PRIi64, blockspergroup);
        ADD_ARG (argv, i, "-g");
        ADD_ARG (argv, i, blockspergroup_s);
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_NUMBEROFGROUPS_BITMASK) {
        if (numberofgroups < 0) {
            reply_with_error ("numberofgroups must be >= 0");
            return -1;
        }
        snprintf (numberofgroups_s, sizeof numberofgroups_s,
                  "%" PRIi64, numberofgroups);
        ADD_ARG (argv, i, "-G");
        ADD_ARG (argv, i, numberofgroups_s);
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_BYTESPERINODE_BITMASK) {
        if (bytesperinode < 0) {
            reply_with_error ("bytesperinode must be >= 0");
            return -1;
        }
        snprintf (bytesperinode_s, sizeof bytesperinode_s, "%" PRIi64, bytesperinode);
        ADD_ARG (argv, i, "-i");
        ADD_ARG (argv, i, bytesperinode_s);
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_INODESIZE_BITMASK) {
        if (inodesize < 0) {
            reply_with_error ("inodesize must be >= 0");
            return -1;
        }
        snprintf (inodesize_s, sizeof inodesize_s, "%" PRIi64, inodesize);
        ADD_ARG (argv, i, "-I");
        ADD_ARG (argv, i, inodesize_s);
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_JOURNALSIZE_BITMASK) {
        if (journalsize < 0) {
            reply_with_error ("journalsize must be >= 0");
            return -1;
        }
        snprintf (journalsize_s, sizeof journalsize_s,
                  "size=" "%" PRIi64, journalsize);
        ADD_ARG (argv, i, "-J");
        ADD_ARG (argv, i, journalsize_s);
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_JOURNALDEVICE_BITMASK) {
        if (journaldevice) {
            /* OString doesn't do device name translation (RHBZ#876579).  We
             * have to do it manually here, but note that LABEL=.. and
             * UUID=.. are valid strings which do not require translation.
             */
            if (STRPREFIX (journaldevice, "/dev/")) {
                if (is_root_device (journaldevice)) {
                    reply_with_error ("%s: device not found", journaldevice);
                    return -1;
                }
                journaldevice_translated = device_name_translation (journaldevice);
                if (journaldevice_translated == NULL) {
                    reply_with_perror ("%s", journaldevice);
                    return -1;
                }

                journaldevice_s = malloc (strlen (journaldevice_translated) + 8);
                if (!journaldevice_s) {
                    reply_with_perror ("malloc");
                    return -1;
                }

                sprintf (journaldevice_s, "device=%s", journaldevice_translated);
            }
            else {
                journaldevice_s = malloc (strlen (journaldevice) + 8);
                if (!journaldevice_s) {
                    reply_with_perror ("malloc");
                    return -1;
                }

                sprintf (journaldevice_s, "device=%s", journaldevice);
            }

            ADD_ARG (argv, i, "-J");
            ADD_ARG (argv, i, journaldevice_s);
        }
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_LABEL_BITMASK) {
        if (label) {
            ADD_ARG (argv, i, "-L");
            ADD_ARG (argv, i, label);
        }
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_RESERVEDBLOCKSPERCENTAGE_BITMASK) {
        if (reservedblockspercentage < 0) {
            reply_with_error ("reservedblockspercentage must be >= 0");
            return -1;
        }
        snprintf (reservedblockspercentage_s, sizeof reservedblockspercentage_s,
                  "%" PRIi32, reservedblockspercentage);
        ADD_ARG (argv, i, "-m");
        ADD_ARG (argv, i, reservedblockspercentage_s);
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_LASTMOUNTEDDIR_BITMASK) {
        if (lastmounteddir) {
            ADD_ARG (argv, i, "-M");
            ADD_ARG (argv, i, lastmounteddir);
        }
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_NUMBEROFINODES_BITMASK) {
        if (numberofinodes < 0) {
            reply_with_error ("numberofinodes must be >= 0");
            return -1;
        }
        snprintf (numberofinodes_s, sizeof numberofinodes_s,
                  "%" PRIi64, numberofinodes);
        ADD_ARG (argv, i, "-N");
        ADD_ARG (argv, i, numberofinodes_s);
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_CREATOROS_BITMASK) {
        if (creatoros) {
            ADD_ARG (argv, i, "-o");
            ADD_ARG (argv, i, creatoros);
        }
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_WRITESBANDGROUPONLY_BITMASK) {
        if (writesbandgrouponly)
            ADD_ARG (argv, i, "-S");
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_FSTYPE_BITMASK) {
        if (fstype) {
            if (!fstype_is_extfs (fstype)) {
                reply_with_error ("%s: not a valid extended filesystem type", fstype);
                return -1;
            }

            ADD_ARG (argv, i, "-t");
            ADD_ARG (argv, i, fstype);
        }
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_USAGETYPE_BITMASK) {
        if (usagetype) {
            ADD_ARG (argv, i, "-T");
            ADD_ARG (argv, i, usagetype);
        }
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_UUID_BITMASK) {
        if (uuid) {
            ADD_ARG (argv, i, "-U");
            ADD_ARG (argv, i, uuid);
        }
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_MMPUPDATEINTERVAL_BITMASK) {
        if (mmpupdateinterval < 0) {
            reply_with_error ("mmpupdateinterval must be >= 0");
            return -1;
        }
        snprintf (mmpupdateinterval_s, sizeof mmpupdateinterval_s,
                  "mmp_update_interval=" "%" PRIi32, mmpupdateinterval);
        ADD_ARG (argv, i, "-E");
        ADD_ARG (argv, i, mmpupdateinterval_s);
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_STRIDESIZE_BITMASK) {
        if (stridesize < 0) {
            reply_with_error ("stridesize must be >= 0");
            return -1;
        }
        snprintf (stridesize_s, sizeof stridesize_s,
                  "stride=" "%" PRIi64, stridesize);
        ADD_ARG (argv, i, "-E");
        ADD_ARG (argv, i, stridesize_s);
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_STRIPEWIDTH_BITMASK) {
        if (stripewidth< 0) {
            reply_with_error ("stripewidth must be >= 0");
            return -1;
        }
        snprintf (stripewidth_s, sizeof stripewidth_s,
                  "stripe_width=" "%" PRIi64, stripewidth);
        ADD_ARG (argv, i, "-E");
        ADD_ARG (argv, i, stripewidth_s);
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_MAXONLINERESIZE_BITMASK) {
        if (maxonlineresize < 0) {
            reply_with_error ("maxonlineresize must be >= 0");
            return -1;
        }
        snprintf (maxonlineresize_s, sizeof maxonlineresize_s,
                  "resize=" "%" PRIi64, maxonlineresize);
        ADD_ARG (argv, i, "-E");
        ADD_ARG (argv, i, maxonlineresize_s);
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_LAZYITABLEINIT_BITMASK) {
        ADD_ARG (argv, i, "-E");
        if (lazyitableinit)
            ADD_ARG (argv, i, "lazy_itable_init=1");
        else
            ADD_ARG (argv, i, "lazy_itable_init=0");
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_LAZYJOURNALINIT_BITMASK) {
        ADD_ARG (argv, i, "-E");
        if (lazyjournalinit)
            ADD_ARG (argv, i, "lazy_journal_init=1");
        else
            ADD_ARG (argv, i, "lazy_journal_init=0");
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_TESTFS_BITMASK) {
        if (testfs) {
            ADD_ARG (argv, i, "-E");
            ADD_ARG (argv, i, "test_fs");
        }
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_DISCARD_BITMASK) {
        ADD_ARG (argv, i, "-E");
        if (discard)
            ADD_ARG (argv, i, "discard");
        else
            ADD_ARG (argv, i, "nodiscard");
    }

    if (optargs_bitmask & GUESTFS_MKE2FS_EXTENT_BITMASK) {
        ADD_ARG (argv, i, "-O");
        if (extent)
            ADD_ARG (argv, i, "extent");
        else
            ADD_ARG (argv, i, "^extent");
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_FILETYPE_BITMASK) {
        ADD_ARG (argv, i, "-O");
        if (filetype)
            ADD_ARG (argv, i, "filetype");
        else
            ADD_ARG (argv, i, "^filetype");
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_FLEXBG_BITMASK) {
        ADD_ARG (argv, i, "-O");
        if (flexbg)
            ADD_ARG (argv, i, "flexbg");
        else
            ADD_ARG (argv, i, "^flexbg");
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_HASJOURNAL_BITMASK) {
        ADD_ARG (argv, i, "-O");
        if (hasjournal)
            ADD_ARG (argv, i, "has_journal");
        else
            ADD_ARG (argv, i, "^has_journal");
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_JOURNALDEV_BITMASK) {
        ADD_ARG (argv, i, "-O");
        if (journaldev)
            ADD_ARG (argv, i, "journal_dev");
        else
            ADD_ARG (argv, i, "^journal_dev");
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_LARGEFILE_BITMASK) {
        ADD_ARG (argv, i, "-O");
        if (largefile)
            ADD_ARG (argv, i, "large_file");
        else
            ADD_ARG (argv, i, "^large_file");
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_QUOTA_BITMASK) {
        ADD_ARG (argv, i, "-O");
        if (quota)
            ADD_ARG (argv, i, "quota");
        else
            ADD_ARG (argv, i, "^quota");
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_RESIZEINODE_BITMASK) {
        ADD_ARG (argv, i, "-O");
        if (resizeinode)
            ADD_ARG (argv, i, "resize_inode");
        else
            ADD_ARG (argv, i, "^resize_inode");
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_SPARSESUPER_BITMASK) {
        ADD_ARG (argv, i, "-O");
        if (sparsesuper)
            ADD_ARG (argv, i, "sparse_super");
        else
            ADD_ARG (argv, i, "^sparse_super");
    }
    if (optargs_bitmask & GUESTFS_MKE2FS_UNINITBG_BITMASK) {
        ADD_ARG (argv, i, "-O");
        if (uninitbg)
            ADD_ARG (argv, i, "uninit_bg");
        else
            ADD_ARG (argv, i, "^uninit_bg");
    }

    ADD_ARG (argv, i, device);

    if (optargs_bitmask & GUESTFS_MKE2FS_BLOCKSCOUNT_BITMASK) {
        if (blockscount < 0) {
            reply_with_error ("blockscount must be >= 0");
            return -1;
        }
        snprintf (blockscount_s, sizeof blockscount_s, "%" PRIi64, blockscount);
        ADD_ARG (argv, i, blockscount_s);
    }

    ADD_ARG (argv, i, NULL);

    wipe_device_before_mkfs (device);

    r = commandv (NULL, &err, argv);
    if (r == -1) {
        reply_with_error ("%s: %s", device, err);
        return -1;
    }

    return 0;
}
Example #28
0
void ppp_start(struct device_list *entry)
{
	int pgrpid;
	
	/* Run pppd directly here and set up to wait for the iface */
	entry->status = 1;
	entry->link_pid = fork();


	if (entry->link_pid < 0) {
		syslog(LOG_ERR, "failed to fork pppd: %m");
		exit(EXIT_FAILURE);
	}

#define ADD_ARG(arg) { argv[i] = arg; argv_len += strlen(argv[i++]) + 1; }
    
	if (entry->link_pid == 0) {
		char **argv = (char **)malloc(sizeof(char *)*(pppd_argc+12));
		int argv_len = 0;
		char buf[24], tmpbuf[50], *argv_buf, connect[70];
		int i = 0, j;

		ADD_ARG(path_pppd);
		ADD_ARG(entry->device);
		ADD_ARG("-defaultroute");
		ADD_ARG("-detach");
		if (modem){
			ADD_ARG("modem");
			ADD_ARG("connect");
			sprintf(connect, 
// should add ABORT 'BLACKLISTED' here
// pppd dies when it is set
				"/usr/sbin/chat -v ABORT 'BUSY' ABORT "
				"'NO CARRIER' '' ATZ OK  ATDT%s CONNECT",
				iptotel((char *)inet_ntoa(*entry->raddr)));
			ADD_ARG(connect);
		}
		else{
			ADD_ARG("local");
		}
		ADD_ARG("115200");
		sprintf(buf, "%s:", inet_ntoa(*entry->laddr));
		sprintf(tmpbuf, "%s%s", buf, inet_ntoa(*entry->raddr));
		ADD_ARG(tmpbuf);
//		if (crtscts) ADD_ARG("crtscts");
//		ADD_ARG("mtu");
//		sprintf(buf,"%d",mtu);
//		ADD_ARG(strdup(buf));
//		ADD_ARG("mru");
//		sprintf(buf,"%d",mru);
//		ADD_ARG(strdup(buf));
//		if (netmask) {
//			ADD_ARG("netmask");
//			ADD_ARG(netmask);
//		}
		for (j = 0; j < pppd_argc; j++) {
			ADD_ARG(pppd_argv[j]);
		}
		argv[i++] = 0;

		if ((argv_buf = (char *)malloc(argv_len + 1))) {
			argv_len = i - 1;
			*argv_buf = '\0';
			for (i = 0; i < argv_len; i++) {
				strcat(argv_buf, argv[i]);
				strcat(argv_buf, " ");
			}
			syslog(LOG_DEBUG, "Running pppd: %s", argv_buf);
		}

		/* make sure pppd is the session leader and has the controlling
		 * terminal so it gets the SIGHUP's
		 */
		pgrpid = setsid();
		ioctl(modem_fd, TIOCSCTTY, 1);
		tcsetpgrp(modem_fd, pgrpid);

		setreuid(getuid(), getuid());
		setregid(getgid(), getgid());

		if (modem_fd != 0)
			dup2(modem_fd, 0);
		else
			fcntl(modem_fd, F_SETFD, 0);
		dup2(0, 1);

		execv(path_pppd,argv);

		syslog(LOG_ERR, "could not exec %s: %m",path_pppd);
		_exit(99);
		/* NOTREACHED */
	}
	syslog(LOG_INFO,"Running pppd (pid = %d).",entry->link_pid);
}
Example #29
0
/* Takes optional arguments, consult optargs_bitmask. */
int
do_md_create (const char *name, char *const *devices,
              int64_t missingbitmap, int nrdevices, int spare,
              int64_t chunk, const char *level)
{
  char nrdevices_s[32];
  char spare_s[32];
  char chunk_s[32];
  size_t j;
  int r;
  char *err;
  uint64_t umissingbitmap = (uint64_t) missingbitmap;

  /* Check the optional parameters and set defaults where appropriate. */
  if (!(optargs_bitmask & GUESTFS_MD_CREATE_MISSINGBITMAP_BITMASK))
    umissingbitmap = 0;

  if (optargs_bitmask & GUESTFS_MD_CREATE_SPARE_BITMASK) {
    if (spare < 0) {
      reply_with_error ("spare must not be negative");
      return -1;
    }
  }
  else
    spare = 0;

  if (optargs_bitmask & GUESTFS_MD_CREATE_NRDEVICES_BITMASK) {
    if (nrdevices < 2) {
      reply_with_error ("nrdevices is less than 2");
      return -1;
    }
  }
  else
    nrdevices = count_strings (devices) + count_bits (umissingbitmap);

  if (optargs_bitmask & GUESTFS_MD_CREATE_LEVEL_BITMASK) {
    if (STRNEQ (level, "linear") && STRNEQ (level, "raid0") &&
        STRNEQ (level, "0") && STRNEQ (level, "stripe") &&
        STRNEQ (level, "raid1") && STRNEQ (level, "1") &&
        STRNEQ (level, "mirror") &&
        STRNEQ (level, "raid4") && STRNEQ (level, "4") &&
        STRNEQ (level, "raid5") && STRNEQ (level, "5") &&
        STRNEQ (level, "raid6") && STRNEQ (level, "6") &&
        STRNEQ (level, "raid10") && STRNEQ (level, "10")) {
      reply_with_error ("unknown level parameter: %s", level);
      return -1;
    }
  }
  else
    level = "raid1";

  if (optargs_bitmask & GUESTFS_MD_CREATE_CHUNK_BITMASK) {
    /* chunk is bytes in the libguestfs API, but K when we pass it to mdadm */
    if ((chunk & 1023) != 0) {
      reply_with_error ("chunk size must be a multiple of 1024 bytes");
      return -1;
    }
  }

  /* Check invariant. */
  if (count_strings (devices) + count_bits (umissingbitmap) !=
      (size_t) (nrdevices + spare)) {
    reply_with_error ("devices (%zu) + bits set in missingbitmap (%zu) is not equal to nrdevices (%d) + spare (%d)",
                      count_strings (devices), count_bits (umissingbitmap),
                      nrdevices, spare);
    return -1;
  }

  size_t MAX_ARGS = nrdevices + 16;
  const char *argv[MAX_ARGS];
  size_t i = 0;

  ADD_ARG (argv, i, "mdadm");
  ADD_ARG (argv, i, "--create");
  /* --run suppresses "Continue creating array" question */
  ADD_ARG (argv, i, "--run");
  ADD_ARG (argv, i, name);
  ADD_ARG (argv, i, "--level");
  ADD_ARG (argv, i, level);
  ADD_ARG (argv, i, "--raid-devices");
  snprintf (nrdevices_s, sizeof nrdevices_s, "%d", nrdevices);
  ADD_ARG (argv, i, nrdevices_s);
  if (optargs_bitmask & GUESTFS_MD_CREATE_SPARE_BITMASK) {
    ADD_ARG (argv, i, "--spare-devices");
    snprintf (spare_s, sizeof spare_s, "%d", spare);
    ADD_ARG (argv, i, spare_s);
  }
  if (optargs_bitmask & GUESTFS_MD_CREATE_CHUNK_BITMASK) {
    ADD_ARG (argv, i, "--chunk");
    snprintf (chunk_s, sizeof chunk_s, "%" PRIi64, chunk / 1024);
    ADD_ARG (argv, i, chunk_s);
  }

  /* Add devices and "missing". */
  j = 0;
  while (devices[j] != NULL || umissingbitmap != 0) {
    if (umissingbitmap & 1)
      ADD_ARG (argv, i, "missing");
    else {
      ADD_ARG (argv, i, devices[j]);
      j++;
    }
    umissingbitmap >>= 1;
  }

  ADD_ARG (argv, i, NULL);

  r = commandv (NULL, &err, argv);
  if (r == -1) {
    reply_with_error ("mdadm: %s: %s", name, err);
    free (err);
    return -1;
  }

  free (err);

  udev_settle ();

  return 0;
}
Example #30
0
/* Takes optional arguments, consult optargs_bitmask. */
int
do_mkfs (const char *fstype, const char *device, int blocksize,
         const char *features, int inode, int sectorsize, const char *label)
{
  const char *argv[MAX_ARGS];
  size_t i = 0;
  char blocksize_str[32];
  char inode_str[32];
  char sectorsize_str[32];
  int r;
  CLEANUP_FREE char *err = NULL;
  int extfs = 0;

  if (fstype_is_extfs (fstype))
    extfs = 1;

  /* For ext2/3/4 run the mke2fs program directly.  This is because
   * the mkfs program "eats" some options, in particular the -F
   * option.
   */
  if (extfs)
    ADD_ARG (argv, i, str_mke2fs);
  else
    ADD_ARG (argv, i, str_mkfs);

  ADD_ARG (argv, i, "-t");
  ADD_ARG (argv, i, fstype);

  /* Force mke2fs to create a filesystem, even if it thinks it
   * shouldn't (RHBZ#690819).
   */
  if (extfs)
    ADD_ARG (argv, i, "-F");

  /* mkfs.ntfs requires the -Q argument otherwise it writes zeroes to
   * every block and does bad block detection, neither of which are
   * useful behaviour for virtual devices.  Also recent versions need
   * to be forced to create filesystems on non-partitions.
   */
  if (STREQ (fstype, "ntfs")) {
    ADD_ARG (argv, i, "-Q");
    ADD_ARG (argv, i, "-F");
  }

  /* mkfs.reiserfs produces annoying interactive prompts unless you
   * tell it to be quiet.
   * mkfs.jfs is the same
   * mkfs.xfs must force to make xfs filesystem when the device already
   * has a filesystem on it
   */
  if (STREQ (fstype, "reiserfs") || STREQ (fstype, "jfs") ||
      STREQ (fstype, "xfs"))
    ADD_ARG (argv, i, "-f");

  /* For GFS, GFS2, assume a single node. */
  if (STREQ (fstype, "gfs") || STREQ (fstype, "gfs2")) {
    ADD_ARG (argv, i, "-p");
    ADD_ARG (argv, i, "lock_nolock");
    /* The man page says this is default, but it doesn't seem to be: */
    ADD_ARG (argv, i, "-j");
    ADD_ARG (argv, i, "1");
    /* Don't ask questions: */
    ADD_ARG (argv, i, "-O");
  }

  /* Force mkfs.fat to create a whole disk filesystem (RHBZ#1039995). */
  if (STREQ (fstype, "fat") || STREQ (fstype, "vfat") ||
      STREQ (fstype, "msdos"))
    ADD_ARG (argv, i, "-I");

  /* Process blocksize parameter if set. */
  if (optargs_bitmask & GUESTFS_MKFS_BLOCKSIZE_BITMASK) {
    if (blocksize <= 0 || !is_power_of_2 (blocksize)) {
      reply_with_error ("block size must be > 0 and a power of 2");
      return -1;
    }

    if (STREQ (fstype, "vfat") ||
        STREQ (fstype, "msdos")) {
      /* For VFAT map the blocksize into a cluster size.  However we
       * have to determine the block device sector size in order to do
       * this.
       */
      int ss = do_blockdev_getss (device);
      if (ss == -1)
        return -1;

      int sectors_per_cluster = blocksize / ss;
      if (sectors_per_cluster < 1 || sectors_per_cluster > 128) {
        reply_with_error ("unsupported cluster size for %s filesystem (requested cluster size = %d, sector size = %d, trying sectors per cluster = %d)",
                          fstype, blocksize, ss, sectors_per_cluster);
        return -1;
      }

      snprintf (blocksize_str, sizeof blocksize_str, "%d", sectors_per_cluster);
      ADD_ARG (argv, i, "-s");
      ADD_ARG (argv, i, blocksize_str);
    }
    else if (STREQ (fstype, "ntfs")) {
      /* For NTFS map the blocksize into a cluster size. */
      snprintf (blocksize_str, sizeof blocksize_str, "%d", blocksize);
      ADD_ARG (argv, i, "-c");
      ADD_ARG (argv, i, blocksize_str);
    }
    else if (STREQ (fstype, "btrfs")) {
      /* For btrfs, blocksize cannot be specified (RHBZ#807905). */
      reply_with_error ("blocksize cannot be set on btrfs filesystems, use 'mkfs-btrfs'");
      return -1;
    }
    else if (STREQ (fstype, "xfs")) {
      /* mkfs -t xfs -b size=<size> (RHBZ#981715). */
      snprintf (blocksize_str, sizeof blocksize_str, "size=%d", blocksize);
      ADD_ARG (argv, i, "-b");
      ADD_ARG (argv, i, blocksize_str);
    }
    else {
      /* For all other filesystem types, try the -b option. */
      snprintf (blocksize_str, sizeof blocksize_str, "%d", blocksize);
      ADD_ARG (argv, i, "-b");
      ADD_ARG (argv, i, blocksize_str);
    }
  }

  if (optargs_bitmask & GUESTFS_MKFS_FEATURES_BITMASK) {
    ADD_ARG (argv, i, "-O");
    ADD_ARG (argv, i, features);
  }

  if (optargs_bitmask & GUESTFS_MKFS_INODE_BITMASK) {
    if (!extfs) {
      reply_with_error ("inode size (-I) can only be set on ext2/3/4 filesystems");
      return -1;
    }

    if (inode <= 0) {
      reply_with_error ("inode size must be larger than zero");
      return -1;
    }

    snprintf (inode_str, sizeof inode_str, "%d", inode);
    ADD_ARG (argv, i, "-I");
    ADD_ARG (argv, i, inode_str);
  }

  if (optargs_bitmask & GUESTFS_MKFS_SECTORSIZE_BITMASK) {
    if (!STREQ (fstype, "ufs")) {
      reply_with_error ("sector size (-S) can only be set on ufs filesystems");
      return -1;
    }

    if (sectorsize <= 0) {
      reply_with_error ("sector size must be larger than zero");
      return -1;
    }

    snprintf (sectorsize_str, sizeof sectorsize_str, "%d", sectorsize);
    ADD_ARG (argv, i, "-S");
    ADD_ARG (argv, i, sectorsize_str);
  }

  if (optargs_bitmask & GUESTFS_MKFS_LABEL_BITMASK) {
    if (extfs) {
      if (strlen (label) > EXT2_LABEL_MAX) {
        reply_with_error ("%s: ext2/3/4 labels are limited to %d bytes",
                          label, EXT2_LABEL_MAX);
        return -1;
      }

      ADD_ARG (argv, i, "-L");
      ADD_ARG (argv, i, label);
    }
    else if (STREQ (fstype, "fat") || STREQ (fstype, "vfat") ||
             STREQ (fstype, "msdos")) {
      ADD_ARG (argv, i, "-n");
      ADD_ARG (argv, i, label);
    }
    else if (STREQ (fstype, "ntfs")) {
      ADD_ARG (argv, i, "-L");
      ADD_ARG (argv, i, label);
    }
    else if (STREQ (fstype, "xfs")) {
      if (strlen (label) > XFS_LABEL_MAX) {
        reply_with_error ("%s: xfs labels are limited to %d bytes",
                          label, XFS_LABEL_MAX);
        return -1;
      }

      ADD_ARG (argv, i, "-L");
      ADD_ARG (argv, i, label);
    }
    else if (STREQ (fstype, "btrfs")) {
      ADD_ARG (argv, i, "-L");
      ADD_ARG (argv, i, label);
    }
    else {
      reply_with_error ("don't know how to set the label for '%s' filesystems",
                        fstype);
      return -1;
    }
  }

  ADD_ARG (argv, i, device);
  ADD_ARG (argv, i, NULL);

  wipe_device_before_mkfs (device);

  r = commandv (NULL, &err, argv);
  if (r == -1) {
    reply_with_error ("%s: %s: %s", fstype, device, err);
    return -1;
  }

  return 0;
}