Mercurial > hg > xemacs-beta
annotate nt/minitar.c @ 5146:88bd4f3ef8e4
make lrecord UID's have a separate UID space for each object, resurrect debug SOE code in extents.c
-------------------- ChangeLog entries follow: --------------------
src/ChangeLog addition:
2010-03-15 Ben Wing <ben@xemacs.org>
* alloc.c:
* alloc.c (c_readonly):
* alloc.c (deadbeef_memory):
* alloc.c (make_compiled_function):
* alloc.c (make_button_data):
* alloc.c (make_motion_data):
* alloc.c (make_process_data):
* alloc.c (make_timeout_data):
* alloc.c (make_magic_data):
* alloc.c (make_magic_eval_data):
* alloc.c (make_eval_data):
* alloc.c (make_misc_user_data):
* alloc.c (noseeum_make_marker):
* alloc.c (ADDITIONAL_FREE_string):
* alloc.c (common_init_alloc_early):
* alloc.c (init_alloc_once_early):
* bytecode.c (print_compiled_function):
* bytecode.c (mark_compiled_function):
* casetab.c:
* casetab.c (print_case_table):
* console.c:
* console.c (print_console):
* database.c (print_database):
* database.c (finalize_database):
* device-msw.c (sync_printer_with_devmode):
* device-msw.c (print_devmode):
* device-msw.c (finalize_devmode):
* device.c:
* device.c (print_device):
* elhash.c:
* elhash.c (print_hash_table):
* eval.c (print_multiple_value):
* eval.c (mark_multiple_value):
* events.c (deinitialize_event):
* events.c (print_event):
* events.c (event_equal):
* extents.c:
* extents.c (soe_dump):
* extents.c (soe_insert):
* extents.c (soe_delete):
* extents.c (soe_move):
* extents.c (extent_fragment_update):
* extents.c (print_extent_1):
* extents.c (print_extent):
* extents.c (vars_of_extents):
* frame.c:
* frame.c (print_frame):
* free-hook.c:
* free-hook.c (check_free):
* glyphs.c:
* glyphs.c (print_image_instance):
* glyphs.c (print_glyph):
* gui.c:
* gui.c (copy_gui_item):
* hash.c:
* hash.c (NULL_ENTRY):
* hash.c (KEYS_DIFFER_P):
* keymap.c (print_keymap):
* keymap.c (MARKED_SLOT):
* lisp.h:
* lrecord.h:
* lrecord.h (LISP_OBJECT_UID):
* lrecord.h (set_lheader_implementation):
* lrecord.h (struct old_lcrecord_header):
* lstream.c (print_lstream):
* lstream.c (finalize_lstream):
* marker.c (print_marker):
* marker.c (marker_equal):
* mc-alloc.c (visit_all_used_page_headers):
* mule-charset.c:
* mule-charset.c (print_charset):
* objects.c (print_color_instance):
* objects.c (print_font_instance):
* objects.c (finalize_font_instance):
* opaque.c (print_opaque):
* opaque.c (print_opaque_ptr):
* opaque.c (equal_opaque_ptr):
* print.c (internal_object_printer):
* print.c (enum printing_badness):
* rangetab.c (print_range_table):
* rangetab.c (range_table_equal):
* specifier.c (print_specifier):
* specifier.c (finalize_specifier):
* symbols.c:
* symbols.c (print_symbol_value_magic):
* tooltalk.c:
* tooltalk.c (print_tooltalk_message):
* tooltalk.c (print_tooltalk_pattern):
* window.c (print_window):
* window.c (debug_print_window):
(1) Make lrecord UID's have a separate UID space for each object.
Otherwise, with 20-bit UID's, we rapidly wrap around, especially
when common objects like conses and strings increment the UID value
for every object created. (Originally I tried making two UID spaces,
one for objects that always print readably and hence don't display
the UID, and one for other objects. But certain objects like markers
for which a UID is displayed are still generated rapidly enough that
UID overflow is a serious issue.) This also has the advantage of
making UID values smaller, hence easier to remember -- their main
purpose is to make it easier to keep track of different objects of
the same type when debugging code. Make sure we dump lrecord UID's
so that we don't have problems with pdumped and non-dumped objects
having the same UID.
(2) Display UID's consistently whenever an object (a) doesn't
consistently print readably (objects like cons and string, which
always print readably, can't display a UID), and (b) doesn't
otherwise have a unique property that makes objects of a
particular type distinguishable. (E.g. buffers didn't and still
don't print an ID, but the buffer name uniquely identifies the
buffer.) Some types, such as event, extent, compiled-function,
didn't always (or didn't ever) display an ID; others (such as
marker, extent, lstream, opaque, opaque-ptr, any object using
internal_object_printer()) used to display the actual machine
pointer instead.
(3) Rename NORMAL_LISP_OBJECT_UID to LISP_OBJECT_UID; make it work
over all Lisp objects and take a Lisp object, not a struct pointer.
(4) Some misc cleanups in alloc.c, elhash.c.
(5) Change code in events.c that "deinitializes" an event so that
it doesn't increment the event UID counter in the process. Also
use deadbeef_memory() to overwrite memory instead of doing the same
with custom code. In the process, make deadbeef_memory() in
alloc.c always available, and delete extraneous copy in mc-alloc.c.
Also capitalize all uses of 0xDEADBEEF. Similarly in elhash.c
call deadbeef_memory().
(6) Resurrect "debug SOE" code in extents.c. Make it conditional
on DEBUG_XEMACS and on a `debug-soe' variable, rather than on
SOE_DEBUG. Make it output to stderr, not stdout.
(7) Delete some custom print methods that were identical to
external_object_printer().
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Mon, 15 Mar 2010 16:35:38 -0500 |
parents | b694dfd2f40e |
children |
rev | line source |
---|---|
327 | 1 |
2 /* Minitar: extract .tar.gz files on Win32 platforms. | |
3 Uses zlib for decompression. | |
4 | |
5 This is very simple-minded, it ignores checksums, and any type of file | |
6 that is not a plain file or a directory. Nonetheless it is useful. | |
7 | |
8 Author: Charles G. Waldman (cgw@pgt.com), Aug 4 1998 | |
9 | |
10 This file is placed in the public domain; you can | |
11 do whatever you like with it. There is NO WARRANTY. | |
12 If it breaks, you get to keep both pieces */ | |
13 | |
14 | |
2951 | 15 #ifdef HAVE_CONFIG_H |
16 # include <config.h> | |
17 #endif | |
18 | |
327 | 19 #include <stdio.h> |
812 | 20 #include <stdlib.h> |
438 | 21 #include <errno.h> |
464 | 22 #include <string.h> |
23 #include <io.h> | |
812 | 24 #ifdef WIN32_NATIVE |
25 # include <direct.h> /* For mkdir */ | |
26 #endif | |
327 | 27 |
28 #include <zlib.h> | |
29 | |
1782 | 30 static void |
495 | 31 Usage (char *name) |
327 | 32 { |
495 | 33 fprintf (stderr, "Usage: %s file.tar.gz [base-dir]\n", name); |
34 fprintf (stderr, "\tExtracts the contents compressed tar file to base-dir\n"); | |
35 exit (-1); | |
327 | 36 } |
37 | |
38 | |
39 #define BLOCKSIZE 512 | |
40 #define MAXNAMELEN 1024 | |
41 | |
464 | 42 static int |
495 | 43 octal (char *str) |
327 | 44 { |
45 int ret = -1; | |
495 | 46 sscanf (str, "%o", &ret); |
327 | 47 return ret; |
48 } | |
49 | |
50 /* this is like mkdir -p, except if there is no trailing slash, | |
51 the final component is assumed to be a file, rather than a | |
52 path component, so it is not created as a directory */ | |
53 | |
464 | 54 static int |
495 | 55 makepath (char *path) |
327 | 56 { |
57 char tmp[MAXNAMELEN]; | |
58 char *cp; | |
59 | |
495 | 60 for (cp=path; cp; cp = (char*)strchr (cp+1, '/')) |
61 { | |
62 if (!*cp) | |
63 break; | |
64 if (*cp != '/') | |
65 continue; | |
66 strncpy (tmp, path, cp-path); | |
67 tmp[cp-path] = '\0'; | |
68 if (strlen (tmp) == 0) | |
69 continue; | |
464 | 70 #ifdef WIN32_NATIVE |
495 | 71 if (mkdir (tmp)) |
464 | 72 #else |
495 | 73 if (mkdir (tmp, 0777)) |
464 | 74 #endif |
495 | 75 { |
76 if (errno == EEXIST) | |
77 continue; | |
78 else | |
79 return -1; | |
80 } | |
327 | 81 } |
82 return 0; | |
83 } | |
84 | |
495 | 85 |
327 | 86 |
464 | 87 int |
495 | 88 main (int argc, char **argv) |
327 | 89 { |
90 char fullname[MAXNAMELEN]; | |
91 char *basedir = "."; | |
92 char *tarfile; | |
93 int size; | |
94 char osize[13]; | |
95 char name[101]; | |
96 char magic[7]; | |
97 char type; | |
98 | |
99 gzFile *infile = (gzFile*)0; | |
100 FILE *outfile = (FILE*)0; | |
101 | |
102 char block[BLOCKSIZE]; | |
103 int nbytes, nread, nwritten; | |
104 | |
105 int in_block = 0; | |
106 int directory = 0; | |
107 | |
108 if (argc < 2 || argc > 3) | |
495 | 109 Usage (argv[0]); |
327 | 110 |
111 tarfile = argv[1]; | |
112 if (argc==3) | |
113 basedir = argv[2]; | |
114 | |
495 | 115 if (! (infile = gzopen (tarfile, "rb"))) |
116 { | |
117 fprintf (stderr, "Cannot open %s\n", tarfile); | |
118 exit (-2); | |
119 } | |
327 | 120 |
495 | 121 while (1) |
122 { | |
123 nread = gzread (infile, block, 512); | |
327 | 124 |
495 | 125 if (!in_block && nread == 0) |
327 | 126 break; |
127 | |
495 | 128 if (nread != BLOCKSIZE) |
129 { | |
130 fprintf (stderr, "Error: incomplete block read. Exiting.\n"); | |
131 exit (-2); | |
327 | 132 } |
133 | |
495 | 134 if (!in_block) |
135 { | |
136 if (block[0]=='\0') /* We're done */ | |
137 break; | |
138 | |
139 strncpy (magic, block+257, 6); | |
140 magic[6] = '\0'; | |
141 if (strcmp (magic, "ustar ")) | |
142 { | |
143 fprintf (stderr, | |
144 "Error: incorrect magic number in tar header. Exiting\n"); | |
1529 | 145 exit (-2); |
495 | 146 } |
147 | |
148 strncpy (name, block, 100); | |
149 name[100] = '\0'; | |
150 sprintf (fullname, "%s/%s", basedir, name); | |
151 printf ("%s\n", fullname); | |
152 type = block[156]; | |
153 | |
154 switch (type) | |
155 { | |
156 case '0': | |
157 case '\0': | |
158 directory = 0; | |
159 break; | |
160 case '5': | |
161 directory = 1; | |
162 break; | |
163 default: | |
164 fprintf (stderr, "Error: unknown type flag %c. Exiting.\n", type); | |
1529 | 165 exit (-2); |
495 | 166 break; |
167 } | |
168 | |
169 if (directory) | |
170 { | |
171 in_block = 0; | |
172 | |
173 /* makepath will ignore the final path component, so make sure | |
174 dirnames have a trailing slash */ | |
327 | 175 |
495 | 176 if (fullname[strlen (fullname)-1] != '/') |
177 strcat (fullname, "/"); | |
178 if (makepath (fullname)) | |
179 { | |
180 fprintf (stderr, "Error: cannot create directory %s. Exiting.\n", | |
181 fullname); | |
182 exit (-2); | |
183 } | |
184 continue; | |
185 } | |
186 else | |
187 { /*file */ | |
188 in_block = 1; | |
189 if (outfile) | |
190 { | |
191 if (fclose (outfile)) | |
192 { | |
193 fprintf (stderr, "Error: cannot close file %s. Exiting.\n", | |
194 fullname); | |
195 exit (-2); | |
196 } | |
197 outfile = (FILE*)0; | |
198 } | |
199 | |
200 if (!(outfile = fopen (fullname, "wb"))) | |
201 { | |
202 /*try creating the directory, maybe it's not there */ | |
203 if (makepath (fullname)) | |
204 { | |
205 fprintf (stderr, "Error: cannot create file %s. Exiting.\n", | |
206 fullname); | |
207 exit (-2); | |
208 } | |
209 /* now try again to open the file */ | |
210 if (!(outfile = fopen (fullname, "wb"))) | |
211 { | |
212 fprintf (stderr, "Error: cannot create file %s. Exiting.\n", | |
213 fullname); | |
214 exit (-2); | |
215 } | |
216 } | |
217 | |
218 strncpy (osize, block+124, 12); | |
219 osize[12] = '\0'; | |
220 size = octal (osize); | |
221 if (size<0) | |
222 { | |
223 fprintf (stderr, "Error: invalid size in tar header. Exiting.\n"); | |
224 exit (-2); | |
225 } | |
1529 | 226 if (size==0) /* file of size 0 is done */ |
227 in_block = 0; | |
495 | 228 } |
1782 | 229 } |
230 else | |
231 { /* write or continue writing file contents */ | |
495 | 232 nbytes = size>512? 512:size; |
327 | 233 |
495 | 234 nwritten = fwrite (block, 1, nbytes, outfile); |
235 if (nwritten != nbytes) | |
236 { | |
237 fprintf (stderr, "Error: only wrote %d bytes to file %s. Exiting.\n", | |
238 nwritten, fullname); | |
1529 | 239 exit (-2); |
495 | 240 } |
241 size -= nbytes; | |
242 if (size==0) | |
243 in_block = 0; | |
244 } | |
327 | 245 } |
495 | 246 return 0; |
247 } | |
327 | 248 |
249 | |
250 |