|
|
1.1 root 1: #include <libc.h>
2: #include <fio.h>
3: #include "sym.h"
4: #include "worm.h"
5: #include <sys/types.h>
6: #include <sys/stat.h>
7:
8: char *prefix = "";
9: int dflag = 0;
10: int quiet = 0;
11: int mflag = 0;
12:
13: main(argc, argv)
14: char **argv;
15: {
16: Superblock s;
17: char *e;
18: int c;
19: char *dev = "/dev/worm0";
20: extern char *optarg;
21: extern int optind;
22:
23: while((c = getopt(argc, argv, "dmf:p:s")) != -1)
24: switch(c)
25: {
26: case 'd': dflag = 1; break;
27: case 'f': dev = optarg; break;
28: case 'm': mflag = 1; break;
29: case 'p': prefix = optarg; break;
30: case 's': quiet = 1; break;
31: case '?': usage();
32: }
33: if(optind >= argc)
34: usage();
35: dev = mapdev(dev);
36: if((s.fd = open(dev, 0)) < 0){
37: perror(dev);
38: exit(1);
39: }
40: if(e = openinode(&s, DO_INODE|SPIN_DOWN)){
41: fprint(2, "%s: %s\n", dev, e);
42: exit(1);
43: }
44: if(strcmp(s.vol_id, argv[optind])){
45: fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind], s.vol_id);
46: exit(1);
47: }
48: optind++;
49: c = 0;
50: if(optind >= argc){
51: while(e = Frdline(0))
52: if(pr(&s, e))
53: c = 1;
54: } else {
55: while(optind < argc)
56: if(pr(&s, argv[optind++]))
57: c = 1;
58: }
59: exit(c);
60: }
61:
62: usage()
63: {
64: fprint(2, "Usage: worm read [-fdevice] [-pprefix] [-dm] vol_id [files ...]\n");
65: exit(1);
66: }
67:
68: pr(s, name)
69: Superblock *s;
70: char *name;
71: {
72: register Inode *i;
73: char b[63*1024L];
74: register long len, n;
75: long nb;
76: int fd;
77: char buf[4096];
78:
79: if((i = inodeof(name)) == 0){
80: fprint(2, "%s not found\n", name);
81: return(1);
82: }
83: sprint(buf, "%s%s", prefix, name);
84: name = buf;
85: if((fd = create(name, i->mode, i->uid, i->gid, i->ctime)) < 0){
86: if(dflag){
87: createdirs(name);
88: fd = create(name, i->mode, i->uid, i->gid, i->ctime);
89: }
90: if(fd < 0){
91: perror(name);
92: if(errno == ENOSPC)
93: exit(1);
94: return(1);
95: }
96: }
97: if(fd == 0) /* a directory */
98: return(0);
99: nb = sizeof b / s->blocksize;
100: Seek(s, i->block);
101: for(n = i->nbytes, len = nb*s->blocksize; n > 0;){
102: if(len > n){
103: len = n;
104: nb = (len+s->blocksize-1)/s->blocksize;
105: }
106: if(Read(s, b, nb)){
107: fprint(2, "while writing %s: ", name);
108: perror("read");
109: exit(1);
110: }
111: if(write(fd, b, (int)len) != len){
112: fprint(2, "while writing %s: ", name);
113: perror("write");
114: exit(1);
115: }
116: n -= len;
117: }
118: close(fd);
119: if(mflag){
120: time_t tp[2];
121:
122: tp[0] = tp[1] = i->ctime;
123: utime(name, tp);
124: }
125: return(0);
126: }
127:
128: createdirs(s)
129: char *s;
130: {
131: char *ls, *ss;
132:
133: for(ls = s; *ls == '/'; ls++)
134: ;
135: for(; *ls && (ss = strchr(ls, '/')); ls = ss+1){
136: *ss = 0;
137: if(access(s, 0) < 0){
138: if(mkdir(s, 0777) < 0){
139: perror(s);
140: return;
141: } else if(!quiet)
142: fprint(2, "created %s\n", s);
143: }
144: *ss = '/';
145: }
146: }
147:
148: create(name, mode, uid, gid, t)
149: char *name;
150: time_t t;
151: {
152: time_t tp[2];
153:
154: tp[0] = tp[1] = t;
155: if((mode&S_IFMT) == S_IFDIR){
156: if(access(name, 0) >= 0){
157: if(chmod(name, mode) < 0){
158: perror(name);
159: return(-1);
160: }
161: } else {
162: if(mkdir(name, mode) < 0){
163: perror(name);
164: return(-1);
165: }
166: }
167: chown(name, uid, gid);
168: utime(name, tp);
169: return(0);
170: } else {
171: int fd;
172:
173: if((fd = creat(name, mode)) >= 0){
174: chown(name, uid, gid);
175: utime(name, tp);
176: }
177: return(fd);
178: }
179: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.