cpio.om (2966B)
1 func main(argc: int, argv: **byte, envp: **byte) { 2 var opts: int; 3 var i: int; 4 var a: alloc; 5 var fd: int; 6 var name: *byte; 7 var stdin: *file; 8 var stdout: *file; 9 var stderr: *file; 10 var stat: stat; 11 var buf: *byte; 12 var len: int; 13 var n: int; 14 var m: int; 15 var k: int; 16 var ret: int; 17 18 setup_alloc(&a); 19 20 i = 1; 21 loop { 22 if i >= argc { 23 break; 24 } 25 26 if !strcmp(argv[i], "-o") { 27 opts = opts | 1; 28 } else { 29 die("invalid argument"); 30 } 31 32 i = i + 1; 33 } 34 35 stdin = fopen(0, &a); 36 stdout = fopen(1, &a); 37 stderr = fopen(2, &a); 38 39 name = alloc(&a, 4096); 40 buf = alloc(&a, 4096); 41 42 loop { 43 if stdin.eof { 44 break; 45 } 46 47 len = fgets(stdin, name, 4096); 48 if len == 0 { 49 continue; 50 } 51 52 if len == 4096 { 53 fflush(stdout); 54 fputs(stderr, "name truncated: "); 55 fputs(stderr, name); 56 fputs(stderr, "\n"); 57 exit(1); 58 } 59 60 fd = open(name, 0, 0); 61 if fd < 0 { 62 fflush(stdout); 63 fputs(stderr, "failed to open: "); 64 fputs(stderr, name); 65 fputs(stderr, "\n"); 66 exit(1); 67 } 68 69 if fstat(fd, &stat) < 0 { 70 fflush(stdout); 71 fputs(stderr, "stat failed: "); 72 fputs(stderr, name); 73 fputs(stderr, "\n"); 74 exit(1); 75 } 76 77 // header 78 fputs(stdout, "070701"); 79 fputh32(stdout, stat.ino & (-1 >> 32)); 80 fputh32(stdout, stat.mode); 81 fputh32(stdout, 0); 82 fputh32(stdout, 0); 83 fputh32(stdout, stat.nlink); 84 fputh32(stdout, stat.mtime); 85 fputh32(stdout, stat.size); 86 fputh32(stdout, stat.dev >> 8); 87 fputh32(stdout, stat.dev & 255); 88 fputh32(stdout, stat.rdev >> 8); 89 fputh32(stdout, (stat.rdev) & 255); 90 fputh32(stdout, len + 1); 91 fputh32(stdout, 0); 92 93 fputs(stdout, name); 94 fputc(stdout, 0); 95 96 // align to four bytes 97 falign(stdout, len + 3); 98 fflush(stdout); 99 100 // copy data 101 n = 0; 102 loop { 103 if n == stat.size { 104 break; 105 } 106 107 k = read(fd, buf, 4096); 108 if k <= 0 { 109 die("failed to read"); 110 } 111 112 if n + k > stat.size { 113 k = stat.size - n; 114 } 115 116 m = 0; 117 loop { 118 if m == k { 119 break; 120 } 121 122 ret = write(1, &buf[m], k - m); 123 if ret < 0 { 124 die("failed to write"); 125 } 126 127 m = m + ret; 128 } 129 130 n = n + k; 131 } 132 133 // align to four bytes 134 falign(stdout, stat.size); 135 fflush(stdout); 136 137 close(fd); 138 } 139 140 // trailer 141 fputs(stdout, "070701"); 142 fputh32(stdout, 0); 143 fputh32(stdout, 0); 144 fputh32(stdout, 0); 145 fputh32(stdout, 0); 146 fputh32(stdout, 0); 147 fputh32(stdout, 0); 148 fputh32(stdout, 0); 149 fputh32(stdout, 0); 150 fputh32(stdout, 0); 151 fputh32(stdout, 0); 152 fputh32(stdout, 0); 153 fputh32(stdout, 11); 154 fputh32(stdout, 0); 155 fputs(stdout, "TRAILER!!!"); 156 fputc(stdout, 0); 157 falign(stdout, 13); 158 159 fflush(stdout); 160 } 161 162 func fputh32(f: *file, x: int) { 163 var i: int; 164 165 if x > (-1 >> 32) { 166 fflush(f); 167 die("cpio: too large"); 168 } 169 170 i = 32; 171 loop { 172 if i == 0 { 173 break; 174 } 175 176 i = i - 4; 177 178 fputc(f, "0123456789abcdef"[(x >> i) & 15] as int); 179 } 180 } 181 182 func falign(f: *file, n: int) { 183 var len: int; 184 len = (4 - (n & 3)) & 3; 185 loop { 186 if len == 0 { 187 break; 188 } 189 190 fputc(f, 0); 191 192 len = len - 1; 193 } 194 }