0
0
mirror of https://github.com/python/cpython.git synced 2024-11-24 00:38:00 +01:00

Updates for THINK C 6.0. Moved the necessary UNIX emulation routines here.

This commit is contained in:
Guido van Rossum 1994-08-19 10:51:31 +00:00
parent e89bc75048
commit d4d7728440
16 changed files with 618 additions and 51 deletions

26
Mac/Compat/chdir.c Normal file
View File

@ -0,0 +1,26 @@
/* Chdir for the Macintosh.
Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
Pathnames must be Macintosh paths, with colons as separators. */
#include "macdefs.h"
/* Change current directory. */
int
chdir(path)
char *path;
{
WDPBRec pb;
char name[MAXPATH];
strncpy(name, path, sizeof name);
name[MAXPATH-1]= EOS;
pb.ioNamePtr= (StringPtr) c2pstr(name);
pb.ioVRefNum= 0;
pb.ioWDDirID= 0;
if (PBHSetVol(&pb, FALSE) != noErr) {
errno= ENOENT;
return -1;
}
return 0;
}

22
Mac/Compat/dirent.h Normal file
View File

@ -0,0 +1,22 @@
/*
* "Dir.h" for the Macintosh.
* Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
*/
#define MAXNAMLEN 31
#define MAXPATH 256
#define DIR struct _dir
struct _dir {
long dirid;
int nextfile;
};
struct dirent {
char d_name[MAXPATH];
};
extern DIR *opendir(char *);
extern struct dirent *readdir(DIR *);
extern void closedir(DIR *);

18
Mac/Compat/getbootvol.c Normal file
View File

@ -0,0 +1,18 @@
/* Return the name of the boot volume (not the current directory).
Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
*/
#include "macdefs.h"
char *
getbootvol()
{
short vrefnum;
static unsigned char name[32];
(void) GetVol(name, &vrefnum);
p2cstr(name);
/* Shouldn't fail; return ":" if it does */
strcat((char *)name, ":");
return (char *)name;
}

109
Mac/Compat/getwd.c Normal file
View File

@ -0,0 +1,109 @@
/* Get full pathname of current working directory. The pathname is
copied to the parameter array 'cwd', and a pointer to this array
is also returned as function result. If an error occurred, however,
the return value is NULL but 'cwd' is filled with an error message.
BUG: expect spectacular crashes when called from a directory whose
path would be over MAXPATH bytes long (files in such directories are
not reachable by full pathname).
Starting with the dir ID returned by PBHGetVol, we do successive
PBGetCatInfo's to get a component of the path until we reach the
root (recognized by a dir ID of 2). We move up along the path
using the dir ID of the parent directory returned by PBGetCatInfo.
Then we catenate the components found in reverse order with the volume
name (already gotten from PBHGetVol), with intervening and trailing
colons
The code works correctly on MFS disks (where it always returns the
volume name) by simply skipping the PBGetCatinfo calls in that case.
There is a 'bug' in PBGetCatInfo when called for an MFS disk (with
HFS running): it then seems to call PBHGetVInfo, which returns a
larger parameter block. But we won't run into this problem because
we never call PBGetCatInfo for the root (assuming that PBHGetVol
still sets the root ID in this case).
Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
*/
#ifdef MPW
#include <Strings.h>
#endif
#include "macdefs.h"
#define ROOTID 2 /* Root directory ID */
char *
getwd(cwd)
char *cwd;
{
/* Universal parameter block. */
union {
#ifdef THINK_C
HFileInfo f;
DirInfo d;
WDPBRec w;
#else /* MPW */
struct HFileInfo f;
struct DirInfo d;
struct WDPBRec w;
#endif
} pb;
char buf[MAXPATH]; /* Buffer to store the name components */
char *ecwd, *ebuf; /* Pointers to end of used part of cwd and buf */
int err; /* Error code of last I/O call */
/* First, get the default volume name and working directory ID. */
pb.w.ioNamePtr= (unsigned char *)cwd;
err= PBHGetVol(&pb.w, FALSE);
if (err != noErr) {
sprintf(cwd, "I/O error %d in PBHGetVol", err);
return NULL;
}
ecwd= strchr(p2cstr((unsigned char*)cwd), EOS);
ebuf= buf;
*ebuf = EOS;
/* Next, if at least we're running HFS, walk up the path. */
if (hfsrunning()) {
long dirid= pb.w.ioWDDirID;
pb.d.ioVRefNum= pb.w.ioWDVRefNum;
while (dirid != ROOTID) {
pb.d.ioNamePtr= (unsigned char *) ++ebuf;
pb.d.ioFDirIndex= -1;
pb.d.ioDrDirID= dirid;
err= PBGetCatInfo((CInfoPBPtr)&pb.d, FALSE);
if (err != noErr) {
sprintf(cwd, "I/O error %d in PBGetCatInfo", err);
return NULL;
}
dirid= pb.d.ioDrParID;
ebuf += strlen(p2cstr((unsigned char *)ebuf));
/* Should check for buf overflow */
}
}
/* Finally, reverse the list of components and append it to cwd.
Ebuf points at the EOS after last component,
and there is an EOS before the first component.
If there are no components, ebuf equals buf (but there
is still an EOS where it points).
Ecwd points at the EOS after the path built up so far,
initially the volume name.
We break out of the loop in the middle, thus
appending a colon at the end in all cases. */
for (;;) {
*ecwd++ = ':';
if (ebuf == buf)
break;
do { } while (*--ebuf != EOS); /* Find component start */
strcpy(ecwd, ebuf+1);
ecwd= strchr(ecwd, EOS);
}
*ecwd= EOS;
return cwd;
}

