示例#1
0
/* We need to rewrite the root path so it is based at /sysroot. */
int
do_aug_init (const char *root, int flags)
{
#ifdef HAVE_AUGEAS
  char *buf;

  if (aug) {
    aug_close (aug);
    aug = NULL;
  }

  buf = sysroot_path (root);
  if (!buf) {
    reply_with_perror ("malloc");
    return -1;
  }

  aug = aug_init (buf, NULL, flags);
  free (buf);

  if (!aug) {
    reply_with_error ("Augeas initialization failed");
    return -1;
  }

  return 0;
#else
  NOT_AVAILABLE (-1);
#endif
}
示例#2
0
int64_t
do_inotify_add_watch (const char *path, int mask)
{
#ifdef HAVE_SYS_INOTIFY_H
  int64_t r;
  char *buf;

  NEED_INOTIFY (-1);

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

  r = inotify_add_watch (inotify_fd, buf, mask);
  free (buf);
  if (r == -1) {
    reply_with_perror ("%s", path);
    return -1;
  }

  return r;
#else
  NOT_AVAILABLE (-1);
#endif
}
示例#3
0
int
do_inotify_init (int max_events)
{
#ifdef HAVE_SYS_INOTIFY_H
  FILE *fp;

  NEED_ROOT (, return -1);

  if (max_events < 0) {
    reply_with_error ("max_events < 0");
    return -1;
  }

  if (max_events > 0) {
    fp = fopen (MQE_PATH, "w");
    if (fp == NULL) {
      reply_with_perror (MQE_PATH);
      return -1;
    }
    fprintf (fp, "%d\n", max_events);
    fclose (fp);
  }

  if (inotify_fd >= 0)
    if (do_inotify_close () == -1)
      return -1;

#ifdef HAVE_INOTIFY_INIT1
  inotify_fd = inotify_init1 (IN_NONBLOCK | IN_CLOEXEC);
  if (inotify_fd == -1) {
    reply_with_perror ("inotify_init1");
    return -1;
  }
#else
  inotify_fd = inotify_init ();
  if (inotify_fd == -1) {
    reply_with_perror ("inotify_init");
    return -1;
  }
  if (fcntl (inotify_fd, F_SETFL, O_NONBLOCK) == -1) {
    reply_with_perror ("fcntl: O_NONBLOCK");
    close (inotify_fd);
    inotify_fd = -1;
    return -1;
  }
  if (fcntl (inotify_fd, F_SETFD, FD_CLOEXEC) == -1) {
    reply_with_perror ("fcntl: FD_CLOEXEC");
    close (inotify_fd);
    inotify_fd = -1;
    return -1;
  }
#endif

  return 0;
#else
  NOT_AVAILABLE (-1);
#endif
}
示例#4
0
int
do_aug_close (void)
{
#ifdef HAVE_AUGEAS
  NEED_AUG(-1);

  aug_close (aug);
  aug = NULL;

  return 0;
#else
  NOT_AVAILABLE (-1);
#endif
}
示例#5
0
int
do_aug_load (void)
{
#ifdef HAVE_AUG_LOAD
  NEED_AUG (-1);

  if (aug_load (aug) == -1) {
    reply_with_error ("Augeas load failed");
    return -1;
  }

  return 0;
#else
  NOT_AVAILABLE (-1);
#endif
}
示例#6
0
int
do_inotify_rm_watch (int wd)
{
#ifdef HAVE_SYS_INOTIFY_H
  NEED_INOTIFY (-1);

  if (inotify_rm_watch (inotify_fd, wd) == -1) {
    reply_with_perror ("%d", wd);
    return -1;
  }

  return 0;
#else
  NOT_AVAILABLE (-1);
#endif
}
示例#7
0
int
do_aug_save (void)
{
#ifdef HAVE_AUGEAS
  NEED_AUG (-1);

  if (aug_save (aug) == -1) {
    reply_with_error ("Augeas save failed");
    return -1;
  }

  return 0;
#else
  NOT_AVAILABLE (-1);
#endif
}
示例#8
0
int
do_aug_defvar (const char *name, const char *expr)
{
#ifdef HAVE_AUG_DEFVAR
  int r;

  NEED_AUG (-1);

  r = aug_defvar (aug, name, expr);
  if (r == -1) {
    reply_with_error ("Augeas defvar failed");
    return -1;
  }
  return r;
#else
  NOT_AVAILABLE (-1);
#endif
}
示例#9
0
char *
do_realpath (const char *path)
{
#ifdef HAVE_REALPATH
    char *ret;

    CHROOT_IN;
    ret = realpath (path, NULL);
    CHROOT_OUT;
    if (ret == NULL) {
        reply_with_perror ("%s", path);
        return NULL;
    }

    return ret;			/* caller frees */
#else
    NOT_AVAILABLE (NULL);
#endif
}
示例#10
0
int
do_aug_clear (const char *path)
{
#ifdef HAVE_AUGEAS
  int r;

  NEED_AUG (-1);

  r = aug_set (aug, path, NULL);
  if (r == -1) {
    reply_with_error ("Augeas clear failed");
    return -1;
  }

  return 0;
#else
  NOT_AVAILABLE (-1);
#endif
}
示例#11
0
int
do_aug_insert (const char *path, const char *label, int before)
{
#ifdef HAVE_AUGEAS
  int r;

  NEED_AUG (-1);

  r = aug_insert (aug, path, label, before);
  if (r == -1) {
    reply_with_error ("Augeas insert failed");
    return -1;
  }

  return 0;
#else
  NOT_AVAILABLE (-1);
#endif
}
示例#12
0
int
do_aug_mv (const char *src, const char *dest)
{
#ifdef HAVE_AUGEAS
  int r;

  NEED_AUG (-1);

  r = aug_mv (aug, src, dest);
  if (r == -1) {
    reply_with_error ("Augeas mv failed");
    return -1;
  }

  return 0;
#else
  NOT_AVAILABLE (-1);
#endif
}
示例#13
0
int
do_aug_rm (const char *path)
{
#ifdef HAVE_AUGEAS
  int r;

  NEED_AUG (-1);

  r = aug_rm (aug, path);
  if (r == -1) {
    reply_with_error ("Augeas rm failed");
    return -1;
  }

  return r;
#else
  NOT_AVAILABLE (-1);
#endif
}
示例#14
0
guestfs_int_int_bool *
do_aug_defnode (const char *name, const char *expr, const char *val)
{
#ifdef HAVE_AUG_DEFNODE
  static guestfs_int_int_bool r;
  int created;

  NEED_AUG (NULL);

  r.i = aug_defnode (aug, name, expr, val, &created);
  if (r.i == -1) {
    reply_with_error ("Augeas defnode failed");
    return NULL;
  }
  r.b = created;
  return &r;
#else
  NOT_AVAILABLE (NULL);
#endif
}
示例#15
0
char *
do_aug_get (const char *path)
{
#ifdef HAVE_AUGEAS
  const char *value = NULL;
  char *v;
  int r;

  NEED_AUG (NULL);

  r = aug_get (aug, path, &value);
  if (r == 0) {
    reply_with_error ("no matching node");
    return NULL;
  }
  if (r != 1) {
    reply_with_error ("Augeas get failed");
    return NULL;
  }

  /* value can still be NULL here, eg. try with path == "/augeas".
   * I don't understand this case, and it seems to contradict the
   * documentation.
   */
  if (value == NULL) {
    reply_with_error ("Augeas returned NULL match");
    return NULL;
  }

  /* The value is an internal Augeas string, so we must copy it. GC FTW. */
  v = strdup (value);
  if (v == NULL) {
    reply_with_perror ("strdup");
    return NULL;
  }

  return v;			/* Caller frees. */
#else
  NOT_AVAILABLE (NULL);
#endif
}
示例#16
0
int
do_inotify_close (void)
{
#ifdef HAVE_SYS_INOTIFY_H
  NEED_INOTIFY (-1);

  if (inotify_fd == -1) {
    reply_with_error ("handle is not open");
    return -1;
  }

  if (close (inotify_fd) == -1) {
    reply_with_perror ("close");
    return -1;
  }

  inotify_fd = -1;
  inotify_posn = 0;

  return 0;
#else
  NOT_AVAILABLE (-1);
#endif
}
示例#17
0
guestfs_int_inotify_event_list *
do_inotify_read (void)
{
#ifdef HAVE_SYS_INOTIFY_H
  int space;
  guestfs_int_inotify_event_list *ret;

  NEED_INOTIFY (NULL);

  ret = malloc (sizeof *ret);
  if (ret == NULL) {
    reply_with_perror ("malloc");
    return NULL;
  }
  ret->guestfs_int_inotify_event_list_len = 0;
  ret->guestfs_int_inotify_event_list_val = NULL;

  /* Read events that are available, but make sure we won't exceed
   * maximum message size.  In order to achieve this we have to
   * guesstimate the remaining space available.
   */
  space = GUESTFS_MESSAGE_MAX / 2;

  while (space > 0) {
    struct inotify_event *event;
    int r;
    size_t n;

    r = read (inotify_fd, inotify_buf + inotify_posn,
              sizeof (inotify_buf) - inotify_posn);
    if (r == -1) {
      if (errno == EWOULDBLOCK || errno == EAGAIN) /* End of list. */
        break;
      reply_with_perror ("read");
      goto error;
    }
    if (r == 0) {		/* End of file - we're not expecting it. */
      reply_with_error ("unexpected end of file");
      goto error;
    }

    inotify_posn += r;

    /* Read complete events from the buffer and add them to the result. */
    n = 0;
    while (n < inotify_posn) {
      guestfs_int_inotify_event *np;
      guestfs_int_inotify_event *in;

      event = (struct inotify_event *) &inotify_buf[n];

      /* Have we got a complete event in the buffer? */
#ifdef __GNUC__
      if (n + sizeof (struct inotify_event) > inotify_posn ||
          n + sizeof (struct inotify_event) + event->len > inotify_posn)
        break;
#else
#error "this code needs fixing so it works on non-GCC compilers"
#endif

      np = realloc (ret->guestfs_int_inotify_event_list_val,
                    (ret->guestfs_int_inotify_event_list_len + 1) *
                    sizeof (guestfs_int_inotify_event));
      if (np == NULL) {
        reply_with_perror ("realloc");
        goto error;
      }
      ret->guestfs_int_inotify_event_list_val = np;
      in = &ret->guestfs_int_inotify_event_list_val[ret->guestfs_int_inotify_event_list_len];
      ret->guestfs_int_inotify_event_list_len++;

      in->in_wd = event->wd;
      in->in_mask = event->mask;
      in->in_cookie = event->cookie;

      if (event->len > 0)
        in->in_name = strdup (event->name);
      else
        in->in_name = strdup (""); /* Should have optional string fields XXX. */
      if (in->in_name == NULL) {
        reply_with_perror ("strdup");
        goto error;
      }

      /* Estimate space used by this event in the message. */
      space -= 16 + 4 + strlen (in->in_name) + 4;

      /* Move pointer to next event. */
#ifdef __GNUC__
      n += sizeof (struct inotify_event) + event->len;
#else
#error "this code needs fixing so it works on non-GCC compilers"
#endif
    }

    /* 'n' now points to the first unprocessed/incomplete
     * message in the buffer. Copy that to offset 0 in the buffer.
     */
    memmove (inotify_buf, &inotify_buf[n], inotify_posn - n);
    inotify_posn -= n;
  }

  /* Return the messages. */
  return ret;

 error:
  xdr_free ((xdrproc_t) xdr_guestfs_int_inotify_event_list, (char *) ret);
  free (ret);
  return NULL;
#else
  NOT_AVAILABLE (NULL);
#endif
}