hostfs_user.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. /*
  2. * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
  3. * Licensed under the GPL
  4. */
  5. #include <unistd.h>
  6. #include <stdio.h>
  7. #include <fcntl.h>
  8. #include <dirent.h>
  9. #include <errno.h>
  10. #include <utime.h>
  11. #include <string.h>
  12. #include <sys/stat.h>
  13. #include <sys/time.h>
  14. #include <sys/vfs.h>
  15. #include "hostfs.h"
  16. #include "kern_util.h"
  17. #include "user.h"
  18. int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
  19. int *nlink_out, int *uid_out, int *gid_out,
  20. unsigned long long *size_out, struct timespec *atime_out,
  21. struct timespec *mtime_out, struct timespec *ctime_out,
  22. int *blksize_out, unsigned long long *blocks_out)
  23. {
  24. struct stat64 buf;
  25. if(lstat64(path, &buf) < 0)
  26. return(-errno);
  27. if(inode_out != NULL) *inode_out = buf.st_ino;
  28. if(mode_out != NULL) *mode_out = buf.st_mode;
  29. if(nlink_out != NULL) *nlink_out = buf.st_nlink;
  30. if(uid_out != NULL) *uid_out = buf.st_uid;
  31. if(gid_out != NULL) *gid_out = buf.st_gid;
  32. if(size_out != NULL) *size_out = buf.st_size;
  33. if(atime_out != NULL) {
  34. atime_out->tv_sec = buf.st_atime;
  35. atime_out->tv_nsec = 0;
  36. }
  37. if(mtime_out != NULL) {
  38. mtime_out->tv_sec = buf.st_mtime;
  39. mtime_out->tv_nsec = 0;
  40. }
  41. if(ctime_out != NULL) {
  42. ctime_out->tv_sec = buf.st_ctime;
  43. ctime_out->tv_nsec = 0;
  44. }
  45. if(blksize_out != NULL) *blksize_out = buf.st_blksize;
  46. if(blocks_out != NULL) *blocks_out = buf.st_blocks;
  47. return(0);
  48. }
  49. int file_type(const char *path, int *maj, int *min)
  50. {
  51. struct stat64 buf;
  52. if(lstat64(path, &buf) < 0)
  53. return(-errno);
  54. /*We cannot pass rdev as is because glibc and the kernel disagree
  55. *about its definition.*/
  56. if(maj != NULL)
  57. *maj = major(buf.st_rdev);
  58. if(min != NULL)
  59. *min = minor(buf.st_rdev);
  60. if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
  61. else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
  62. else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
  63. else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
  64. else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
  65. else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
  66. else return(OS_TYPE_FILE);
  67. }
  68. int access_file(char *path, int r, int w, int x)
  69. {
  70. int mode = 0;
  71. if(r) mode = R_OK;
  72. if(w) mode |= W_OK;
  73. if(x) mode |= X_OK;
  74. if(access(path, mode) != 0) return(-errno);
  75. else return(0);
  76. }
  77. int open_file(char *path, int r, int w, int append)
  78. {
  79. int mode = 0, fd;
  80. if(r && !w)
  81. mode = O_RDONLY;
  82. else if(!r && w)
  83. mode = O_WRONLY;
  84. else if(r && w)
  85. mode = O_RDWR;
  86. else panic("Impossible mode in open_file");
  87. if(append)
  88. mode |= O_APPEND;
  89. fd = open64(path, mode);
  90. if(fd < 0) return(-errno);
  91. else return(fd);
  92. }
  93. void *open_dir(char *path, int *err_out)
  94. {
  95. DIR *dir;
  96. dir = opendir(path);
  97. *err_out = errno;
  98. if(dir == NULL) return(NULL);
  99. return(dir);
  100. }
  101. char *read_dir(void *stream, unsigned long long *pos,
  102. unsigned long long *ino_out, int *len_out)
  103. {
  104. DIR *dir = stream;
  105. struct dirent *ent;
  106. seekdir(dir, *pos);
  107. ent = readdir(dir);
  108. if(ent == NULL) return(NULL);
  109. *len_out = strlen(ent->d_name);
  110. *ino_out = ent->d_ino;
  111. *pos = telldir(dir);
  112. return(ent->d_name);
  113. }
  114. int read_file(int fd, unsigned long long *offset, char *buf, int len)
  115. {
  116. int n;
  117. n = pread64(fd, buf, len, *offset);
  118. if(n < 0) return(-errno);
  119. *offset += n;
  120. return(n);
  121. }
  122. int write_file(int fd, unsigned long long *offset, const char *buf, int len)
  123. {
  124. int n;
  125. n = pwrite64(fd, buf, len, *offset);
  126. if(n < 0) return(-errno);
  127. *offset += n;
  128. return(n);
  129. }
  130. int lseek_file(int fd, long long offset, int whence)
  131. {
  132. int ret;
  133. ret = lseek64(fd, offset, whence);
  134. if(ret < 0)
  135. return(-errno);
  136. return(0);
  137. }
  138. int fsync_file(int fd, int datasync)
  139. {
  140. int ret;
  141. if (datasync)
  142. ret = fdatasync(fd);
  143. else
  144. ret = fsync(fd);
  145. if (ret < 0)
  146. return -errno;
  147. return 0;
  148. }
  149. void close_file(void *stream)
  150. {
  151. close(*((int *) stream));
  152. }
  153. void close_dir(void *stream)
  154. {
  155. closedir(stream);
  156. }
  157. int file_create(char *name, int ur, int uw, int ux, int gr,
  158. int gw, int gx, int or, int ow, int ox)
  159. {
  160. int mode, fd;
  161. mode = 0;
  162. mode |= ur ? S_IRUSR : 0;
  163. mode |= uw ? S_IWUSR : 0;
  164. mode |= ux ? S_IXUSR : 0;
  165. mode |= gr ? S_IRGRP : 0;
  166. mode |= gw ? S_IWGRP : 0;
  167. mode |= gx ? S_IXGRP : 0;
  168. mode |= or ? S_IROTH : 0;
  169. mode |= ow ? S_IWOTH : 0;
  170. mode |= ox ? S_IXOTH : 0;
  171. fd = open64(name, O_CREAT | O_RDWR, mode);
  172. if(fd < 0)
  173. return(-errno);
  174. return(fd);
  175. }
  176. int set_attr(const char *file, struct hostfs_iattr *attrs)
  177. {
  178. struct utimbuf buf;
  179. int err, ma;
  180. if(attrs->ia_valid & HOSTFS_ATTR_MODE){
  181. if(chmod(file, attrs->ia_mode) != 0) return(-errno);
  182. }
  183. if(attrs->ia_valid & HOSTFS_ATTR_UID){
  184. if(chown(file, attrs->ia_uid, -1)) return(-errno);
  185. }
  186. if(attrs->ia_valid & HOSTFS_ATTR_GID){
  187. if(chown(file, -1, attrs->ia_gid)) return(-errno);
  188. }
  189. if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
  190. if(truncate(file, attrs->ia_size)) return(-errno);
  191. }
  192. ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
  193. if((attrs->ia_valid & ma) == ma){
  194. buf.actime = attrs->ia_atime.tv_sec;
  195. buf.modtime = attrs->ia_mtime.tv_sec;
  196. if(utime(file, &buf) != 0) return(-errno);
  197. }
  198. else {
  199. struct timespec ts;
  200. if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
  201. err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
  202. NULL, NULL, &ts, NULL, NULL, NULL);
  203. if(err != 0)
  204. return(err);
  205. buf.actime = attrs->ia_atime.tv_sec;
  206. buf.modtime = ts.tv_sec;
  207. if(utime(file, &buf) != 0)
  208. return(-errno);
  209. }
  210. if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
  211. err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
  212. NULL, &ts, NULL, NULL, NULL, NULL);
  213. if(err != 0)
  214. return(err);
  215. buf.actime = ts.tv_sec;
  216. buf.modtime = attrs->ia_mtime.tv_sec;
  217. if(utime(file, &buf) != 0)
  218. return(-errno);
  219. }
  220. }
  221. if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
  222. if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
  223. err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL,
  224. &attrs->ia_atime, &attrs->ia_mtime, NULL,
  225. NULL, NULL);
  226. if(err != 0) return(err);
  227. }
  228. return(0);
  229. }
  230. int make_symlink(const char *from, const char *to)
  231. {
  232. int err;
  233. err = symlink(to, from);
  234. if(err) return(-errno);
  235. return(0);
  236. }
  237. int unlink_file(const char *file)
  238. {
  239. int err;
  240. err = unlink(file);
  241. if(err) return(-errno);
  242. return(0);
  243. }
  244. int do_mkdir(const char *file, int mode)
  245. {
  246. int err;
  247. err = mkdir(file, mode);
  248. if(err) return(-errno);
  249. return(0);
  250. }
  251. int do_rmdir(const char *file)
  252. {
  253. int err;
  254. err = rmdir(file);
  255. if(err) return(-errno);
  256. return(0);
  257. }
  258. int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor)
  259. {
  260. int err;
  261. err = mknod(file, mode, makedev(major, minor));
  262. if(err) return(-errno);
  263. return(0);
  264. }
  265. int link_file(const char *to, const char *from)
  266. {
  267. int err;
  268. err = link(to, from);
  269. if(err) return(-errno);
  270. return(0);
  271. }
  272. int do_readlink(char *file, char *buf, int size)
  273. {
  274. int n;
  275. n = readlink(file, buf, size);
  276. if(n < 0)
  277. return(-errno);
  278. if(n < size)
  279. buf[n] = '\0';
  280. return(n);
  281. }
  282. int rename_file(char *from, char *to)
  283. {
  284. int err;
  285. err = rename(from, to);
  286. if(err < 0) return(-errno);
  287. return(0);
  288. }
  289. int do_statfs(char *root, long *bsize_out, long long *blocks_out,
  290. long long *bfree_out, long long *bavail_out,
  291. long long *files_out, long long *ffree_out,
  292. void *fsid_out, int fsid_size, long *namelen_out,
  293. long *spare_out)
  294. {
  295. struct statfs64 buf;
  296. int err;
  297. err = statfs64(root, &buf);
  298. if(err < 0) return(-errno);
  299. *bsize_out = buf.f_bsize;
  300. *blocks_out = buf.f_blocks;
  301. *bfree_out = buf.f_bfree;
  302. *bavail_out = buf.f_bavail;
  303. *files_out = buf.f_files;
  304. *ffree_out = buf.f_ffree;
  305. memcpy(fsid_out, &buf.f_fsid,
  306. sizeof(buf.f_fsid) > fsid_size ? fsid_size :
  307. sizeof(buf.f_fsid));
  308. *namelen_out = buf.f_namelen;
  309. spare_out[0] = buf.f_spare[0];
  310. spare_out[1] = buf.f_spare[1];
  311. spare_out[2] = buf.f_spare[2];
  312. spare_out[3] = buf.f_spare[3];
  313. spare_out[4] = buf.f_spare[4];
  314. return(0);
  315. }
  316. /*
  317. * Overrides for Emacs so that we follow Linus's tabbing style.
  318. * Emacs will notice this stuff at the end of the file and automatically
  319. * adjust the settings for this buffer only. This must remain at the end
  320. * of the file.
  321. * ---------------------------------------------------------------------------
  322. * Local variables:
  323. * c-file-style: "linux"
  324. * End:
  325. */