30
Mac/Compat/mkdir.c Normal file
View File

@ -0,0 +1,30 @@
/* Mkdir for the Macintosh.
Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
Pathnames must be Macintosh paths, with colons as separators. */
#include "macdefs.h"
/* Create a directory. */
int
mkdir(path, mode)
char *path;
int mode; /* Ignored */
{
HFileParam pb;
char name[MAXPATH];
if (!hfsrunning()) {
errno= ENODEV;
return -1;
}
strncpy(name, path, sizeof name);
pb.ioNamePtr= (StringPtr) c2pstr(name);
pb.ioVRefNum= 0;
pb.ioDirID= 0;
if (PBDirCreate((HParmBlkPtr)&pb, FALSE) != noErr) {
errno= EACCES;
return -1;
}
return 0;
}

104
Mac/Compat/opendir.c Normal file
View File

@ -0,0 +1,104 @@
/*
* Macintosh version of UNIX directory access package
* (opendir, readdir, closedir).
* Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
*/
#include "dirent.h"
#include "macdefs.h"
static DIR opened;
/*
* Open a directory. This means calling PBOpenWD.
* The value returned is always the address of opened, or NULL.
* (I have as yet no use for multiple open directories; this could
* be implemented by allocating memory dynamically.)
*/
DIR *
opendir(path)
char *path;
{
union {
WDPBRec d;
VolumeParam v;
} pb;
char ppath[MAXPATH];
short err;
if (opened.nextfile != 0) {
errno = EBUSY;
return NULL; /* A directory is already open. */
}
strncpy(ppath+1, path, ppath[0]= strlen(path));
pb.d.ioNamePtr= (unsigned char *)ppath;
pb.d.ioVRefNum= 0;
if (hfsrunning()) {
pb.d.ioWDProcID= 0;
pb.d.ioWDDirID= 0;
err= PBOpenWD((WDPBPtr)&pb, FALSE);
}
else {
pb.v.ioVolIndex= 0;
err= PBGetVInfo((ParmBlkPtr)&pb, FALSE);
}
if (err != noErr) {
errno = ENOENT;
return NULL;
}
opened.dirid= pb.d.ioVRefNum;
opened.nextfile= 1;
return &opened;
}
/*
* Close a directory.
*/
void
closedir(dirp)
DIR *dirp;
{
if (hfsrunning()) {
WDPBRec pb;
pb.ioVRefNum= dirp->dirid;
(void) PBCloseWD(&pb, FALSE);
}
dirp->dirid= 0;
dirp->nextfile= 0;
}
/*
* Read the next directory entry.
*/
struct dirent *
readdir(dp)
DIR *dp;
{
union {
DirInfo d;
FileParam f;
HFileInfo hf;
} pb;
short err;
static struct dirent dir;
dir.d_name[0]= 0;
pb.d.ioNamePtr= (unsigned char *)dir.d_name;
pb.d.ioVRefNum= dp->dirid;
pb.d.ioFDirIndex= dp->nextfile++;
pb.d.ioDrDirID= 0;
if (hfsrunning())
err= PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
else
err= PBGetFInfo((ParmBlkPtr)&pb, FALSE);
if (err != noErr) {
errno = EIO;
return NULL;
}
(void) p2cstr((unsigned char *)dir.d_name);
return &dir;
}

