reader.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * Copyright (C) 2005 - Alejandro Liu Ly <alejandro_liu@hotmail.com>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. */
  18. /**
  19. * @project mfstool
  20. * @module readers
  21. * @section 3
  22. * @doc routines for reading files
  23. */
  24. #include "minix_fs.h"
  25. #include "protos.h"
  26. #include <sys/stat.h>
  27. #include <utime.h>
  28. #include <unistd.h>
  29. /**
  30. * Read a file from file system
  31. * @param fs - File system structure
  32. * @param fp - Output file
  33. * @param path - File to read
  34. * @param type - Read type: S_IFREG or S_IFLNK
  35. * @param ispipe - If true we do not use fseek to skip holes
  36. */
  37. int readfile(struct minix_fs_dat *fs,FILE *fp,const char *path,
  38. int type,int ispipe) {
  39. int inode = find_inode(fs,path);
  40. int i,bsz,j;
  41. u8 blk[BLOCK_SIZE];
  42. int fdirsize;
  43. if (inode == -1) fatalmsg("%s: not found",path);
  44. if (VERSION_2(fs)) {
  45. struct minix2_inode *ino = INODE2(fs,inode);
  46. if (type == S_IFREG && !S_ISREG(ino->i_mode))
  47. fatalmsg("%s: is not a regular file",path);
  48. else if (type == S_IFLNK && !S_ISLNK(ino->i_mode))
  49. fatalmsg("%s: is not a symbolic link",path);
  50. fdirsize = ino->i_size;
  51. } else {
  52. struct minix_inode *ino = INODE(fs,inode);
  53. if (type == S_IFREG && !S_ISREG(ino->i_mode))
  54. fatalmsg("%s: is not a regular file",path);
  55. else if (type == S_IFLNK && !S_ISLNK(ino->i_mode))
  56. fatalmsg("%s: is not a symbolic link",path);
  57. fdirsize = ino->i_size;
  58. }
  59. for (i = 0; i < fdirsize; i += BLOCK_SIZE) {
  60. bsz = read_inoblk(fs,inode,i / BLOCK_SIZE,blk);
  61. if (bsz) {
  62. dofwrite(fp,blk,bsz);
  63. } else {
  64. bsz = fdirsize - i > BLOCK_SIZE ? BLOCK_SIZE : fdirsize % BLOCK_SIZE;
  65. if (ispipe) {
  66. for (j=0;j<bsz;j++) putc(0,fp);
  67. } else
  68. fseek(fp,bsz,SEEK_CUR);
  69. }
  70. }
  71. return inode;
  72. }
  73. /**
  74. * Similar to UNIX cat command
  75. * @param fs - file system structure
  76. * @param argc - from command line
  77. * @param argv - from command line
  78. */
  79. void cmd_cat(struct minix_fs_dat *fs,int argc,char **argv) {
  80. int i;
  81. for (i=1;i<argc;i++) {
  82. readfile(fs,stdout,argv[i],S_IFREG,1);
  83. }
  84. }
  85. /**
  86. * Extract image files to a normal file
  87. * @param fs - file system structure
  88. * @param argc - from command line
  89. * @param argv - from command line
  90. */
  91. void cmd_extract(struct minix_fs_dat *fs,int argc,char **argv) {
  92. FILE *fp;
  93. struct utimbuf tb;
  94. int uid,gid,mode,inode;
  95. if (argc != 3) fatalmsg("Usage: %s [image file] [output file]\n",argv[0]);
  96. fp = fopen(argv[2],"wb");
  97. if (!fp) die(argv[2]);
  98. inode = readfile(fs,fp,argv[1],S_IFREG,0);
  99. /* We want to copy also the modes ... */
  100. if (VERSION_2(fs)) {
  101. struct minix2_inode *ino = INODE2(fs,inode);
  102. tb.actime = ino->i_atime;
  103. tb.modtime = ino->i_mtime;
  104. uid = ino->i_uid;
  105. gid = ino->i_gid;
  106. mode = ino->i_mode & 07777;
  107. } else {
  108. struct minix_inode *ino = INODE(fs,inode);
  109. tb.modtime = tb.actime = ino->i_time;
  110. uid = ino->i_uid;
  111. gid = ino->i_gid;
  112. mode = ino->i_mode & 07777;
  113. }
  114. fclose(fp);
  115. if (!(opt_squash || getuid())) chown(argv[2],uid,gid);
  116. chmod(argv[2],mode);
  117. utime(argv[2],&tb);
  118. }
  119. /**
  120. * Read contents of a symlink
  121. * @param fs - file system structure
  122. * @param argc - from command line
  123. * @param argv - from command line
  124. */
  125. void cmd_readlink(struct minix_fs_dat *fs,int argc,char **argv) {
  126. if (argc == 1) {
  127. fatalmsg("Usage: %s [links ...]\n",argv[0]);
  128. } else if (argc == 2) {
  129. readfile(fs,stdout,argv[1],S_IFLNK,1);
  130. putc('\n',stdout);
  131. } else {
  132. int i;
  133. for (i=1;i<argc;i++) {
  134. printf("%s: ",argv[i]);
  135. readfile(fs,stdout,argv[i],S_IFLNK,1);
  136. putc('\n',stdout);
  137. }
  138. }
  139. }