hostfs_user.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  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) return(-errno);
  135. return(0);
  136. }
  137. void close_file(void *stream)
  138. {
  139. close(*((int *) stream));
  140. }
  141. void close_dir(void *stream)
  142. {
  143. closedir(stream);
  144. }
  145. int file_create(char *name, int ur, int uw, int ux, int gr,
  146. int gw, int gx, int or, int ow, int ox)
  147. {
  148. int mode, fd;
  149. mode = 0;
  150. mode |= ur ? S_IRUSR : 0;
  151. mode |= uw ? S_IWUSR : 0;
  152. mode |= ux ? S_IXUSR : 0;
  153. mode |= gr ? S_IRGRP : 0;
  154. mode |= gw ? S_IWGRP : 0;
  155. mode |= gx ? S_IXGRP : 0;
  156. mode |= or ? S_IROTH : 0;
  157. mode |= ow ? S_IWOTH : 0;
  158. mode |= ox ? S_IXOTH : 0;
  159. fd = open64(name, O_CREAT | O_RDWR, mode);
  160. if(fd < 0)
  161. return(-errno);
  162. return(fd);
  163. }
  164. int set_attr(const char *file, struct hostfs_iattr *attrs)
  165. {
  166. struct utimbuf buf;
  167. int err, ma;
  168. if(attrs->ia_valid & HOSTFS_ATTR_MODE){
  169. if(chmod(file, attrs->ia_mode) != 0) return(-errno);
  170. }
  171. if(attrs->ia_valid & HOSTFS_ATTR_UID){
  172. if(chown(file, attrs->ia_uid, -1)) return(-errno);
  173. }
  174. if(attrs->ia_valid & HOSTFS_ATTR_GID){
  175. if(chown(file, -1, attrs->ia_gid)) return(-errno);
  176. }
  177. if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
  178. if(truncate(file, attrs->ia_size)) return(-errno);
  179. }
  180. ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
  181. if((attrs->ia_valid & ma) == ma){
  182. buf.actime = attrs->ia_atime.tv_sec;
  183. buf.modtime = attrs->ia_mtime.tv_sec;
  184. if(utime(file, &buf) != 0) return(-errno);
  185. }
  186. else {
  187. struct timespec ts;
  188. if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
  189. err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
  190. NULL, NULL, &ts, NULL, NULL, NULL);
  191. if(err != 0)
  192. return(err);
  193. buf.actime = attrs->ia_atime.tv_sec;
  194. buf.modtime = ts.tv_sec;
  195. if(utime(file, &buf) != 0)
  196. return(-errno);
  197. }
  198. if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
  199. err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
  200. NULL, &ts, NULL, NULL, NULL, NULL);
  201. if(err != 0)
  202. return(err);
  203. buf.actime = ts.tv_sec;
  204. buf.modtime = attrs->ia_mtime.tv_sec;
  205. if(utime(file, &buf) != 0)
  206. return(-errno);
  207. }
  208. }
  209. if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
  210. if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
  211. err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL,
  212. &attrs->ia_atime, &attrs->ia_mtime, NULL,
  213. NULL, NULL);
  214. if(err != 0) return(err);
  215. }
  216. return(0);
  217. }
  218. int make_symlink(const char *from, const char *to)
  219. {
  220. int err;
  221. err = symlink(to, from);
  222. if(err) return(-errno);
  223. return(0);
  224. }
  225. int unlink_file(const char *file)
  226. {
  227. int err;
  228. err = unlink(file);
  229. if(err) return(-errno);
  230. return(0);
  231. }
  232. int do_mkdir(const char *file, int mode)
  233. {
  234. int err;
  235. err = mkdir(file, mode);
  236. if(err) return(-errno);
  237. return(0);
  238. }
  239. int do_rmdir(const char *file)
  240. {
  241. int err;
  242. err = rmdir(file);
  243. if(err) return(-errno);
  244. return(0);
  245. }
  246. int do_mknod(const char *file, int mode, int dev)
  247. {
  248. int err;
  249. err = mknod(file, mode, dev);
  250. if(err) return(-errno);
  251. return(0);
  252. }
  253. int link_file(const char *to, const char *from)
  254. {
  255. int err;
  256. err = link(to, from);
  257. if(err) return(-errno);
  258. return(0);
  259. }
  260. int do_readlink(char *file, char *buf, int size)
  261. {
  262. int n;
  263. n = readlink(file, buf, size);
  264. if(n < 0)
  265. return(-errno);
  266. if(n < size)
  267. buf[n] = '\0';
  268. return(n);
  269. }
  270. int rename_file(char *from, char *to)
  271. {
  272. int err;
  273. err = rename(from, to);
  274. if(err < 0) return(-errno);
  275. return(0);
  276. }
  277. int do_statfs(char *root, long *bsize_out, long long *blocks_out,
  278. long long *bfree_out, long long *bavail_out,
  279. long long *files_out, long long *ffree_out,
  280. void *fsid_out, int fsid_size, long *namelen_out,
  281. long *spare_out)
  282. {
  283. struct statfs64 buf;
  284. int err;
  285. err = statfs64(root, &buf);
  286. if(err < 0) return(-errno);
  287. *bsize_out = buf.f_bsize;
  288. *blocks_out = buf.f_blocks;
  289. *bfree_out = buf.f_bfree;
  290. *bavail_out = buf.f_bavail;
  291. *files_out = buf.f_files;
  292. *ffree_out = buf.f_ffree;
  293. memcpy(fsid_out, &buf.f_fsid,
  294. sizeof(buf.f_fsid) > fsid_size ? fsid_size :
  295. sizeof(buf.f_fsid));
  296. *namelen_out = buf.f_namelen;
  297. spare_out[0] = buf.f_spare[0];
  298. spare_out[1] = buf.f_spare[1];
  299. spare_out[2] = buf.f_spare[2];
  300. spare_out[3] = buf.f_spare[3];
  301. spare_out[4] = buf.f_spare[4];
  302. spare_out[5] = buf.f_spare[5];
  303. return(0);
  304. }
  305. /*
  306. * Overrides for Emacs so that we follow Linus's tabbing style.
  307. * Emacs will notice this stuff at the end of the file and automatically
  308. * adjust the settings for this buffer only. This must remain at the end
  309. * of the file.
  310. * ---------------------------------------------------------------------------
  311. * Local variables:
  312. * c-file-style: "linux"
  313. * End:
  314. */