X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=daemon%2Fstat.c;h=22592bb2dd2269a93ec9ba0a7e022ca88ac6f255;hp=da2d2740761fda1b1214dc4af036a0c446db452c;hb=HEAD;hpb=0dd6c8c8442d4ff588f6dac2efab24d3409b0dec diff --git a/daemon/stat.c b/daemon/stat.c index da2d274..22592bb 100644 --- a/daemon/stat.c +++ b/daemon/stat.c @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include @@ -23,29 +23,26 @@ #include #include #include -#include +#include #include -#include "../src/guestfs_protocol.h" +#include "guestfs_protocol.h" #include "daemon.h" #include "actions.h" guestfs_int_stat * -do_stat (char *path) +do_stat (const char *path) { int r; guestfs_int_stat *ret; struct stat statbuf; - NEED_ROOT (NULL); - ABS_PATH (path, return NULL); - CHROOT_IN; r = stat (path, &statbuf); CHROOT_OUT; if (r == -1) { - reply_with_perror ("stat"); + reply_with_perror ("%s", path); return NULL; } @@ -63,8 +60,16 @@ do_stat (char *path) ret->gid = statbuf.st_gid; ret->rdev = statbuf.st_rdev; ret->size = statbuf.st_size; +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE ret->blksize = statbuf.st_blksize; +#else + ret->blksize = -1; +#endif +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS ret->blocks = statbuf.st_blocks; +#else + ret->blocks = -1; +#endif ret->atime = statbuf.st_atime; ret->mtime = statbuf.st_mtime; ret->ctime = statbuf.st_ctime; @@ -73,21 +78,18 @@ do_stat (char *path) } guestfs_int_stat * -do_lstat (char *path) +do_lstat (const char *path) { int r; guestfs_int_stat *ret; struct stat statbuf; - NEED_ROOT (NULL); - ABS_PATH (path, return NULL); - CHROOT_IN; r = lstat (path, &statbuf); CHROOT_OUT; if (r == -1) { - reply_with_perror ("stat"); + reply_with_perror ("%s", path); return NULL; } @@ -105,8 +107,16 @@ do_lstat (char *path) ret->gid = statbuf.st_gid; ret->rdev = statbuf.st_rdev; ret->size = statbuf.st_size; +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE ret->blksize = statbuf.st_blksize; +#else + ret->blksize = -1; +#endif +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS ret->blocks = statbuf.st_blocks; +#else + ret->blocks = -1; +#endif ret->atime = statbuf.st_atime; ret->mtime = statbuf.st_mtime; ret->ctime = statbuf.st_ctime; @@ -114,42 +124,77 @@ do_lstat (char *path) return ret; } -guestfs_int_statvfs * -do_statvfs (char *path) +guestfs_int_stat_list * +do_lstatlist (const char *path, char *const *names) { - int r; - guestfs_int_statvfs *ret; - struct statvfs statbuf; + int path_fd; + guestfs_int_stat_list *ret; + size_t i, nr_names; - NEED_ROOT (NULL); - ABS_PATH (path, return NULL); + nr_names = count_strings (names); + + ret = malloc (sizeof *ret); + if (!ret) { + reply_with_perror ("malloc"); + return NULL; + } + ret->guestfs_int_stat_list_len = nr_names; + ret->guestfs_int_stat_list_val = calloc (nr_names, sizeof (guestfs_int_stat)); + if (ret->guestfs_int_stat_list_val == NULL) { + reply_with_perror ("malloc"); + free (ret); + return NULL; + } CHROOT_IN; - r = statvfs (path, &statbuf); + path_fd = open (path, O_RDONLY | O_DIRECTORY); CHROOT_OUT; - if (r == -1) { - reply_with_perror ("statvfs"); + if (path_fd == -1) { + reply_with_perror ("%s", path); + free (ret->guestfs_int_stat_list_val); + free (ret); return NULL; } - ret = malloc (sizeof *ret); - if (ret == NULL) { - reply_with_perror ("malloc"); - return NULL; + for (i = 0; names[i] != NULL; ++i) { + int r; + struct stat statbuf; + + r = fstatat (path_fd, names[i], &statbuf, AT_SYMLINK_NOFOLLOW); + if (r == -1) + ret->guestfs_int_stat_list_val[i].ino = -1; + else { + ret->guestfs_int_stat_list_val[i].dev = statbuf.st_dev; + ret->guestfs_int_stat_list_val[i].ino = statbuf.st_ino; + ret->guestfs_int_stat_list_val[i].mode = statbuf.st_mode; + ret->guestfs_int_stat_list_val[i].nlink = statbuf.st_nlink; + ret->guestfs_int_stat_list_val[i].uid = statbuf.st_uid; + ret->guestfs_int_stat_list_val[i].gid = statbuf.st_gid; + ret->guestfs_int_stat_list_val[i].rdev = statbuf.st_rdev; + ret->guestfs_int_stat_list_val[i].size = statbuf.st_size; +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE + ret->guestfs_int_stat_list_val[i].blksize = statbuf.st_blksize; +#else + ret->guestfs_int_stat_list_val[i].blksize = -1; +#endif +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS + ret->guestfs_int_stat_list_val[i].blocks = statbuf.st_blocks; +#else + ret->guestfs_int_stat_list_val[i].blocks = -1; +#endif + ret->guestfs_int_stat_list_val[i].atime = statbuf.st_atime; + ret->guestfs_int_stat_list_val[i].mtime = statbuf.st_mtime; + ret->guestfs_int_stat_list_val[i].ctime = statbuf.st_ctime; + } } - ret->bsize = statbuf.f_bsize; - ret->frsize = statbuf.f_frsize; - ret->blocks = statbuf.f_blocks; - ret->bfree = statbuf.f_bfree; - ret->bavail = statbuf.f_bavail; - ret->files = statbuf.f_files; - ret->ffree = statbuf.f_ffree; - ret->favail = statbuf.f_favail; - ret->fsid = statbuf.f_fsid; - ret->flag = statbuf.f_flag; - ret->namemax = statbuf.f_namemax; + if (close (path_fd) == -1) { + reply_with_perror ("close: %s", path); + free (ret->guestfs_int_stat_list_val); + free (ret); + return NULL; + } return ret; }