22
Mac/Compat/rmdir.c Normal file
View File

@ -0,0 +1,22 @@
/* Rmdir for the Macintosh.
Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
Pathnames must be Macintosh paths, with colons as separators. */
#include "macdefs.h"
int
rmdir(path)
char *path;
{
IOParam pb;
char name[MAXPATH];
strncpy(name, path, sizeof name);
pb.ioNamePtr= (StringPtr) c2pstr(name);
pb.ioVRefNum= 0;
if (PBDelete((ParmBlkPtr)&pb, FALSE) != noErr) {
errno= EACCES;
return -1;
}
return 0;
}

17
Mac/Compat/sync.c Normal file
View File

@ -0,0 +1,17 @@
/* The equivalent of the Unix 'sync' system call: FlushVol.
Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
For now, we only flush the default volume
(since that's the only volume written to by MacB). */
#include "macdefs.h"
int
sync()
{
if (FlushVol((StringPtr)0, 0) == noErr)
return 0;
else {
errno= ENODEV;
return -1;
}
}

View File

@ -1,10 +1,8 @@
/* config.h.in. Generated automatically from configure.in by autoheader. */
/* config.h for Macintosh THINK C 6.0. */
/* Define if on Macintosh, compiling with any C compiler. */
/* Define if on Macintosh (THINK C or MPW */
#define macintosh
#define HAVE_STDARG_PROTOTYPES 1
/* Define if on AIX 3.
System headers sometimes define this.
We just want to avoid a redefinition error message. */
@ -12,6 +10,9 @@
#undef _ALL_SOURCE
#endif
/* Define if type char is unsigned and you are not using gcc. */
#undef __CHAR_UNSIGNED__
/* Define to empty if the keyword does not work. */
#undef const
@ -85,25 +86,69 @@
(as it does on SGI IRIX 4.x) */
#undef BAD_EXEC_PROTOTYPES
/* Define if your compiler botches static forward declarations
(as it does on SCI ODT 3.0) */
#undef BAD_STATIC_FORWARD
/* Define to `long' if <time.h> doesn't define. */
#undef clock_t
/* Define if getpgrp() must be called as getpgrp(0)
and (consequently) setpgrp() as setpgrp(0, 0). */
#undef GETPGRP_HAVE_ARGS
#undef GETPGRP_HAVE_ARG
/* Define this if your time.h defines altzone */
#undef HAVE_ALTZONE
/* Define if your compiler supports function prototypes */
#define HAVE_PROTOTYPES
/* Define if your compiler supports variable length function prototypes
(e.g. void fprintf(FILE *, char *, ...);) *and* <stdarg.h> */
#define HAVE_STDARG_PROTOTYPES
/* Define if you have POSIX threads */
#undef _POSIX_THREADS
/* Define to empty if the keyword does not work. */
#undef signed
/* Define if you can safely include both <sys/select.h> and <sys/time.h>
(which you can't on SCO ODT 3.0). */
#undef SYS_SELECT_WITH_SYS_TIME
/* Define if you want to use SGI (IRIX 4) dynamic linking.
This requires the "dl" library by Jack Jansen,
ftp://ftp.cwi.nl/pub/dynload/dl-1.6.tar.Z.
Don't bother on IRIX 5, it already has dynamic linking using SunOS
style shared libraries */
#undef WITH_SGI_DL
/* Define if you want to emulate SGI (IRIX 4) dynamic linking.
This is rumoured to work on VAX (Ultrix), Sun3 (SunOS 3.4),
Sequent Symmetry (Dynix), and Atari ST.
This requires the "dl-dld" library,
ftp://ftp.cwi.nl/pub/dynload/dl-dld-1.1.tar.Z,
as well as the "GNU dld" library,
ftp://ftp.cwi.nl/pub/dynload/dld-3.2.3.tar.Z.
Don't bother on SunOS 4 or 5, they already have dynamic linking using
shared libraries */
#undef WITH_DL_DLD
/* Define if you want to compile in rudimentary thread support */
#undef WITH_THREAD
/* Define if you want to use the GNU readline library */
#undef WITH_READLINE
/* Define if you have chown. */
#undef HAVE_CHOWN
/* Define if you have clock. */
#define HAVE_CLOCK 1
#define HAVE_CLOCK
/* Define if you have dlopen. */
#undef HAVE_DLOPEN
/* Define if you have ftime. */
#undef HAVE_FTIME
@ -114,17 +159,23 @@
/* Define if you have getpgrp. */
#undef HAVE_GETPGRP
/* Define if you have getpid. */
#undef HAVE_GETPID
/* Define if you have gettimeofday. */
#undef HAVE_GETTIMEOFDAY
/* Define if you have getwd. */
#define HAVE_GETWD 1
/* Define if you have link. */
#undef HAVE_LINK
/* Define if you have lstat. */
#undef HAVE_LSTAT
/* Define if you have readline. */
#undef HAVE_READLINE
/* Define if you have nice. */
#undef HAVE_NICE
/* Define if you have readlink. */
#undef HAVE_READLINK
@ -132,6 +183,9 @@
/* Define if you have select. */
#undef HAVE_SELECT
/* Define if you have setgid. */
#undef HAVE_SETGID
/* Define if you have setpgid. */
#undef HAVE_SETPGID
@ -141,8 +195,11 @@
/* Define if you have setsid. */
#undef HAVE_SETSID
/* Define if you have setuid. */
#undef HAVE_SETUID
/* Define if you have setvbuf. */
#define HAVE_SETVBUF 1
#define HAVE_SETVBUF
/* Define if you have siginterrupt. */
#undef HAVE_SIGINTERRUPT
@ -168,14 +225,17 @@
/* Define if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
#define HAVE_SIGNAL_H
/* Define if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
#define HAVE_STDARG_H
/* Define if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
#define HAVE_STDLIB_H
/* Define if you have the <sys/audioio.h> header file. */
#undef HAVE_SYS_AUDIOIO_H
@ -186,6 +246,9 @@
/* Define if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define if you have the <sys/times.h> header file. */
#undef HAVE_SYS_TIMES_H
@ -207,12 +270,18 @@
/* Define if you have the dl library (-ldl). */
#undef HAVE_LIBDL
/* Define if you have the inet library (-linet). */
#undef HAVE_LIBINET
/* Define if you have the mpc library (-lmpc). */
#undef HAVE_LIBMPC
/* Define if you have the nsl library (-lnsl). */
#undef HAVE_LIBNSL
/* Define if you have the pthreads library (-lpthreads). */
#undef HAVE_LIBPTHREADS
/* Define if you have the seq library (-lseq). */
#undef HAVE_LIBSEQ
@ -222,5 +291,11 @@
/* Define if you have the sun library (-lsun). */
#undef HAVE_LIBSUN
/* Define if you have the termcap library (-ltermcap). */
#undef HAVE_LIBTERMCAP
/* Define if you have the termlib library (-ltermlib). */
#undef HAVE_LIBTERMLIB
/* Define if you have the thread library (-lthread). */
#undef HAVE_LIBTHREAD

