diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/guestfs-actions.c | 225 | ||||
-rw-r--r-- | src/guestfs-actions.h | 3 | ||||
-rw-r--r-- | src/guestfs-structs.h | 30 | ||||
-rw-r--r-- | src/guestfs_protocol.c | 124 | ||||
-rw-r--r-- | src/guestfs_protocol.h | 83 | ||||
-rw-r--r-- | src/guestfs_protocol.x | 57 |
6 files changed, 521 insertions, 1 deletions
diff --git a/src/guestfs-actions.c b/src/guestfs-actions.c index c6f574a7..8f40102e 100644 --- a/src/guestfs-actions.c +++ b/src/guestfs-actions.c @@ -3699,3 +3699,228 @@ char **guestfs_command_lines (guestfs_h *g, return rv.ret.lines.lines_val; } +struct stat_rv { + int cb_done; /* flag to indicate callback was called */ + struct guestfs_message_header hdr; + struct guestfs_message_error err; + struct guestfs_stat_ret ret; +}; + +static void stat_cb (guestfs_h *g, void *data, XDR *xdr) +{ + struct stat_rv *rv = (struct stat_rv *) data; + + if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + error (g, "guestfs_stat: failed to parse reply header"); + return; + } + if (rv->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &rv->err)) { + error (g, "guestfs_stat: failed to parse reply error"); + return; + } + goto done; + } + if (!xdr_guestfs_stat_ret (xdr, &rv->ret)) { + error (g, "guestfs_stat: failed to parse reply"); + return; + } + done: + rv->cb_done = 1; + main_loop.main_loop_quit (g); +} + +struct guestfs_stat *guestfs_stat (guestfs_h *g, + const char *path) +{ + struct guestfs_stat_args args; + struct stat_rv rv; + int serial; + + if (g->state != READY) { + error (g, "guestfs_stat called from the wrong state, %d != READY", + g->state); + return NULL; + } + + memset (&rv, 0, sizeof rv); + + args.path = (char *) path; + serial = dispatch (g, GUESTFS_PROC_STAT, + (xdrproc_t) xdr_guestfs_stat_args, (char *) &args); + if (serial == -1) + return NULL; + + rv.cb_done = 0; + g->reply_cb_internal = stat_cb; + g->reply_cb_internal_data = &rv; + main_loop.main_loop_run (g); + g->reply_cb_internal = NULL; + g->reply_cb_internal_data = NULL; + if (!rv.cb_done) { + error (g, "guestfs_stat failed, see earlier error messages"); + return NULL; + } + + if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_STAT, serial) == -1) + return NULL; + + if (rv.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", rv.err.error); + return NULL; + } + + /* caller will free this */ + return safe_memdup (g, &rv.ret.statbuf, sizeof (rv.ret.statbuf)); +} + +struct lstat_rv { + int cb_done; /* flag to indicate callback was called */ + struct guestfs_message_header hdr; + struct guestfs_message_error err; + struct guestfs_lstat_ret ret; +}; + +static void lstat_cb (guestfs_h *g, void *data, XDR *xdr) +{ + struct lstat_rv *rv = (struct lstat_rv *) data; + + if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + error (g, "guestfs_lstat: failed to parse reply header"); + return; + } + if (rv->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &rv->err)) { + error (g, "guestfs_lstat: failed to parse reply error"); + return; + } + goto done; + } + if (!xdr_guestfs_lstat_ret (xdr, &rv->ret)) { + error (g, "guestfs_lstat: failed to parse reply"); + return; + } + done: + rv->cb_done = 1; + main_loop.main_loop_quit (g); +} + +struct guestfs_stat *guestfs_lstat (guestfs_h *g, + const char *path) +{ + struct guestfs_lstat_args args; + struct lstat_rv rv; + int serial; + + if (g->state != READY) { + error (g, "guestfs_lstat called from the wrong state, %d != READY", + g->state); + return NULL; + } + + memset (&rv, 0, sizeof rv); + + args.path = (char *) path; + serial = dispatch (g, GUESTFS_PROC_LSTAT, + (xdrproc_t) xdr_guestfs_lstat_args, (char *) &args); + if (serial == -1) + return NULL; + + rv.cb_done = 0; + g->reply_cb_internal = lstat_cb; + g->reply_cb_internal_data = &rv; + main_loop.main_loop_run (g); + g->reply_cb_internal = NULL; + g->reply_cb_internal_data = NULL; + if (!rv.cb_done) { + error (g, "guestfs_lstat failed, see earlier error messages"); + return NULL; + } + + if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_LSTAT, serial) == -1) + return NULL; + + if (rv.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", rv.err.error); + return NULL; + } + + /* caller will free this */ + return safe_memdup (g, &rv.ret.statbuf, sizeof (rv.ret.statbuf)); +} + +struct statvfs_rv { + int cb_done; /* flag to indicate callback was called */ + struct guestfs_message_header hdr; + struct guestfs_message_error err; + struct guestfs_statvfs_ret ret; +}; + +static void statvfs_cb (guestfs_h *g, void *data, XDR *xdr) +{ + struct statvfs_rv *rv = (struct statvfs_rv *) data; + + if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + error (g, "guestfs_statvfs: failed to parse reply header"); + return; + } + if (rv->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &rv->err)) { + error (g, "guestfs_statvfs: failed to parse reply error"); + return; + } + goto done; + } + if (!xdr_guestfs_statvfs_ret (xdr, &rv->ret)) { + error (g, "guestfs_statvfs: failed to parse reply"); + return; + } + done: + rv->cb_done = 1; + main_loop.main_loop_quit (g); +} + +struct guestfs_statvfs *guestfs_statvfs (guestfs_h *g, + const char *path) +{ + struct guestfs_statvfs_args args; + struct statvfs_rv rv; + int serial; + + if (g->state != READY) { + error (g, "guestfs_statvfs called from the wrong state, %d != READY", + g->state); + return NULL; + } + + memset (&rv, 0, sizeof rv); + + args.path = (char *) path; + serial = dispatch (g, GUESTFS_PROC_STATVFS, + (xdrproc_t) xdr_guestfs_statvfs_args, (char *) &args); + if (serial == -1) + return NULL; + + rv.cb_done = 0; + g->reply_cb_internal = statvfs_cb; + g->reply_cb_internal_data = &rv; + main_loop.main_loop_run (g); + g->reply_cb_internal = NULL; + g->reply_cb_internal_data = NULL; + if (!rv.cb_done) { + error (g, "guestfs_statvfs failed, see earlier error messages"); + return NULL; + } + + if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_STATVFS, serial) == -1) + return NULL; + + if (rv.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", rv.err.error); + return NULL; + } + + /* caller will free this */ + return safe_memdup (g, &rv.ret.statbuf, sizeof (rv.ret.statbuf)); +} + diff --git a/src/guestfs-actions.h b/src/guestfs-actions.h index 06efabf0..a838a049 100644 --- a/src/guestfs-actions.h +++ b/src/guestfs-actions.h @@ -82,3 +82,6 @@ extern int guestfs_lvm_remove_all (guestfs_h *handle); extern char *guestfs_file (guestfs_h *handle, const char *path); extern char *guestfs_command (guestfs_h *handle, char * const* const arguments); extern char **guestfs_command_lines (guestfs_h *handle, char * const* const arguments); +extern struct guestfs_stat *guestfs_stat (guestfs_h *handle, const char *path); +extern struct guestfs_stat *guestfs_lstat (guestfs_h *handle, const char *path); +extern struct guestfs_statvfs *guestfs_statvfs (guestfs_h *handle, const char *path); diff --git a/src/guestfs-structs.h b/src/guestfs-structs.h index b3751cd5..76ac8199 100644 --- a/src/guestfs-structs.h +++ b/src/guestfs-structs.h @@ -97,3 +97,33 @@ struct guestfs_lvm_lv_list { struct guestfs_lvm_lv *val; }; +struct guestfs_stat { + int64_t dev; + int64_t ino; + int64_t mode; + int64_t nlink; + int64_t uid; + int64_t gid; + int64_t rdev; + int64_t size; + int64_t blksize; + int64_t blocks; + int64_t atime; + int64_t mtime; + int64_t ctime; +}; + +struct guestfs_statvfs { + int64_t bsize; + int64_t frsize; + int64_t blocks; + int64_t bfree; + int64_t bavail; + int64_t files; + int64_t ffree; + int64_t favail; + int64_t fsid; + int64_t flag; + int64_t namemax; +}; + diff --git a/src/guestfs_protocol.c b/src/guestfs_protocol.c index 0849f7ae..99377b4d 100644 --- a/src/guestfs_protocol.c +++ b/src/guestfs_protocol.c @@ -174,6 +174,70 @@ xdr_guestfs_lvm_int_lv_list (XDR *xdrs, guestfs_lvm_int_lv_list *objp) } bool_t +xdr_guestfs_int_stat (XDR *xdrs, guestfs_int_stat *objp) +{ + register int32_t *buf; + + if (!xdr_quad_t (xdrs, &objp->dev)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->ino)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->mode)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->nlink)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->uid)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->gid)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->rdev)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->size)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->blksize)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->blocks)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->atime)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->mtime)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->ctime)) + return FALSE; + return TRUE; +} + +bool_t +xdr_guestfs_int_statvfs (XDR *xdrs, guestfs_int_statvfs *objp) +{ + register int32_t *buf; + + if (!xdr_quad_t (xdrs, &objp->bsize)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->frsize)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->blocks)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->bfree)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->bavail)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->files)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->ffree)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->favail)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->fsid)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->flag)) + return FALSE; + if (!xdr_quad_t (xdrs, &objp->namemax)) + return FALSE; + return TRUE; +} + +bool_t xdr_guestfs_mount_args (XDR *xdrs, guestfs_mount_args *objp) { register int32_t *buf; @@ -890,6 +954,66 @@ xdr_guestfs_command_lines_ret (XDR *xdrs, guestfs_command_lines_ret *objp) } bool_t +xdr_guestfs_stat_args (XDR *xdrs, guestfs_stat_args *objp) +{ + register int32_t *buf; + + if (!xdr_string (xdrs, &objp->path, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_guestfs_stat_ret (XDR *xdrs, guestfs_stat_ret *objp) +{ + register int32_t *buf; + + if (!xdr_guestfs_int_stat (xdrs, &objp->statbuf)) + return FALSE; + return TRUE; +} + +bool_t +xdr_guestfs_lstat_args (XDR *xdrs, guestfs_lstat_args *objp) +{ + register int32_t *buf; + + if (!xdr_string (xdrs, &objp->path, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_guestfs_lstat_ret (XDR *xdrs, guestfs_lstat_ret *objp) +{ + register int32_t *buf; + + if (!xdr_guestfs_int_stat (xdrs, &objp->statbuf)) + return FALSE; + return TRUE; +} + +bool_t +xdr_guestfs_statvfs_args (XDR *xdrs, guestfs_statvfs_args *objp) +{ + register int32_t *buf; + + if (!xdr_string (xdrs, &objp->path, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_guestfs_statvfs_ret (XDR *xdrs, guestfs_statvfs_ret *objp) +{ + register int32_t *buf; + + if (!xdr_guestfs_int_statvfs (xdrs, &objp->statbuf)) + return FALSE; + return TRUE; +} + +bool_t xdr_guestfs_procedure (XDR *xdrs, guestfs_procedure *objp) { register int32_t *buf; diff --git a/src/guestfs_protocol.h b/src/guestfs_protocol.h index 4b314682..07207237 100644 --- a/src/guestfs_protocol.h +++ b/src/guestfs_protocol.h @@ -92,6 +92,38 @@ typedef struct { guestfs_lvm_int_lv *guestfs_lvm_int_lv_list_val; } guestfs_lvm_int_lv_list; +struct guestfs_int_stat { + quad_t dev; + quad_t ino; + quad_t mode; + quad_t nlink; + quad_t uid; + quad_t gid; + quad_t rdev; + quad_t size; + quad_t blksize; + quad_t blocks; + quad_t atime; + quad_t mtime; + quad_t ctime; +}; +typedef struct guestfs_int_stat guestfs_int_stat; + +struct guestfs_int_statvfs { + quad_t bsize; + quad_t frsize; + quad_t blocks; + quad_t bfree; + quad_t bavail; + quad_t files; + quad_t ffree; + quad_t favail; + quad_t fsid; + quad_t flag; + quad_t namemax; +}; +typedef struct guestfs_int_statvfs guestfs_int_statvfs; + struct guestfs_mount_args { char *device; char *mountpoint; @@ -465,6 +497,36 @@ struct guestfs_command_lines_ret { }; typedef struct guestfs_command_lines_ret guestfs_command_lines_ret; +struct guestfs_stat_args { + char *path; +}; +typedef struct guestfs_stat_args guestfs_stat_args; + +struct guestfs_stat_ret { + guestfs_int_stat statbuf; +}; +typedef struct guestfs_stat_ret guestfs_stat_ret; + +struct guestfs_lstat_args { + char *path; +}; +typedef struct guestfs_lstat_args guestfs_lstat_args; + +struct guestfs_lstat_ret { + guestfs_int_stat statbuf; +}; +typedef struct guestfs_lstat_ret guestfs_lstat_ret; + +struct guestfs_statvfs_args { + char *path; +}; +typedef struct guestfs_statvfs_args guestfs_statvfs_args; + +struct guestfs_statvfs_ret { + guestfs_int_statvfs statbuf; +}; +typedef struct guestfs_statvfs_ret guestfs_statvfs_ret; + enum guestfs_procedure { GUESTFS_PROC_MOUNT = 1, GUESTFS_PROC_SYNC = 2, @@ -517,7 +579,10 @@ enum guestfs_procedure { GUESTFS_PROC_FILE = 49, GUESTFS_PROC_COMMAND = 50, GUESTFS_PROC_COMMAND_LINES = 51, - GUESTFS_PROC_dummy = 51 + 1, + GUESTFS_PROC_STAT = 52, + GUESTFS_PROC_LSTAT = 53, + GUESTFS_PROC_STATVFS = 54, + GUESTFS_PROC_dummy = 54 + 1, }; typedef enum guestfs_procedure guestfs_procedure; #define GUESTFS_MESSAGE_MAX 4194304 @@ -562,6 +627,8 @@ extern bool_t xdr_guestfs_lvm_int_vg (XDR *, guestfs_lvm_int_vg*); extern bool_t xdr_guestfs_lvm_int_vg_list (XDR *, guestfs_lvm_int_vg_list*); extern bool_t xdr_guestfs_lvm_int_lv (XDR *, guestfs_lvm_int_lv*); extern bool_t xdr_guestfs_lvm_int_lv_list (XDR *, guestfs_lvm_int_lv_list*); +extern bool_t xdr_guestfs_int_stat (XDR *, guestfs_int_stat*); +extern bool_t xdr_guestfs_int_statvfs (XDR *, guestfs_int_statvfs*); extern bool_t xdr_guestfs_mount_args (XDR *, guestfs_mount_args*); extern bool_t xdr_guestfs_touch_args (XDR *, guestfs_touch_args*); extern bool_t xdr_guestfs_cat_args (XDR *, guestfs_cat_args*); @@ -623,6 +690,12 @@ extern bool_t xdr_guestfs_command_args (XDR *, guestfs_command_args*); extern bool_t xdr_guestfs_command_ret (XDR *, guestfs_command_ret*); extern bool_t xdr_guestfs_command_lines_args (XDR *, guestfs_command_lines_args*); extern bool_t xdr_guestfs_command_lines_ret (XDR *, guestfs_command_lines_ret*); +extern bool_t xdr_guestfs_stat_args (XDR *, guestfs_stat_args*); +extern bool_t xdr_guestfs_stat_ret (XDR *, guestfs_stat_ret*); +extern bool_t xdr_guestfs_lstat_args (XDR *, guestfs_lstat_args*); +extern bool_t xdr_guestfs_lstat_ret (XDR *, guestfs_lstat_ret*); +extern bool_t xdr_guestfs_statvfs_args (XDR *, guestfs_statvfs_args*); +extern bool_t xdr_guestfs_statvfs_ret (XDR *, guestfs_statvfs_ret*); extern bool_t xdr_guestfs_procedure (XDR *, guestfs_procedure*); extern bool_t xdr_guestfs_message_direction (XDR *, guestfs_message_direction*); extern bool_t xdr_guestfs_message_status (XDR *, guestfs_message_status*); @@ -637,6 +710,8 @@ extern bool_t xdr_guestfs_lvm_int_vg (); extern bool_t xdr_guestfs_lvm_int_vg_list (); extern bool_t xdr_guestfs_lvm_int_lv (); extern bool_t xdr_guestfs_lvm_int_lv_list (); +extern bool_t xdr_guestfs_int_stat (); +extern bool_t xdr_guestfs_int_statvfs (); extern bool_t xdr_guestfs_mount_args (); extern bool_t xdr_guestfs_touch_args (); extern bool_t xdr_guestfs_cat_args (); @@ -698,6 +773,12 @@ extern bool_t xdr_guestfs_command_args (); extern bool_t xdr_guestfs_command_ret (); extern bool_t xdr_guestfs_command_lines_args (); extern bool_t xdr_guestfs_command_lines_ret (); +extern bool_t xdr_guestfs_stat_args (); +extern bool_t xdr_guestfs_stat_ret (); +extern bool_t xdr_guestfs_lstat_args (); +extern bool_t xdr_guestfs_lstat_ret (); +extern bool_t xdr_guestfs_statvfs_args (); +extern bool_t xdr_guestfs_statvfs_ret (); extern bool_t xdr_guestfs_procedure (); extern bool_t xdr_guestfs_message_direction (); extern bool_t xdr_guestfs_message_status (); diff --git a/src/guestfs_protocol.x b/src/guestfs_protocol.x index 68362d64..e03aef66 100644 --- a/src/guestfs_protocol.x +++ b/src/guestfs_protocol.x @@ -85,6 +85,36 @@ struct guestfs_lvm_int_lv { typedef struct guestfs_lvm_int_lv guestfs_lvm_int_lv_list<>; +struct guestfs_int_stat { + hyper dev; + hyper ino; + hyper mode; + hyper nlink; + hyper uid; + hyper gid; + hyper rdev; + hyper size; + hyper blksize; + hyper blocks; + hyper atime; + hyper mtime; + hyper ctime; +}; + +struct guestfs_int_statvfs { + hyper bsize; + hyper frsize; + hyper blocks; + hyper bfree; + hyper bavail; + hyper files; + hyper ffree; + hyper favail; + hyper fsid; + hyper flag; + hyper namemax; +}; + struct guestfs_mount_args { string device<>; string mountpoint<>; @@ -352,6 +382,30 @@ struct guestfs_command_lines_ret { str lines<>; }; +struct guestfs_stat_args { + string path<>; +}; + +struct guestfs_stat_ret { + guestfs_int_stat statbuf; +}; + +struct guestfs_lstat_args { + string path<>; +}; + +struct guestfs_lstat_ret { + guestfs_int_stat statbuf; +}; + +struct guestfs_statvfs_args { + string path<>; +}; + +struct guestfs_statvfs_ret { + guestfs_int_statvfs statbuf; +}; + enum guestfs_procedure { GUESTFS_PROC_MOUNT = 1, GUESTFS_PROC_SYNC = 2, @@ -404,6 +458,9 @@ enum guestfs_procedure { GUESTFS_PROC_FILE = 49, GUESTFS_PROC_COMMAND = 50, GUESTFS_PROC_COMMAND_LINES = 51, + GUESTFS_PROC_STAT = 52, + GUESTFS_PROC_LSTAT = 53, + GUESTFS_PROC_STATVFS = 54, GUESTFS_PROC_dummy }; |