Mercurial > hg > xemacs-beta
comparison nt/minitar.c @ 495:02f7a782086f
[xemacs-hg @ 2001-05-01 09:36:44 by ben]
* config.inc.samp (MAKEINFO): point at more standard c: not f:.
Fix more compiler warnings, clean up the style to conform
more to standard XEmacs.
author | ben |
---|---|
date | Tue, 01 May 2001 09:36:44 +0000 |
parents | 5aa1854ad537 |
children | f846c2ef930d |
comparison
equal
deleted
inserted
replaced
494:4137b1fb7b90 | 495:02f7a782086f |
---|---|
18 #include <io.h> | 18 #include <io.h> |
19 | 19 |
20 #include <zlib.h> | 20 #include <zlib.h> |
21 | 21 |
22 static int | 22 static int |
23 Usage(char *name) | 23 Usage (char *name) |
24 { | 24 { |
25 fprintf(stderr,"Usage: %s file.tar.gz [base-dir]\n",name); | 25 fprintf (stderr, "Usage: %s file.tar.gz [base-dir]\n", name); |
26 fprintf(stderr,"\tExtracts the contents compressed tar file to base-dir\n"); | 26 fprintf (stderr, "\tExtracts the contents compressed tar file to base-dir\n"); |
27 exit(-1); | 27 exit (-1); |
28 return 0; | |
28 } | 29 } |
29 | 30 |
30 | 31 |
31 #define BLOCKSIZE 512 | 32 #define BLOCKSIZE 512 |
32 #define MAXNAMELEN 1024 | 33 #define MAXNAMELEN 1024 |
33 | 34 |
34 static int | 35 static int |
35 octal(char *str) | 36 octal (char *str) |
36 { | 37 { |
37 int ret = -1; | 38 int ret = -1; |
38 sscanf(str,"%o",&ret); | 39 sscanf (str, "%o", &ret); |
39 return ret; | 40 return ret; |
40 } | 41 } |
41 | 42 |
42 /* this is like mkdir -p, except if there is no trailing slash, | 43 /* this is like mkdir -p, except if there is no trailing slash, |
43 the final component is assumed to be a file, rather than a | 44 the final component is assumed to be a file, rather than a |
44 path component, so it is not created as a directory */ | 45 path component, so it is not created as a directory */ |
45 | 46 |
46 static int | 47 static int |
47 makepath(char *path) | 48 makepath (char *path) |
48 { | 49 { |
49 char tmp[MAXNAMELEN]; | 50 char tmp[MAXNAMELEN]; |
50 char *cp; | 51 char *cp; |
51 | 52 |
52 for (cp=path; cp; cp = (char*)strchr(cp+1,'/')){ | 53 for (cp=path; cp; cp = (char*)strchr (cp+1, '/')) |
53 if (!*cp) | 54 { |
54 break; | 55 if (!*cp) |
55 if (*cp != '/') | 56 break; |
56 continue; | 57 if (*cp != '/') |
57 strncpy(tmp, path, cp-path); | 58 continue; |
58 tmp[cp-path] = '\0'; | 59 strncpy (tmp, path, cp-path); |
59 if (strlen(tmp) == 0) | 60 tmp[cp-path] = '\0'; |
60 continue; | 61 if (strlen (tmp) == 0) |
62 continue; | |
61 #ifdef WIN32_NATIVE | 63 #ifdef WIN32_NATIVE |
62 if (mkdir(tmp)){ | 64 if (mkdir (tmp)) |
63 #else | 65 #else |
64 if (mkdir(tmp,0777)){ | 66 if (mkdir (tmp, 0777)) |
65 #endif | 67 #endif |
66 if (errno == EEXIST) | 68 { |
67 continue; | 69 if (errno == EEXIST) |
68 else | 70 continue; |
69 return -1; | 71 else |
72 return -1; | |
73 } | |
70 } | 74 } |
71 } | |
72 return 0; | 75 return 0; |
73 } | 76 } |
74 | 77 |
75 | 78 |
76 | |
77 | 79 |
78 int | 80 int |
79 main(int argc, char **argv) | 81 main (int argc, char **argv) |
80 { | 82 { |
81 char fullname[MAXNAMELEN]; | 83 char fullname[MAXNAMELEN]; |
82 char *basedir = "."; | 84 char *basedir = "."; |
83 char *tarfile; | 85 char *tarfile; |
84 int size; | 86 int size; |
95 | 97 |
96 int in_block = 0; | 98 int in_block = 0; |
97 int directory = 0; | 99 int directory = 0; |
98 | 100 |
99 if (argc < 2 || argc > 3) | 101 if (argc < 2 || argc > 3) |
100 Usage(argv[0]); | 102 Usage (argv[0]); |
101 | 103 |
102 tarfile = argv[1]; | 104 tarfile = argv[1]; |
103 if (argc==3) | 105 if (argc==3) |
104 basedir = argv[2]; | 106 basedir = argv[2]; |
105 | 107 |
106 if (! (infile = gzopen(tarfile,"rb"))){ | 108 if (! (infile = gzopen (tarfile, "rb"))) |
107 fprintf(stderr,"Cannot open %s\n", tarfile); | 109 { |
108 exit(-2); | 110 fprintf (stderr, "Cannot open %s\n", tarfile); |
109 } | 111 exit (-2); |
112 } | |
110 | 113 |
111 while (1){ | 114 while (1) |
115 { | |
116 nread = gzread (infile, block, 512); | |
117 | |
118 if (!in_block && nread == 0) | |
119 break; | |
120 | |
121 if (nread != BLOCKSIZE) | |
122 { | |
123 fprintf (stderr, "Error: incomplete block read. Exiting.\n"); | |
124 exit (-2); | |
125 } | |
126 | |
127 if (!in_block) | |
128 { | |
129 if (block[0]=='\0') /* We're done */ | |
130 break; | |
131 | |
132 strncpy (magic, block+257, 6); | |
133 magic[6] = '\0'; | |
134 if (strcmp (magic, "ustar ")) | |
135 { | |
136 fprintf (stderr, | |
137 "Error: incorrect magic number in tar header. Exiting\n"); | |
138 } | |
139 | |
140 strncpy (name, block, 100); | |
141 name[100] = '\0'; | |
142 sprintf (fullname, "%s/%s", basedir, name); | |
143 printf ("%s\n", fullname); | |
144 type = block[156]; | |
145 | |
146 switch (type) | |
147 { | |
148 case '0': | |
149 case '\0': | |
150 directory = 0; | |
151 break; | |
152 case '5': | |
153 directory = 1; | |
154 break; | |
155 default: | |
156 fprintf (stderr, "Error: unknown type flag %c. Exiting.\n", type); | |
157 break; | |
158 } | |
159 | |
160 if (directory) | |
161 { | |
162 in_block = 0; | |
163 | |
164 /* makepath will ignore the final path component, so make sure | |
165 dirnames have a trailing slash */ | |
166 | |
167 if (fullname[strlen (fullname)-1] != '/') | |
168 strcat (fullname, "/"); | |
169 if (makepath (fullname)) | |
170 { | |
171 fprintf (stderr, "Error: cannot create directory %s. Exiting.\n", | |
172 fullname); | |
173 exit (-2); | |
174 } | |
175 continue; | |
176 } | |
177 else | |
178 { /*file */ | |
179 in_block = 1; | |
180 if (outfile) | |
181 { | |
182 if (fclose (outfile)) | |
183 { | |
184 fprintf (stderr, "Error: cannot close file %s. Exiting.\n", | |
185 fullname); | |
186 exit (-2); | |
187 } | |
188 outfile = (FILE*)0; | |
189 } | |
190 | |
191 if (!(outfile = fopen (fullname, "wb"))) | |
192 { | |
193 /*try creating the directory, maybe it's not there */ | |
194 if (makepath (fullname)) | |
195 { | |
196 fprintf (stderr, "Error: cannot create file %s. Exiting.\n", | |
197 fullname); | |
198 exit (-2); | |
199 } | |
200 /* now try again to open the file */ | |
201 if (!(outfile = fopen (fullname, "wb"))) | |
202 { | |
203 fprintf (stderr, "Error: cannot create file %s. Exiting.\n", | |
204 fullname); | |
205 exit (-2); | |
206 } | |
207 } | |
208 | |
209 strncpy (osize, block+124, 12); | |
210 osize[12] = '\0'; | |
211 size = octal (osize); | |
212 if (size<0) | |
213 { | |
214 fprintf (stderr, "Error: invalid size in tar header. Exiting.\n"); | |
215 exit (-2); | |
216 } | |
217 } | |
218 } else { /* write or continue writing file contents */ | |
219 nbytes = size>512? 512:size; | |
220 | |
221 nwritten = fwrite (block, 1, nbytes, outfile); | |
222 if (nwritten != nbytes) | |
223 { | |
224 fprintf (stderr, "Error: only wrote %d bytes to file %s. Exiting.\n", | |
225 nwritten, fullname); | |
226 } | |
227 size -= nbytes; | |
228 if (size==0) | |
229 in_block = 0; | |
230 } | |
231 } | |
232 return 0; | |
233 } | |
234 | |
235 | |
112 | 236 |
113 | |
114 nread = gzread(infile,block,512); | |
115 | |
116 if (!in_block && nread == 0) | |
117 break; | |
118 | |
119 if (nread != BLOCKSIZE){ | |
120 fprintf(stderr,"Error: incomplete block read. Exiting.\n"); | |
121 exit(-2); | |
122 } | |
123 | |
124 if (!in_block){ | |
125 if (block[0]=='\0') /* We're done */ | |
126 break; | |
127 | |
128 strncpy(magic,block+257,6); | |
129 magic[6] = '\0'; | |
130 if (strcmp(magic,"ustar ")){ | |
131 fprintf(stderr, | |
132 "Error: incorrect magic number in tar header. Exiting\n"); | |
133 } | |
134 | |
135 strncpy(name,block,100); | |
136 name[100] = '\0'; | |
137 sprintf(fullname,"%s/%s",basedir,name); | |
138 printf("%s\n",fullname); | |
139 type = block[156]; | |
140 | |
141 switch(type){ | |
142 case '0': | |
143 case '\0': | |
144 directory = 0; | |
145 break; | |
146 case '5': | |
147 directory = 1; | |
148 break; | |
149 default: | |
150 fprintf(stderr,"Error: unknown type flag %c. Exiting.\n",type); | |
151 break; | |
152 } | |
153 | |
154 if (directory){ | |
155 in_block = 0; | |
156 | |
157 /* makepath will ignore the final path component, so make sure | |
158 dirnames have a trailing slash */ | |
159 | |
160 if (fullname[strlen(fullname)-1] != '/') | |
161 strcat(fullname,"/"); | |
162 if (makepath(fullname)){ | |
163 fprintf(stderr, "Error: cannot create directory %s. Exiting.\n", | |
164 fullname); | |
165 exit(-2); | |
166 } | |
167 continue; | |
168 } else { /*file */ | |
169 in_block = 1; | |
170 if (outfile){ | |
171 if (fclose(outfile)){ | |
172 fprintf(stderr,"Error: cannot close file %s. Exiting.\n", | |
173 fullname); | |
174 exit(-2); | |
175 } | |
176 outfile = (FILE*)0; | |
177 } | |
178 | |
179 if ( !(outfile = fopen(fullname,"wb"))){ | |
180 /*try creating the directory, maybe it's not there */ | |
181 if (makepath(fullname)){ | |
182 fprintf(stderr,"Error: cannot create file %s. Exiting.\n", | |
183 fullname); | |
184 exit(-2); | |
185 } | |
186 /* now try again to open the file */ | |
187 if (!(outfile = fopen(fullname,"wb"))){ | |
188 fprintf(stderr,"Error: cannot create file %s. Exiting.\n", | |
189 fullname); | |
190 exit(-2); | |
191 } | |
192 } | |
193 | |
194 strncpy(osize,block+124,12); | |
195 osize[12] = '\0'; | |
196 size = octal(osize); | |
197 if (size<0){ | |
198 fprintf(stderr,"Error: invalid size in tar header. Exiting.\n"); | |
199 exit(-2); | |
200 } | |
201 } | |
202 } else { /* write or continue writing file contents */ | |
203 nbytes = size>512? 512:size; | |
204 | |
205 nwritten = fwrite(block, 1, nbytes, outfile); | |
206 if (nwritten != nbytes){ | |
207 fprintf(stderr, "Error: only wrote %d bytes to file %s. Exiting.\n", | |
208 nwritten, fullname); | |
209 } | |
210 size -= nbytes; | |
211 if (size==0) | |
212 in_block = 0; | |
213 } | |
214 } | |
215 exit (0); | |
216 } | |
217 | |
218 | |
219 | |
220 |