38
Mac/Include/macdefs.h Normal file
View File

@ -0,0 +1,38 @@
/* Useful #includes and #defines for programming a set of Unix
look-alike file system access functions on the Macintosh.
Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
*/
#include <Types.h>
#include <Files.h>
#include <OSUtils.h>
#ifndef MPW
#include <pascal.h>
#endif
#include <errno.h>
#include <string.h>
/* Difference in origin between Mac and Unix clocks: */
#define TIMEDIFF ((unsigned long) \
(((1970-1904)*365 + (1970-1904)/4) * 24 * 3600))
/* Macro to find out whether we can do HFS-only calls: */
#define FSFCBLen (* (short *) 0x3f6)
#define hfsrunning() (FSFCBLen > 0)
/* Universal constants: */
#define MAXPATH 256
#define TRUE 1
#define FALSE 0
#ifndef NULL
#define NULL 0
#endif
#define EOS '\0'
#define SEP ':'
#if 0 // doesn't work
/* Call Macsbug: */
pascal void Debugger() extern 0xA9FF;
#endif

View File

@ -1,5 +1,6 @@
/***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
/* Generated automatically from ../../Modules/config.c.in by makesetup. */
/* -*- C -*- ***********************************************
Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands.
All Rights Reserved
@ -34,6 +35,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "myproto.h"
#include "mymalloc.h"
#include "osdefs.h"
#include "intrcheck.h"
#ifndef NO_MAIN
@ -52,17 +54,9 @@ main(argc, argv)
char **argv;
{
#ifdef macintosh
#ifndef MPW /* XXX RJW undefined in MPW */
wargs(&argc, &argv);
/* Macs always support stdwin */
// wargs(&argc, &argv);
#endif
#ifndef MPW_3 /* XXX RJW doesn't seem to work with MPW C 3.0 */
extern int std_open_hook();
set_open_hook (std_open_hook);
#endif
#endif
argv0 = argv[0];
realmain(argc, argv);
}
@ -76,6 +70,40 @@ getprogramname()
#endif
/* Python version information */
#include "patchlevel.h"
/* Return the version string. This is constructed from the official
version number (from patchlevel.h), and the current date (if known
to the compiler, else a manually inserted date). */
#define VERSION "%s (%s)"
#ifdef __DATE__
#define DATE __DATE__
#else
#define DATE "Aug 17 1994"
#endif
char *
getversion()
{
static char version[80];
sprintf(version, VERSION, PATCHLEVEL, DATE);
return version;
}
/* Return the copyright string. This is updated manually. */
char *
getcopyright()
{
return "Copyright 1991-1994 Stichting Mathematisch Centrum, Amsterdam";
}
/* Return the initial python search path. This is called once from
initsys() to initialize sys.path.
The environment variable PYTHONPATH is fetched and the default path
@ -85,14 +113,14 @@ getprogramname()
#ifndef PYTHONPATH
#ifdef macintosh
#define PYTHONPATH ": :Lib :Lib:stdwin :Demo"
#define PYTHONPATH ": :Lib :Lib:stdwin :Lib:test :Lib:mac"
#endif /* macintosh */
#endif /* !PYTHONPATH */
#ifndef PYTHONPATH
#ifdef MSDOS
#if defined(MSDOS) || defined(NT)
#define PYTHONPATH ".;..\\lib;\\python\\lib"
#endif /* MSDOS */
#endif /* MSDOS || NT */
#endif /* !PYTHONPATH */
#ifndef PYTHONPATH
@ -146,6 +174,7 @@ extern void initfcntl();
extern void initnis();
extern void initpwd();
extern void initgrp();
extern void initcrypt();
extern void initselect();
extern void initsocket();
extern void initaudioop();
@ -166,6 +195,10 @@ extern void initsv();
extern void initfl();
extern void initthread();
extern void inittiming();
extern void initsignal();
extern void initnew();
extern void initdl();
extern void initsyslog();
/* -- ADDMODULE MARKER 1 -- */
@ -187,9 +220,11 @@ struct {
{"audioop", initaudioop},
{"imageop", initimageop},
{"rgbimg", initrgbimg},
{"stdwin", initstdwin},
// {"stdwin", initstdwin},
{"md5", initmd5},
{"rotor", initrotor},
// {"signal", initsignal},
{"new", initnew},
/* -- ADDMODULE MARKER 2 -- */

View File

@ -36,9 +36,9 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <fcntl.h>
#include ":::unixemu:macdefs.h"
#include ":::unixemu:dir.h"
#include ":::unixemu:stat.h"
#include "macdefs.h"
#include "dirent.h"
#include "stat.h"
#ifndef MAXPATHLEN
#define MAXPATHLEN 1024
@ -46,14 +46,13 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* Prototypes for Unix simulation on Mac */
int access PROTO((const char *path, int mode));
int chdir PROTO((const char *path));
char *getbootvol PROTO((void));
char *getwd PROTO((char *));
int mkdir PROTO((const char *path, int mode));
DIR * opendir PROTO((char *));
void closedir PROTO((DIR *));
struct direct * readdir PROTO((DIR *));
struct dirent * readdir PROTO((DIR *));
int rmdir PROTO((const char *path));
int stat PROTO((const char *path, struct stat *buf));
int sync PROTO((void));
@ -128,14 +127,6 @@ mac_strint(args, func)
return None;
}
static object *
mac_access(self, args)
object *self;
object *args;
{
return mac_strint(args, access);
}
static object *
mac_chdir(self, args)
object *self;
@ -243,7 +234,7 @@ mac_listdir(self, args)
char *name;
object *d, *v;
DIR *dirp;
struct direct *ep;
struct dirent *ep;
if (!getargs(args, "s", &name))
return NULL;
BGN_SAVE
@ -376,11 +367,17 @@ mac_stat(self, args)
END_SAVE
if (res != 0)
return mac_error();
return mkvalue("(llll)",
return mkvalue("(llllllllll)",
(long)st.st_mode,
0L /* st_ino */,
(long)st.st_dev,
(long)st.st_nlink,
(long)st.st_uid,
(long)st.st_gid,
(long)st.st_size,
(long)st.st_rsize,
(long)st.st_mtime);
(long)st.st_atime,
(long)st.st_mtime,
(long)st.st_ctime);
}
static object *
@ -426,7 +423,6 @@ mac_write(self, args)
}
static struct methodlist mac_methods[] = {
{"access_", mac_access}, /* "access" is a Python reserved word */
{"chdir", mac_chdir},
{"close", mac_close},
#ifdef MPW

View File

@ -1,4 +1,4 @@
#include "::unixemu:stat.h"
#include <stat.h>
/* Interfaced used by import.c */

View File

@ -10,12 +10,12 @@
guesstabsize(path)
char *path;
{
char s[256];
Str255 s;
int refnum;
Handle h;
int tabsize = 0;
s[0] = strlen(path);
strncpy(s+1, path, s[0]);
memcpy(s+1, path, s[0]);
refnum = OpenResFile(s);
/* printf("%s --> refnum=%d\n", path, refnum); */
if (refnum == -1)

View File

@ -1,5 +1,9 @@
#! /usr/local/bin/python
# Replace \r by \n -- useful after transferring files from the Mac...
# Run this on UNIX.
# Usage: crlf.py file ...
import sys
import os
import string
@ -7,8 +11,8 @@ import string
def main():
args = sys.argv[1:]
if not args:
print 'no files'
sys.exit(1)
print 'usage:', sys.argv[0], 'file ...'
sys.exit(2)
for file in args:
print file, '...'
data = open(file, 'r').read()

71
Mac/scripts/unshar.py Normal file
View File

@ -0,0 +1,71 @@
# Extract files from a SHAR archive.
# Run this on the Mac.
# Usage:
# >>> import unshar
# >>> f = open('SHAR')
# >>> unshar.unshar(f)
import string
def unshar(fp, verbose=0, overwrite=0):
ofp = None
file = None
while 1:
line = fp.readline()
if verbose > 3: print 'Got:', `line`
if line[:1] == 'X':
# Most common case first
if ofp: ofp.write(line[1:])
continue
if not line:
if verbose: print 'EOF'
if ofp:
print 'Unterminated file -- closing'
ofp.close()
ofp = None
break
if line[0] == '#':
if verbose: print line,
continue
if line[:14] == 'sed "s/^X//" >':
if verbose: print "!!!", `line`
i = string.find(line, "'")
j = string.find(line, "'", i+1)
if i >= 0 and j > i:
file = line[i+1:j]
if '/' in file:
words = string.splitfields(file, '/')
for funny in '', '.':
while funny in words: words.remove(funny)
for i in range(len(words)):
if words[i] == '..': words[i] = ''
words.insert(0, '')
file = string.joinfields(words, ':')
try:
ofp = open(file, 'r')
ofp.close()
ofp = None
over = 1
except IOError:
over = 0
if over and not overwrite:
print 'Skipping', file, '(already exists) ...'
continue
ofp = open(file, 'w')
if over:
print 'Overwriting', file, '...'
else:
print 'Writing', file, '...'
continue
if line == 'END_OF_FILE\n':
if not file:
print 'Unexpected END_OF_FILE marker'
if ofp:
print 'done'
ofp.close()
ofp = None
else:
print 'done skipping'
file = None
continue
if verbose: print "...", `line`