/* 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 }
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 }
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 }
int do_aug_close (void) { #ifdef HAVE_AUGEAS NEED_AUG(-1); aug_close (aug); aug = NULL; return 0; #else NOT_AVAILABLE (-1); #endif }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }