Mercurial > hg > xemacs-beta
view nt/minitar.c @ 4903:70089046adef
fix compile problems in intl-encap* under VS6
-------------------- ChangeLog entries follow: --------------------
lib-src/ChangeLog addition:
2010-01-30 Ben Wing <ben@xemacs.org>
* make-mswin-unicode.pl:
Make it possible to specify an overridden prototype in cases where
either Cygwin or Visual Studio has errors in their headers that
can be corrected by falling back to a less qualified type (typically
without const).
src/ChangeLog addition:
2010-01-30 Ben Wing <ben@xemacs.org>
* intl-auto-encap-win32.c:
* intl-auto-encap-win32.c (qxeExtractAssociatedIcon):
* intl-auto-encap-win32.c (qxeExtractIconEx):
* intl-auto-encap-win32.c (qxeCreateMDIWindow):
* intl-auto-encap-win32.c (qxeCreateWindowStation):
* intl-auto-encap-win32.c (qxeDdeCreateStringHandle):
* intl-auto-encap-win32.c (qxeAbortSystemShutdown):
* intl-auto-encap-win32.c (qxeRegConnectRegistry):
* intl-auto-encap-win32.c (qxeGetICMProfile):
* intl-auto-encap-win32.h:
Rebuild.
* intl-encap-win32.c:
* intl-encap-win32.c (qxeUpdateICMRegKey):
Delete manual definitions of functions with former errors in
Cygwin headers but no longer. Use "override" with some functions
where Cygwin or VS6 accidentally omits a const declaration or
includes an extra one. Use "no" on SendMessageTimeout, which
has an error in the VS6 prototype (you could manually fix this
with an ifdef to split the Cygwin vs. VS6 calls, if we ever
actually used this function).
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Sat, 30 Jan 2010 20:34:23 -0600 |
parents | b694dfd2f40e |
children |
line wrap: on
line source
/* Minitar: extract .tar.gz files on Win32 platforms. Uses zlib for decompression. This is very simple-minded, it ignores checksums, and any type of file that is not a plain file or a directory. Nonetheless it is useful. Author: Charles G. Waldman (cgw@pgt.com), Aug 4 1998 This file is placed in the public domain; you can do whatever you like with it. There is NO WARRANTY. If it breaks, you get to keep both pieces */ #ifdef HAVE_CONFIG_H # include <config.h> #endif #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <io.h> #ifdef WIN32_NATIVE # include <direct.h> /* For mkdir */ #endif #include <zlib.h> static void Usage (char *name) { fprintf (stderr, "Usage: %s file.tar.gz [base-dir]\n", name); fprintf (stderr, "\tExtracts the contents compressed tar file to base-dir\n"); exit (-1); } #define BLOCKSIZE 512 #define MAXNAMELEN 1024 static int octal (char *str) { int ret = -1; sscanf (str, "%o", &ret); return ret; } /* this is like mkdir -p, except if there is no trailing slash, the final component is assumed to be a file, rather than a path component, so it is not created as a directory */ static int makepath (char *path) { char tmp[MAXNAMELEN]; char *cp; for (cp=path; cp; cp = (char*)strchr (cp+1, '/')) { if (!*cp) break; if (*cp != '/') continue; strncpy (tmp, path, cp-path); tmp[cp-path] = '\0'; if (strlen (tmp) == 0) continue; #ifdef WIN32_NATIVE if (mkdir (tmp)) #else if (mkdir (tmp, 0777)) #endif { if (errno == EEXIST) continue; else return -1; } } return 0; } int main (int argc, char **argv) { char fullname[MAXNAMELEN]; char *basedir = "."; char *tarfile; int size; char osize[13]; char name[101]; char magic[7]; char type; gzFile *infile = (gzFile*)0; FILE *outfile = (FILE*)0; char block[BLOCKSIZE]; int nbytes, nread, nwritten; int in_block = 0; int directory = 0; if (argc < 2 || argc > 3) Usage (argv[0]); tarfile = argv[1]; if (argc==3) basedir = argv[2]; if (! (infile = gzopen (tarfile, "rb"))) { fprintf (stderr, "Cannot open %s\n", tarfile); exit (-2); } while (1) { nread = gzread (infile, block, 512); if (!in_block && nread == 0) break; if (nread != BLOCKSIZE) { fprintf (stderr, "Error: incomplete block read. Exiting.\n"); exit (-2); } if (!in_block) { if (block[0]=='\0') /* We're done */ break; strncpy (magic, block+257, 6); magic[6] = '\0'; if (strcmp (magic, "ustar ")) { fprintf (stderr, "Error: incorrect magic number in tar header. Exiting\n"); exit (-2); } strncpy (name, block, 100); name[100] = '\0'; sprintf (fullname, "%s/%s", basedir, name); printf ("%s\n", fullname); type = block[156]; switch (type) { case '0': case '\0': directory = 0; break; case '5': directory = 1; break; default: fprintf (stderr, "Error: unknown type flag %c. Exiting.\n", type); exit (-2); break; } if (directory) { in_block = 0; /* makepath will ignore the final path component, so make sure dirnames have a trailing slash */ if (fullname[strlen (fullname)-1] != '/') strcat (fullname, "/"); if (makepath (fullname)) { fprintf (stderr, "Error: cannot create directory %s. Exiting.\n", fullname); exit (-2); } continue; } else { /*file */ in_block = 1; if (outfile) { if (fclose (outfile)) { fprintf (stderr, "Error: cannot close file %s. Exiting.\n", fullname); exit (-2); } outfile = (FILE*)0; } if (!(outfile = fopen (fullname, "wb"))) { /*try creating the directory, maybe it's not there */ if (makepath (fullname)) { fprintf (stderr, "Error: cannot create file %s. Exiting.\n", fullname); exit (-2); } /* now try again to open the file */ if (!(outfile = fopen (fullname, "wb"))) { fprintf (stderr, "Error: cannot create file %s. Exiting.\n", fullname); exit (-2); } } strncpy (osize, block+124, 12); osize[12] = '\0'; size = octal (osize); if (size<0) { fprintf (stderr, "Error: invalid size in tar header. Exiting.\n"); exit (-2); } if (size==0) /* file of size 0 is done */ in_block = 0; } } else { /* write or continue writing file contents */ nbytes = size>512? 512:size; nwritten = fwrite (block, 1, nbytes, outfile); if (nwritten != nbytes) { fprintf (stderr, "Error: only wrote %d bytes to file %s. Exiting.\n", nwritten, fullname); exit (-2); } size -= nbytes; if (size==0) in_block = 0; } } return 0; }