charles@tasis.utas.oz (Charles Lakos) (07/05/89)
Actually there are 2 questions: 1. Has someone used the sublaunching as described in Tech Note 126 in LSC? If so, how is the inline function Launchit coded, and is it necessary to type up the assembly code referred to in Tech Note 88 or is it available elsewhere? 2. I have written a DRVR which is given a time slice periodically (by setting the dNeedTime flag). At certain times it decides to perform an action. My question is whether it is possible to determine the "stability of the environment"? What I mean by this might be best explained by examples. The DRVR presumably can sound the bell any time it gets a look in. But it presumably ought to be more reticent putting up a dialog window - you might be in the middle of printing or other comms. And it should be even more reticent in sublaunching another application! How do I know when is a good time to do these things? Any suggestions welcome. Charles Lakos. ACSnet: charles@tasis.utas.oz ARPA: charles%tasis.utas.oz@uunet.uu.net UUCP: {enea,hplabs,mcvax,uunet,ukc}!munnari!tasis.utas.oz!charles Snail: Computer Science Dept., University of Tasmania, GPO Box 252C, Hobart, TAS, 7001, Australia. Charles Lakos. ACSnet: charles@tasis.utas.oz ARPA: charles%tasis.utas.oz@uunet.uu.net UUCP: {enea,hplabs,mcvax,uunet,ukc}!munnari!tasis.utas.oz!charles Snail: Computer Science Dept., University of Tasmania, GPO Box 252C, Hobart, TAS, 7001, Australia.
drew@lethe.UUCP (Drew Sullivan) (07/08/89)
In article <943@diemen.cc.utas.oz> charles@tasis.utas.oz (Charles Lakos) writes: >1. Has someone used the sublaunching as described in Tech Note 126 in LSC? > If so, how is the inline function Launchit coded, and is it necessary > to type up the assembly code referred to in Tech Note 88 or is it > available elsewhere? #!/bin/sh # Unix funcions for the Macintosh # All are released for any use. # If you have routines, please send them to me. # Also if you find bugs I want to know!. # echo "x - access.c" sed "s/^X//" > access.c <<'!-E-o-F' X/* X * access -- macintosh access funcion X */ X#include <sys/types.h> X#include <string.h> X#include <errno.h> X X#include "getarg.h" X Xextern int errno; X X#define NULL 0 X Xint access(fname, mode) char *fname; int mode; { X CInfoPBRec pb; X OSErr rc; X Str255 name; X X if (fname == NULL || *fname == '\0') { X errno = EINVAL; X return -1; X } X X /* get info the name just passed to us */ X repmem((char *)&pb,"",1,sizeof(pb)); X pb.dirInfo.ioDrDirID = av_curdir(fname); X pb.dirInfo.ioNamePtr = (StringPtr)CtoPstr(strcpy((char *)name, fname)); X X if (mac_err(PBGetCatInfo(&pb, FALSE), "PBGetCatInfo")) { X return -1; X } X /* BUG should check for real read/write, access (Type=='APPL') perms */ X return 0; X} X !-E-o-F echo "x - chdir.c" sed "s/^X//" > chdir.c <<'!-E-o-F' X#include <stdio.h> X#include <string.h> X X#include "getarg.h" X Xint chdir(name) char *name; { X char work[256]; X WDPBRec wd; X ioParam pb; X OSErr rc; X X repmem((char *)&wd,"",1,sizeof(wd)); X X if (mac_err(PBHGetVol(&wd, false), "PBHGetVol")) { X return -1; X } X X wd.ioCompletion = NULL; X wd.ioNamePtr = (StringPtr)CtoPstr(strcpy(work, name)); X X if (mac_err(PBHSetVol(&wd, FALSE), "PBOpenWD")) { X return -1; X } X#if DEBUG X printf("wd.ioVRefNum = %x, wd.ioWDDirID = %lx\n", wd.ioVRefNum, wd.ioWDDirID); X#endif X if (mac_err(PBHGetVol(&wd, false), "PBHGetVol")) { X return -1; X } X CurDirStore = wd.ioWDDirID; X return 0; X} !-E-o-F echo "x - curdir.c" sed "s/^X//" > curdir.c <<'!-E-o-F' X#include "portlink.h" X#include "stdlib.p" X#include "getarg.h" X#include <HFS.h> X#include <errno.h> X X#define EOS '\0' X X/* X * av_curdir - is used to check and map to in the current directory X * for relative file names; X */ X Xlong av_curdir(file) char *file; { X OSErr rc; X WDPBRec wd; X X if (strchr(file, ':') == NULL || *file == ':') { X /* relative to the current working directory */ X repmem((char *)&wd,"",1,sizeof(wd)); X X if (mac_err(PBHGetVol(&wd, false), "PBHGetVol")) { X return -1; X } X return wd.ioWDDirID; X } X /* absolue path, no current working directory */ X return 0L; X} X X#if DEBUG X#define maperr(n,p) errno = n; msg = p X#else X#define maperr(n,p) errno = n X#endif X Xint _mac_error = 0; Xchar * _mac_errid = ""; X Xint mac_err(rc, rn) int rc; char *rn; { X char *msg; X X if (rc == noErr) { X return 0; X } X _mac_error = rc; X _mac_errid = rn; X X switch (rc) { X case bdNamErr: maperr(EINVAL, "Bad file name"); break; X case dirNFErr: maperr(ENOTDIR, "Directory not found"); break; X case extFSErr: maperr(EXDEV, "External file system"); break; X case fnfErr: maperr(ENOENT, "File not found"); break; X case ioErr: maperr(EIO, "I/O Error"); break; X case nsvErr: maperr(ENOENT, "No such volume"); break; X case paramErr: maperr(ENOENT, "No default volume"); break; X default: maperr(EINVAL, "<unknown error>"); break; X } X#if DEBUG X fprintf(stderr, "%s: %d (%s) -> %d", rn, rc, msg, errno); X perror(""); X#endif X return rc; X} X X !-E-o-F echo "x - filelength.c" sed "s/^X//" > filelength.c <<'!-E-o-F' X/* X * filelenth -- return size of a unix file-descriptor X */ X#include <stdio.h> X#include <io.h> X Xlong filelength(fd) int fd; { X long size; X int rc; X X if (mac_err(GetEOF(_file[fd].refnum, &size), "GetEOF")) { X return -1L; X } X return size; /* length of the data fork */ X} !-E-o-F echo "x - getarg.c" sed "s/^X//" > getarg.c <<'!-E-o-F' X/* X * getarg.c -- simulate command line processing X */ X#include "portlink.h" X#include "stdio.p" X#include <ctype.h> X#include "string.p" X#include "getarg.h" X#include "stdlib.p" X X#include "stdext.h" X X#define MAXARGS 100 X Xstatic void reopen(char *, FILE *, char *mode); X X/* X * av_argcnt -- return the number of elements in an argv list (returns argc) X */ Xint av_argcnt(argv) char **argv; { X int argc = 0; X X while (*argv++) ++argc; X return argc; X} X X/* X * av_getargs -- Maps the mac command vector to C's argv vector X * it does I/O redirection X */ Xchar **av_getargs() { X static char * argbuf[MAXARGS]; X char **args = argbuf; X char *arg, buf[BUFSIZ]; X int i, t; X struct arg_hdr *ph; X AppFile *ap; X X *args++ = strdup(strpcpy(buf, CurApName)); X X ph = *(struct arg_hdr **)AppParmHandle; X ap = &ph->lst; X for (i=0; i < ph->count; ++i) { X arg = strpcpy(buf, (char *)ap->fName); X X if ((t = ap->fName[0]+1) & 1) ++t; X ap = (AppFile *)(ap->fName + t); X X if (*arg == '<' ) { X reopen(++arg, stdin, "r"); X continue; X } X if (*arg == '>') { X if (*++arg == '>') { X reopen(++arg, stdout, "a"); X continue; X } X if (*arg == '?') { X reopen(++arg, stderr, "w"); X continue; X } X reopen(arg, stdout, "w"); X continue; X } X *args++ = strdup(arg); /* simple arg */ X } X *args = NULL; X return argbuf; X} X X X/* X * strpcpy -- copy a pascal string to a c string. X */ Xchar *strpcpy(s, p) char *s, *p; { X strncpy(s, p+1, *p); X s[*p] = EOS; X return s; X} X X/* X * reopen -- re-open stdin/out/err X * (bug -- silently terminate program on failure X */ Xstatic void reopen( file, fp, mode ) char *file; FILE *fp; char *mode; { X if ((fp = freopen(file, mode, fp)) == NULL) { X exit(1); X } X} X !-E-o-F echo "x - getopt.c" sed "s/^X//" > getopt.c <<'!-E-o-F' X#ifndef lint Xstatic char sccsid[] = "@(#)getopt.c 5.1 (Berkeley) 7/2/83"; X#endif X X#include <stdio.h> X#include <string.h> X X#define ERR(s, c) if(opterr){\ X fputs(argv[0], stderr);\ X fputs(s, stderr);\ X fputc(c, stderr);\ X fputc('\n', stderr);} else X Xint opterr = 1; Xint optind = 1; Xint optopt; Xchar *optarg; X Xint getopt (argc, argv, opts) Xint argc; Xchar **argv, *opts; X{ X static int sp = 1; X register int c; X register char *cp; X X if (sp == 1) X if (optind >= argc || X argv[optind][0] != '-' || argv[optind][1] == '\0') X return EOF; X else if (strcmp(argv[optind], "--") == 0) { X optind++; X return EOF; X } X optopt = c = argv[optind][sp]; X if (c == ':' || (cp=strchr(opts, c)) == NULL) { X ERR (": illegal option -- ", c); X if (argv[optind][++sp] == '\0') { X optind++; X sp = 1; X } X return '?'; X } X if (*++cp == ':') { X if (argv[optind][sp+1] != '\0') X optarg = &argv[optind++][sp+1]; X else if (++optind >= argc) { X ERR (": option requires an argument -- ", c); X sp = 1; X return '?'; X } else X optarg = argv[optind++]; X sp = 1; X } X else { X if (argv[optind][++sp] == '\0') { X sp = 1; X optind++; X } X optarg = NULL; X } X return c; X} !-E-o-F echo "x - getwd.c" sed "s/^X//" > getwd.c <<'!-E-o-F' X#include <stdio.h> X#include <string.h> X X#include "getarg.h" X Xchar *getwd(name) char *name; { X OSErr rc; X WDPBRec wd; X X repmem((char *)&wd,"",1,sizeof(wd)); X X if (mac_err(PBHGetVol(&wd, false), "PBHGetVol")) { X return NULL; X } X X if (av_getname(name, wd.ioWDDirID)) { X return NULL; X } X if (strchr(name, ':') == NULL) strcat(name, ":"); X return name; X} X Xint av_getname(name, n) char *name; long n; { X CInfoPBRec pb; X OSErr rc; X char space[32]; X X repmem((char *)&pb,"",1,sizeof(pb)); X X pb.dirInfo.ioNamePtr = (StringPtr)space; X pb.dirInfo.ioFDirIndex = -1; X pb.dirInfo.ioDrDirID = n; X X if (mac_err(PBGetCatInfo(&pb, FALSE), "PBGetCatInfo")) { X return -1; X } X PtoCstr(space); X if (n <= 2) { X strcpy(name, space); X } else { X av_getname(name, pb.dirInfo.ioDrParID); X strcat(name, ":"); X strcat(name, space); X } X return 0; !-E-o-F echo "x - mount.h" sed "s/^X//" > mount.h <<'!-E-o-F' X/* X * mount.h X */ X Xextern char * vol_getlabel(int); /* get volume name */ X !-E-o-F echo "x - putarg.c" sed "s/^X//" > putarg.c <<'!-E-o-F' X/* X * putarg.c -- simulate command line processing X */ X#include "portlink.h" X#include "stdio.p" X#include <ctype.h> X#include "string.p" X#include "getarg.h" X#include "stdlib.p" X X#include "stdext.h" X X#define MAXARGS 100 X Xstatic Handle myAppHandle; X Xchar ** av_hackargs(p) char *p; { X static char *argbuf[MAXARGS]; X char **av; X X for (av=argbuf; *p; ) { X *av++ = p; X if ((p=strchr(p, ' ')) == NULL) break; X *p++ = '\0'; X while (*p && isspace(*p)) ++p; X } X *av = NULL; X X return argbuf; X} X X/* X * av_putargs -- build a low memory version of the arglist. X */ Xvoid av_putargs(av) char **av; { X THz curzone, syszone; X Size avsize; X int i, t, argc; X char **p; X struct arg_hdr *ph; X AppFile *ap; X CInfoPBRec pb; X X argc = 0; X avsize = sizeof(struct arg_hdr) - sizeof(AppFile); X for (p=av; *p; ++p) { X ++argc; X t = strlen(*p)+1; X if (t & 1) ++t; X avsize += sizeof(AppFile) - sizeof(Str255) + t; X } X myAppHandle = AppParmHandle; X curzone = GetZone(); X syszone = SystemZone(); X X SetZone(syszone); X AppParmHandle = NewHandle(avsize); X HLock(AppParmHandle); X X ph = *(struct arg_hdr **)AppParmHandle; X ph->message = 0; /* open file */ X ph->count = argc; /* number of args to pass */ X ap = &ph->lst; X X for (i=0; i < argc; ++i) { X strcpy((char *)ap->fName, av[i]); X CtoPstr((char *)ap->fName); X X /* get info the name */ X repmem((char *)&pb,"",1,sizeof(pb)); X pb.dirInfo.ioDrDirID = av_curdir(av[i]); X pb.dirInfo.ioNamePtr = (StringPtr)ap->fName; X if (PBGetCatInfo(&pb, FALSE) == noErr) { X ap->vRefNum = pb.hFileInfo.ioVRefNum; X ap->fType = pb.hFileInfo.ioFlFndrInfo.fdType; X ap->versNum = 0; X } else { X ap->vRefNum = 0; X ap->fType = 0; X ap->versNum = 0; X } X X if ((t = ap->fName[0]+1) & 1) ++t; X ap = (AppFile *)(ap->fName + t); X } X#if DEBUG X av_dispargs(); X#endif X HUnlock(AppParmHandle); X SetZone(curzone); X} X Xvoid av_unputargs() { X DisposHandle(AppParmHandle); X AppParmHandle = myAppHandle; X} X Xvoid av_dispargs() { X char *arg, buf[BUFSIZ]; X int i, t; X struct arg_hdr *ph; X AppFile *ap; X X printf("av[0]: '%s'\n", strpcpy(buf, CurApName)); X X ph = *(struct arg_hdr **)AppParmHandle; X ap = &ph->lst; X for (i=0; i < ph->count; ++i) { X strpcpy(buf, (char *)ap->fName); X printf("av[%d]: %4.4s '%s'\n", i+1, &ap->fType, buf); X X if ((t = ap->fName[0]+1) & 1) ++t; X ap = (AppFile *)(ap->fName + t); X } !-E-o-F echo "x - stat.c" sed "s/^X//" > stat.c <<'!-E-o-F' X/* X * stat -- return unix stat information. X */ X#include "portlink.h" X#include <sys/types.h> X#include <sys/stat.h> X#include "string.p" X#include "stdlib.p" X#include "getarg.h" X#include <errno.h> X X#define isadir(pb) (pb.hFileInfo.ioFlAttrib & 0x0010) /* bit 4 in ....4 3210 */ X X#define EPOC 0 /* map from Jan 1,1904 to ctime's idea of the EPOC */ X /* normally Jan 1,1970, but Lightspeed-C uses the mac's EPOC */ X Xint stat(fname, sb) char *fname; struct stat *sb; { X CInfoPBRec pb; X OSErr rc; X Str255 name; X X if (fname == NULL || *fname == '\0') { X errno = EINVAL; X return NULL; X } X /* get info the name just passed to us */ X repmem((char *)&pb,"",1,sizeof(pb)); X pb.dirInfo.ioDrDirID = av_curdir(fname); X pb.dirInfo.ioNamePtr = (StringPtr)CtoPstr(strcpy((char *)name, fname)); X X if (mac_err(PBGetCatInfo(&pb, FALSE), "PBGetCatInfo")) { X return -1; X } X sb->st_dev = pb.hFileInfo.ioDirID; X sb->st_ino = pb.hFileInfo.ioFDirIndex; X if (isadir(pb)) { X sb->st_mode = S_IFDIR; X sb->st_nlink = 2; X sb->st_size = pb.dirInfo.ioDrNmFls; /* length of the data fork */ X } else { X sb->st_mode = S_IFREG; X sb->st_nlink = 1; X sb->st_size = pb.hFileInfo.ioFlLgLen; /* length of the data fork */ X#if RESOURCE X sb->st_rsize = pb.hFileInfo.ioFlRLgLen; /* length of the data fork */ X#endif X } X sb->st_uid = 0; X sb->st_gid = 0; X sb->st_rdev = sb->st_dev; X sb->st_atime = pb.hFileInfo.ioFlBkDat - EPOC; /* access time is the backup date */ X sb->st_mtime = pb.hFileInfo.ioFlMdDat - EPOC; /* modified date */ X sb->st_ctime = pb.hFileInfo.ioFlCrDat - EPOC; /* created date */ X return 0; X} X !-E-o-F echo "x - stdext.h" sed "s/^X//" > stdext.h <<'!-E-o-F' X/* X * stdext.h -- standard extensions X */ X#ifndef _STDEXT_H_DEFINED_ X#define _STDEXT_H_DEFINED_ X X#define ABORT (-1) /* status returns */ X#define ERR (-1) X#define OK 0 X X#define NO 0 /* bool returns */ X#define YES 1 X X#define EOS '\0' X X#ifndef NULL X#define NULL 0 X#endif X X#define MAXFNAME 15 /* maximum file name */ X#define MAXPNAME 128 /* maximum path name */ X#define MAXLINE 160 /* maximum line size */ X Xtypedef unsigned bool; /* boolean type */ Xtypedef unsigned char uchar; /* unsigned types */ Xtypedef unsigned int uint; Xtypedef unsigned long ulong; X Xtypedef struct TABLE TABLE; /* table type */ Xtypedef int STATUS; /* status type */ Xtypedef unsigned KEY; Xtypedef unsigned RAWKEY; Xtypedef long FPOS; /* file position */ X Xextern char * memdup(char *, int); /* malloc a new copy of the memory */ X Xextern char * nextb(char *s); Xextern char * skipb(char *s); Xextern char * skipfld(char *s, int flds); X Xextern char * strbase(char *s, char sep); /* point to after sep or s */ Xextern char * strrbase(char *s, char sep); /* point to sep char or end */ Xextern char * basename(char *path); /* point to last part of path */ Xextern char * programname(char *pathname, char *misname); /* dos fixup */ Xextern char * tackname(char *path, char *name); Xextern int pathdirlength(char *path); /* length of the dir part */ Xextern void syspath(char *from, char *to); /* normalize path */ X Xextern void strsetswitch(void); /* setup the dos switchar */ Xextern char * strdelete(char *s, int n); /* delete n chars from str */ Xextern char * strinsert(char *s1, char *s2); /* s2 inserted into s1 */ Xextern char * strtrim(char *s); /* the string blank trimmed */ Xextern char * strnnull(char *s); /* return a non-null s */ Xextern char * strfield(char *p, int n); /* return ptr to fld n */ Xextern char * strflags(uint flag, char *dp); /* return flags as str */ Xextern int strsplit(char **vector, char *str); /* return # of flds */ X Xextern char dos_switchar(char mode); /* return option char */ Xextern void fsync(FILE *); /* sync a file descriptor */ X Xextern char Path_Sep_Str[2]; X#define PATH_SEP (Path_Sep_Str[0]) X#define PATH_SEP_STR (Path_Sep_Str) X X#define bit_flip(f,b) ( f = (f&(~b)) | ((~f)&b) ) /* flip bit b in f */ X X X#endif /* _STDEXT_H_DEFINED_ */ !-E-o-F echo "x - strdup.c" sed "s/^X//" > strdup.c <<'!-E-o-F' X/* X * strdup -- malloc a copy of string p X */ X#include <stdlib.h> X Xchar *strdup(p) char *p; { X char *s; X X s = malloc(strlen(p)+1); X if (s) strcpy(s, p); X return s; X} X !-E-o-F echo "x - system.c" sed "s/^X//" > system.c <<'!-E-o-F' X/* X * system -- run a sub-command X */ X#include <stdio.h> X#include <string.h> X#include <HFS.h> X#include "getarg.h" X X#define nil (void *)0 X Xtypedef struct LaunchStruct { X StringPtr pfName; /* pointer to the name of launchee */ X long int param; X long int extBlockLen; /*number of bytes in extension == 6*/ X short int fFlags; /*Finder file info flags (see below)*/ X long int launchFlags; /*bit 31,30==1 for sublaunch, others reserved*/ X} *pLaunchStruct; X Xstatic OSErr sublaunch(char *, char **); Xstatic void subwait(void); X Xint system(cmd) char *cmd; { X OSErr rc; X char *p, **av; X X#if DEBUG X printf("Run: %s\n", cmd); X#endif X if ((p = strchr(cmd, ' ')) == NULL) { X av_hackargs(""); X } else { X *p++ = '\0'; X av = av_hackargs(p); X } X X rc = sublaunch(cmd, av); X return rc < 0 ? -1 : 0; X} X Xstatic OSErr sublaunch(cmd, av) char *cmd, **av; { X struct LaunchStruct myLaunch; X Point where; /*where to display dialog*/ X SFTypeList myFileTypes; /* we only want APPLs */ X short int numFileTypes=1; X CInfoPBRec pb; X WDPBRec wd; X StringPtr dirNameStr; X OSErr rc; X char CmdName[255]; X X /*Get the Finder flags*/ X repmem((char *)&pb,"",1,sizeof(pb)); X pb.dirInfo.ioDrDirID = av_curdir(cmd); X pb.dirInfo.ioNamePtr = (StringPtr)CtoPstr(strcpy((char *)CmdName, cmd)); X X if (mac_err(PBGetCatInfo(&pb, false), "PBGetCatInfo")) { X return -1; X } X X repmem((char *)&wd,"",1,sizeof(wd)); X if (mac_err(PBHGetVol(&wd, false), "PBHGetVOL")) { X return -1; X } X wd.ioWDProcID = 'ERIC'; X if (mac_err(PBOpenWD(&wd, false), "PBOpenWD")) { X return -1; X } X /*Set the current volume to where the target application is*/ X if (mac_err(SetVol(nil, wd.ioVRefNum), "SetVol")) { X return -1; X } X X av_putargs(av); X X /*Set up the launch parameters*/ X myLaunch.pfName = (StringPtr)CmdName; /*pointer to our fileName*/ X myLaunch.param = 'LC'; /* No alternate screen or sound buffers set up. X 'LC' tells Launch that there is non-junk next */ X myLaunch.extBlockLen = 6; /* length of param. block past this long word*/ X X /* from _GetCatInfo copy flags; set bit 6 of low byte to 1 for RO access:*/ X myLaunch.fFlags = pb.hFileInfo.ioFlFndrInfo.fdFlags; X X /* set BOTH hi bits for a sublaunch */ X myLaunch.launchFlags = 0xC0000000; X X if ((rc=LaunchIt(&myLaunch)) < 0) { X mac_err(rc, "Launch"); X av_unputargs(); X return -1; X } X subwait(); X av_unputargs(); X return noErr; X} X XOSErr LaunchIt(pLnch) pLaunchStruct pLnch; { /* < 0 means error */ X register int rc; X X /* INLINE $205F, $A9F2, $3E80 X * pops pointer into A0 and calls Launch, X * pops D0 error code into result: X */ X asm { X MOVE.L pLnch,A0 X _Launch X MOVE.W d0,rc X } X#if DEBUG X printf("launch rc=%d\n", rc); X#endif X return rc; X X} X Xstatic void subwait() { X int i; X X unsigned short mask; X EventRecord event; X unsigned long sleep; X RgnHandle mouseRgn; X X mask = ~0; X sleep = 10; X X for (i=0; i++ < 50;) { X WaitNextEvent(mask, &event, sleep, nil); X switch(event.what) { X case 0xf: X if ((event.message & 0xf) == 1) { X#if DEBUG X printf("Activated.\n"); X#endif X return; X } X if ((event.message & 0xf) == 2) { X#if DEBUG X printf("Suspened.\n"); X#endif X continue; X } X case updateEvt: X case nullEvent: X continue; X } X#if DEBUG X printf("what=%4x, msgs=%16lx\n", event.what, event.message); X#endif X if (((event.message >> 24L) & 0xFF) == 0xFD) { X#if DEBUG X printf("Process: %d exited\n", event.where); X#endif X return; X } X } X} X XOSErr do_launch() { X struct LaunchStruct myLaunch; X Point where; /*where to display dialog*/ X SFReply reply; /*reply record*/ X SFTypeList myFileTypes; /* we only want APPLs */ X short int numFileTypes=1; X HFileInfo myPB; X StringPtr dirNameStr; X OSErr rc; X X#if DEBUG X#define p(M) ((char *)&myLaunch.M - (char *)&myLaunch) X printf("pfName=%lx, param=%lx, extBL=%lx, fFlags=%lx, lFlags=%lx\n", X X p(pfName), /* pointer to the name of launchee */ X p(param), X p(extBlockLen), /*number of bytes in extension == 6*/ X p(fFlags), /*Finder file info flags (see below)*/ X p(launchFlags)); /*bit 31,30==1 for sublaunch, others reserved */ X#undef p X#endif X X where.h = 80; X where.v = 90; X myFileTypes[0] = 'APPL'; /* we only want APPLs */ X /*Let the user choose the file to Launch*/ X SFGetFile(where, "", nil, numFileTypes, myFileTypes, nil, &reply); X if (!reply.good) { X return -1; X } X dirNameStr = (StringPtr)&reply.fName; /*initialize to file selected*/ X X /*Get the Finder flags*/ X myPB.ioNamePtr= dirNameStr; X myPB.ioFDirIndex= 0; X myPB.ioDirID = 0; X myPB.ioVRefNum = reply.vRefNum; X rc = PBGetCatInfo((CInfoPBPtr) &myPB,false); X if (rc != noErr) X return rc; X X /*Set the current volume to where the target application is*/ X rc = SetVol(nil, reply.vRefNum); X if (rc != noErr) X return rc; X X /*Set up the launch parameters*/ X myLaunch.pfName = (StringPtr)&reply.fName; /*pointer to our fileName*/ X myLaunch.param = 'LC'; /*we don't want alternate screen X or sound buffers*/ X /*set up LC so as to tell Launch that there is non-junk next*/ X myLaunch.extBlockLen = 6; /*length of param. block past X this long word*/ X /*copy flags; set bit 6 of low byte to 1 for RO access:*/ X myLaunch.fFlags = myPB.ioFlFndrInfo.fdFlags; /*from _GetCatInfo*/ X X /* Test subLaunch and set launchFlags accordingly */ X myLaunch.launchFlags = 0xC0000000; /*set BOTH hi bits for a sublaunch */ X X if ((rc = LaunchIt(&myLaunch)) < 0) { /* call _Launch */ X /* the launch failed, so put up an alert to inform the user */ X#if DEBUG X printf("Launch Failed"); X#endif X return rc; X } else { X return noErr; X } /*if reply.good*/ X subwait(); X} !-E-o-F echo "x - vol_getlabel.c" sed "s/^X//" > vol_getlabel.c <<'!-E-o-F' X Xchar *vol_getlabel(drive) char drive; { X static Str255 name; X int rnum = 0; X OSErr rc; X X if ((rc = GetVol(name, &rnum)) != 0) { X mac_err("vol_getlabel", rc); X return (char *)0; X } X#if DEBUG X printf("GetVol: %d -> %s, result: %x\n", rc, name, rnum); X#endif X return PtoCstr((char *)name); X} !-E-o-F -- -- Drew Sullivan, <drew@lethe.uucp> Newsgroups: aus.mac,comp.sys.mac.programmer Subject: Re: Sublaunching in LSC Summary: Expires: References: <943@diemen.cc.utas.oz> Sender: Reply-To: drew@lethe.UUCP (Drew Sullivan) Followup-To: Distribution: Organization: Systems Software Keywords: In article <943@diemen.cc.utas.oz> charles@tasis.utas.oz (Charles Lakos) writes: >1. Has someone used the sublaunching as described in Tech Note 126 in LSC? > If so, how is the inline function Launchit coded, and is it necessary > to type up the assembly code referred to in Tech Note 88 or is it > available elsewhere? #!/bin/sh # Unix funcions for the Macintosh # All are released for any use. # If you have routines, please send them to me. # Also if you find bugs I want to know!. # echo "x - access.c" sed "s/^X//" > access.c <<'!-E-o-F' X/* X * access -- macintosh access funcion X */ X#include <sys/types.h> X#include <string.h> X#include <errno.h> X X#include "getarg.h" X Xextern int errno; X X#define NULL 0 X Xint access(fname, mode) char *fname; int mode; { X CInfoPBRec pb; X OSErr rc; X Str255 name; X X if (fname == NULL || *fname == '\0') { X errno = EINVAL; X return -1; X } X X /* get info the name just passed to us */ X repmem((char *)&pb,"",1,sizeof(pb)); X pb.dirInfo.ioDrDirID = av_curdir(fname); X pb.dirInfo.ioNamePtr = (StringPtr)CtoPstr(strcpy((char *)name, fname)); X X if (mac_err(PBGetCatInfo(&pb, FALSE), "PBGetCatInfo")) { X return -1; X } X /* BUG should check for real read/write, access (Type=='APPL') perms */ X return 0; X} X !-E-o-F echo "x - chdir.c" sed "s/^X//" > chdir.c <<'!-E-o-F' X#include <stdio.h> X#include <string.h> X X#include "getarg.h" X Xint chdir(name) char *name; { X char work[256]; X WDPBRec wd; X ioParam pb; X OSErr rc; X X repmem((char *)&wd,"",1,sizeof(wd)); X X if (mac_err(PBHGetVol(&wd, false), "PBHGetVol")) { X return -1; X } X X wd.ioCompletion = NULL; X wd.ioNamePtr = (StringPtr)CtoPstr(strcpy(work, name)); X X if (mac_err(PBHSetVol(&wd, FALSE), "PBOpenWD")) { X return -1; X } X#if DEBUG X printf("wd.ioVRefNum = %x, wd.ioWDDirID = %lx\n", wd.ioVRefNum, wd.ioWDDirID); X#endif X if (mac_err(PBHGetVol(&wd, false), "PBHGetVol")) { X return -1; X } X CurDirStore = wd.ioWDDirID; X return 0; X} !-E-o-F echo "x - curdir.c" sed "s/^X//" > curdir.c <<'!-E-o-F' X#include "portlink.h" X#include "stdlib.p" X#include "getarg.h" X#include <HFS.h> X#include <errno.h> X X#define EOS '\0' X X/* X * av_curdir - is used to check and map to in the current directory X * for relative file names; X */ X Xlong av_curdir(file) char *file; { X OSErr rc; X WDPBRec wd; X X if (strchr(file, ':') == NULL || *file == ':') { X /* relative to the current working directory */ X repmem((char *)&wd,"",1,sizeof(wd)); X X if (mac_err(PBHGetVol(&wd, false), "PBHGetVol")) { X return -1; X } X return wd.ioWDDirID; X } X /* absolue path, no current working directory */ X return 0L; X} X X#if DEBUG X#define maperr(n,p) errno = n; msg = p X#else X#define maperr(n,p) errno = n X#endif X Xint _mac_error = 0; Xchar * _mac_errid = ""; X Xint mac_err(rc, rn) int rc; char *rn; { X char *msg; X X if (rc == noErr) { X return 0; X } X _mac_error = rc; X _mac_errid = rn; X X switch (rc) { X case bdNamErr: maperr(EINVAL, "Bad file name"); break; X case dirNFErr: maperr(ENOTDIR, "Directory not found"); break; X case extFSErr: maperr(EXDEV, "External file system"); break; X case fnfErr: maperr(ENOENT, "File not found"); break; X case ioErr: maperr(EIO, "I/O Error"); break; X case nsvErr: maperr(ENOENT, "No such volume"); break; X case paramErr: maperr(ENOENT, "No default volume"); break; X default: maperr(EINVAL, "<unknown error>"); break; X } X#if DEBUG X fprintf(stderr, "%s: %d (%s) -> %d", rn, rc, msg, errno); X perror(""); X#endif X return rc; X} X X !-E-o-F echo "x - filelength.c" sed "s/^X//" > filelength.c <<'!-E-o-F' X/* X * filelenth -- return size of a unix file-descriptor X */ X#include <stdio.h> X#include <io.h> X Xlong filelength(fd) int fd; { X long size; X int rc; X X if (mac_err(GetEOF(_file[fd].refnum, &size), "GetEOF")) { X return -1L; X } X return size; /* length of the data fork */ X} !-E-o-F echo "x - getarg.c" sed "s/^X//" > getarg.c <<'!-E-o-F' X/* X * getarg.c -- simulate command line processing X */ X#include "portlink.h" X#include "stdio.p" X#include <ctype.h> X#include "string.p" X#include "getarg.h" X#include "stdlib.p" X X#include "stdext.h" X X#define MAXARGS 100 X Xstatic void reopen(char *, FILE *, char *mode); X X/* X * av_argcnt -- return the number of elements in an argv list (returns argc) X */ Xint av_argcnt(argv) char **argv; { X int argc = 0; X X while (*argv++) ++argc; X return argc; X} X X/* X * av_getargs -- Maps the mac command vector to C's argv vector X * it does I/O redirection X */ Xchar **av_getargs() { X static char * argbuf[MAXARGS]; X char **args = argbuf; X char *arg, buf[BUFSIZ]; X int i, t; X struct arg_hdr *ph; X AppFile *ap; X X *args++ = strdup(strpcpy(buf, CurApName)); X X ph = *(struct arg_hdr **)AppParmHandle; X ap = &ph->lst; X for (i=0; i < ph->count; ++i) { X arg = strpcpy(buf, (char *)ap->fName); X X if ((t = ap->fName[0]+1) & 1) ++t; X ap = (AppFile *)(ap->fName + t); X X if (*arg == '<' ) { X reopen(++arg, stdin, "r"); X continue; X } X if (*arg == '>') { X if (*++arg == '>') { X reopen(++arg, stdout, "a"); X continue; X } X if (*arg == '?') { X reopen(++arg, stderr, "w"); X continue; X } X reopen(arg, stdout, "w"); X continue; X } X *args++ = strdup(arg); /* simple arg */ X } X *args = NULL; X return argbuf; X} X X X/* X * strpcpy -- copy a pascal string to a c string. X */ Xchar *strpcpy(s, p) char *s, *p; { X strncpy(s, p+1, *p); X s[*p] = EOS; X return s; X} X X/* X * reopen -- re-open stdin/out/err X * (bug -- silently terminate program on failure X */ Xstatic void reopen( file, fp, mode ) char *file; FILE *fp; char *mode; { X if ((fp = freopen(file, mode, fp)) == NULL) { X exit(1); X } X} X !-E-o-F echo "x - getopt.c" sed "s/^X//" > getopt.c <<'!-E-o-F' X#ifndef lint Xstatic char sccsid[] = "@(#)getopt.c 5.1 (Berkeley) 7/2/83"; X#endif X X#include <stdio.h> X#include <string.h> X X#define ERR(s, c) if(opterr){\ X fputs(argv[0], stderr);\ X fputs(s, stderr);\ X fputc(c, stderr);\ X fputc('\n', stderr);} else X Xint opterr = 1; Xint optind = 1; Xint optopt; Xchar *optarg; X Xint getopt (argc, argv, opts) Xint argc; Xchar **argv, *opts; X{ X static int sp = 1; X register int c; X register char *cp; X X if (sp == 1) X if (optind >= argc || X argv[optind][0] != '-' || argv[optind][1] == '\0') X return EOF; X else if (strcmp(argv[optind], "--") == 0) { X optind++; X return EOF; X } X optopt = c = argv[optind][sp]; X if (c == ':' || (cp=strchr(opts, c)) == NULL) { X ERR (": illegal option -- ", c); X if (argv[optind][++sp] == '\0') { X optind++; X sp = 1; X } X return '?'; X } X if (*++cp == ':') { X if (argv[optind][sp+1] != '\0') X optarg = &argv[optind++][sp+1]; X else if (++optind >= argc) { X ERR (": option requires an argument -- ", c); X sp = 1; X return '?'; X } else X optarg = argv[optind++]; X sp = 1; X } X else { X if (argv[optind][++sp] == '\0') { X sp = 1; X optind++; X } X optarg = NULL; X } X return c; X} !-E-o-F echo "x - getwd.c" sed "s/^X//" > getwd.c <<'!-E-o-F' X#include <stdio.h> X#include <string.h> X X#include "getarg.h" X Xchar *getwd(name) char *name; { X OSErr rc; X WDPBRec wd; X X repmem((char *)&wd,"",1,sizeof(wd)); X X if (mac_err(PBHGetVol(&wd, false), "PBHGetVol")) { X return NULL; X } X X if (av_getname(name, wd.ioWDDirID)) { X return NULL; X } X if (strchr(name, ':') == NULL) strcat(name, ":"); X return name; X} X Xint av_getname(name, n) char *name; long n; { X CInfoPBRec pb; X OSErr rc; X char space[32]; X X repmem((char *)&pb,"",1,sizeof(pb)); X X pb.dirInfo.ioNamePtr = (StringPtr)space; X pb.dirInfo.ioFDirIndex = -1; X pb.dirInfo.ioDrDirID = n; X X if (mac_err(PBGetCatInfo(&pb, FALSE), "PBGetCatInfo")) { X return -1; X } X PtoCstr(space); X if (n <= 2) { X strcpy(name, space); X } else { X av_getname(name, pb.dirInfo.ioDrParID); X strcat(name, ":"); X strcat(name, space); X } X return 0; !-E-o-F echo "x - mount.h" sed "s/^X//" > mount.h <<'!-E-o-F' X/* X * mount.h X */ X Xextern char * vol_getlabel(int); /* get volume name */ X !-E-o-F echo "x - putarg.c" sed "s/^X//" > putarg.c <<'!-E-o-F' X/* X * putarg.c -- simulate command line processing X */ X#include "portlink.h" X#include "stdio.p" X#include <ctype.h> X#include "string.p" X#include "getarg.h" X#include "stdlib.p" X X#include "stdext.h" X X#define MAXARGS 100 X Xstatic Handle myAppHandle; X Xchar ** av_hackargs(p) char *p; { X static char *argbuf[MAXARGS]; X char **av; X X for (av=argbuf; *p; ) { X *av++ = p; X if ((p=strchr(p, ' ')) == NULL) break; X *p++ = '\0'; X while (*p && isspace(*p)) ++p; X } X *av = NULL; X X return argbuf; X} X X/* X * av_putargs -- build a low memory version of the arglist. X */ Xvoid av_putargs(av) char **av; { X THz curzone, syszone; X Size avsize; X int i, t, argc; X char **p; X struct arg_hdr *ph; X AppFile *ap; X CInfoPBRec pb; X X argc = 0; X avsize = sizeof(struct arg_hdr) - sizeof(AppFile); X for (p=av; *p; ++p) { X ++argc; X t = strlen(*p)+1; X if (t & 1) ++t; X avsize += sizeof(AppFile) - sizeof(Str255) + t; X } X myAppHandle = AppParmHandle; X curzone = GetZone(); X syszone = SystemZone(); X X SetZone(syszone); X AppParmHandle = NewHandle(avsize); X HLock(AppParmHandle); X X ph = *(struct arg_hdr **)AppParmHandle; X ph->message = 0; /* open file */ X ph->count = argc; /* number of args to pass */ X ap = &ph->lst; X X for (i=0; i < argc; ++i) { X strcpy((char *)ap->fName, av[i]); X CtoPstr((char *)ap->fName); X X /* get info the name */ X repmem((char *)&pb,"",1,sizeof(pb)); X pb.dirInfo.ioDrDirID = av_curdir(av[i]); X pb.dirInfo.ioNamePtr = (StringPtr)ap->fName; X if (PBGetCatInfo(&pb, FALSE) == noErr) { X ap->vRefNum = pb.hFileInfo.ioVRefNum; X ap->fType = pb.hFileInfo.ioFlFndrInfo.fdType; X ap->versNum = 0; X } else { X ap->vRefNum = 0; X ap->fType = 0; X ap->versNum = 0; X } X X if ((t = ap->fName[0]+1) & 1) ++t; X ap = (AppFile *)(ap->fName + t); X } X#if DEBUG X av_dispargs(); X#endif X HUnlock(AppParmHandle); X SetZone(curzone); X} X Xvoid av_unputargs() { X DisposHandle(AppParmHandle); X AppParmHandle = myAppHandle; X} X Xvoid av_dispargs() { X char *arg, buf[BUFSIZ]; X int i, t; X struct arg_hdr *ph; X AppFile *ap; X X printf("av[0]: '%s'\n", strpcpy(buf, CurApName)); X X ph = *(struct arg_hdr **)AppParmHandle; X ap = &ph->lst; X for (i=0; i < ph->count; ++i) { X strpcpy(buf, (char *)ap->fName); X printf("av[%d]: %4.4s '%s'\n", i+1, &ap->fType, buf); X X if ((t = ap->fName[0]+1) & 1) ++t; X ap = (AppFile *)(ap->fName + t); X } !-E-o-F echo "x - stat.c" sed "s/^X//" > stat.c <<'!-E-o-F' X/* X * stat -- return unix stat information. X */ X#include "portlink.h" X#include <sys/types.h> X#include <sys/stat.h> X#include "string.p" X#include "stdlib.p" X#include "getarg.h" X#include <errno.h> X X#define isadir(pb) (pb.hFileInfo.ioFlAttrib & 0x0010) /* bit 4 in ....4 3210 */ X X#define EPOC 0 /* map from Jan 1,1904 to ctime's idea of the EPOC */ X /* normally Jan 1,1970, but Lightspeed-C uses the mac's EPOC */ X Xint stat(fname, sb) char *fname; struct stat *sb; { X CInfoPBRec pb; X OSErr rc; X Str255 name; X X if (fname == NULL || *fname == '\0') { X errno = EINVAL; X return NULL; X } X /* get info the name just passed to us */ X repmem((char *)&pb,"",1,sizeof(pb)); X pb.dirInfo.ioDrDirID = av_curdir(fname); X pb.dirInfo.ioNamePtr = (StringPtr)CtoPstr(strcpy((char *)name, fname)); X X if (mac_err(PBGetCatInfo(&pb, FALSE), "PBGetCatInfo")) { X return -1; X } X sb->st_dev = pb.hFileInfo.ioDirID; X sb->st_ino = pb.hFileInfo.ioFDirIndex; X if (isadir(pb)) { X sb->st_mode = S_IFDIR; X sb->st_nlink = 2; X sb->st_size = pb.dirInfo.ioDrNmFls; /* length of the data fork */ X } else { X sb->st_mode = S_IFREG; X sb->st_nlink = 1; X sb->st_size = pb.hFileInfo.ioFlLgLen; /* length of the data fork */ X#if RESOURCE X sb->st_rsize = pb.hFileInfo.ioFlRLgLen; /* length of the data fork */ X#endif X } X sb->st_uid = 0; X sb->st_gid = 0; X sb->st_rdev = sb->st_dev; X sb->st_atime = pb.hFileInfo.ioFlBkDat - EPOC; /* access time is the backup date */ X sb->st_mtime = pb.hFileInfo.ioFlMdDat - EPOC; /* modified date */ X sb->st_ctime = pb.hFileInfo.ioFlCrDat - EPOC; /* created date */ X return 0; X} X !-E-o-F echo "x - stdext.h" sed "s/^X//" > stdext.h <<'!-E-o-F' X/* X * stdext.h -- standard extensions X */ X#ifndef _STDEXT_H_DEFINED_ X#define _STDEXT_H_DEFINED_ X X#define ABORT (-1) /* status returns */ X#define ERR (-1) X#define OK 0 X X#define NO 0 /* bool returns */ X#define YES 1 X X#define EOS '\0' X X#ifndef NULL X#define NULL 0 X#endif X X#define MAXFNAME 15 /* maximum file name */ X#define MAXPNAME 128 /* maximum path name */ X#define MAXLINE 160 /* maximum line size */ X Xtypedef unsigned bool; /* boolean type */ Xtypedef unsigned char uchar; /* unsigned types */ Xtypedef unsigned int uint; Xtypedef unsigned long ulong; X Xtypedef struct TABLE TABLE; /* table type */ Xtypedef int STATUS; /* status type */ Xtypedef unsigned KEY; Xtypedef unsigned RAWKEY; Xtypedef long FPOS; /* file position */ X Xextern char * memdup(char *, int); /* malloc a new copy of the memory */ X Xextern char * nextb(char *s); Xextern char * skipb(char *s); Xextern char * skipfld(char *s, int flds); X Xextern char * strbase(char *s, char sep); /* point to after sep or s */ Xextern char * strrbase(char *s, char sep); /* point to sep char or end */ Xextern char * basename(char *path); /* point to last part of path */ Xextern char * programname(char *pathname, char *misname); /* dos fixup */ Xextern char * tackname(char *path, char *name); Xextern int pathdirlength(char *path); /* length of the dir part */ Xextern void syspath(char *from, char *to); /* normalize path */ X Xextern void strsetswitch(void); /* setup the dos switchar */ Xextern char * strdelete(char *s, int n); /* delete n chars from str */ Xextern char * strinsert(char *s1, char *s2); /* s2 inserted into s1 */ Xextern char * strtrim(char *s); /* the string blank trimmed */ Xextern char * strnnull(char *s); /* return a non-null s */ Xextern char * strfield(char *p, int n); /* return ptr to fld n */ Xextern char * strflags(uint flag, char *dp); /* return flags as str */ Xextern int strsplit(char **vector, char *str); /* return # of flds */ X Xextern char dos_switchar(char mode); /* return option char */ Xextern void fsync(FILE *); /* sync a file descriptor */ X Xextern char Path_Sep_Str[2]; X#define PATH_SEP (Path_Sep_Str[0]) X#define PATH_SEP_STR (Path_Sep_Str) X X#define bit_flip(f,b) ( f = (f&(~b)) | ((~f)&b) ) /* flip bit b in f */ X X X#endif /* _STDEXT_H_DEFINED_ */ !-E-o-F echo "x - strdup.c" sed "s/^X//" > strdup.c <<'!-E-o-F' X/* X * strdup -- malloc a copy of string p X */ X#include <stdlib.h> X Xchar *strdup(p) char *p; { X char *s; X X s = malloc(strlen(p)+1); X if (s) strcpy(s, p); X return s; X} X !-E-o-F echo "x - system.c" sed "s/^X//" > system.c <<'!-E-o-F' X/* X * system -- run a sub-command X */ X#include <stdio.h> X#include <string.h> X#include <HFS.h> X#include "getarg.h" X X#define nil (void *)0 X Xtypedef struct LaunchStruct { X StringPtr pfName; /* pointer to the name of launchee */ X long int param; X long int extBlockLen; /*number of bytes in extension == 6*/ X short int fFlags; /*Finder file info flags (see below)*/ X long int launchFlags; /*bit 31,30==1 for sublaunch, others reserved*/ X} *pLaunchStruct; X Xstatic OSErr sublaunch(char *, char **); Xstatic void subwait(void); X Xint system(cmd) char *cmd; { X OSErr rc; X char *p, **av; X X#if DEBUG X printf("Run: %s\n", cmd); X#endif X if ((p = strchr(cmd, ' ')) == NULL) { X av_hackargs(""); X } else { X *p++ = '\0'; X av = av_hackargs(p); X } X X rc = sublaunch(cmd, av); X return rc < 0 ? -1 : 0; X} X Xstatic OSErr sublaunch(cmd, av) char *cmd, **av; { X struct LaunchStruct myLaunch; X Point where; /*where to display dialog*/ X SFTypeList myFileTypes; /* we only want APPLs */ X short int numFileTypes=1; X CInfoPBRec pb; X WDPBRec wd; X StringPtr dirNameStr; X OSErr rc; X char CmdName[255]; X X /*Get the Finder flags*/ X repmem((char *)&pb,"",1,sizeof(pb)); X pb.dirInfo.ioDrDirID = av_curdir(cmd); X pb.dirInfo.ioNamePtr = (StringPtr)CtoPstr(strcpy((char *)CmdName, cmd)); X X if (mac_err(PBGetCatInfo(&pb, false), "PBGetCatInfo")) { X return -1; X } X X repmem((char *)&wd,"",1,sizeof(wd)); X if (mac_err(PBHGetVol(&wd, false), "PBHGetVOL")) { X return -1; X } X wd.ioWDProcID = 'ERIC'; X if (mac_err(PBOpenWD(&wd, false), "PBOpenWD")) { X return -1; X } X /*Set the current volume to where the target application is*/ X if (mac_err(SetVol(nil, wd.ioVRefNum), "SetVol")) { X return -1; X } X X av_putargs(av); X X /*Set up the launch parameters*/ X myLaunch.pfName = (StringPtr)CmdName; /*pointer to our fileName*/ X myLaunch.param = 'LC'; /* No alternate screen or sound buffers set up. X 'LC' tells Launch that there is non-junk next */ X myLaunch.extBlockLen = 6; /* length of param. block past this long word*/ X X /* from _GetCatInfo copy flags; set bit 6 of low byte to 1 for RO access:*/ X myLaunch.fFlags = pb.hFileInfo.ioFlFndrInfo.fdFlags; X X /* set BOTH hi bits for a sublaunch */ X myLaunch.launchFlags = 0xC0000000; X X if ((rc=LaunchIt(&myLaunch)) < 0) { X mac_err(rc, "Launch"); X av_unputargs(); X return -1; X } X subwait(); X av_unputargs(); X return noErr; X} X XOSErr LaunchIt(pLnch) pLaunchStruct pLnch; { /* < 0 means error */ X register int rc; X X /* INLINE $205F, $A9F2, $3E80 X * pops pointer into A0 and calls Launch, X * pops D0 error code into result: X */ X asm { X MOVE.L pLnch,A0 X _Launch X MOVE.W d0,rc X } X#if DEBUG X printf("launch rc=%d\n", rc); X#endif X return rc; X X} X Xstatic void subwait() { X int i; X X unsigned short mask; X EventRecord event; X unsigned long sleep; X RgnHandle mouseRgn; X X mask = ~0; X sleep = 10; X X for (i=0; i++ < 50;) { X WaitNextEvent(mask, &event, sleep, nil); X switch(event.what) { X case 0xf: X if ((event.message & 0xf) == 1) { X#if DEBUG X printf("Activated.\n"); X#endif X return; X } X if ((event.message & 0xf) == 2) { X#if DEBUG X printf("Suspened.\n"); X#endif X continue; X } X case updateEvt: X case nullEvent: X continue; X } X#if DEBUG X printf("what=%4x, msgs=%16lx\n", event.what, event.message); X#endif X if (((event.message >> 24L) & 0xFF) == 0xFD) { X#if DEBUG X printf("Process: %d exited\n", event.where); X#endif X return; X } X } X} X XOSErr do_launch() { X struct LaunchStruct myLaunch; X Point where; /*where to display dialog*/ X SFReply reply; /*reply record*/ X SFTypeList myFileTypes; /* we only want APPLs */ X short int numFileTypes=1; X HFileInfo myPB; X StringPtr dirNameStr; X OSErr rc; X X#if DEBUG X#define p(M) ((char *)&myLaunch.M - (char *)&myLaunch) X printf("pfName=%lx, param=%lx, extBL=%lx, fFlags=%lx, lFlags=%lx\n", X X p(pfName), /* pointer to the name of launchee */ X p(param), X p(extBlockLen), /*number of bytes in extension == 6*/ X p(fFlags), /*Finder file info flags (see below)*/ X p(launchFlags)); /*bit 31,30==1 for sublaunch, others reserved */ X#undef p X#endif X X where.h = 80; X where.v = 90; X myFileTypes[0] = 'APPL'; /* we only want APPLs */ X /*Let the user choose the file to Launch*/ X SFGetFile(where, "", nil, numFileTypes, myFileTypes, nil, &reply); X if (!reply.good) { X return -1; X } X dirNameStr = (StringPtr)&reply.fName; /*initialize to file selected*/ X X /*Get the Finder flags*/ X myPB.ioNamePtr= dirNameStr; X myPB.ioFDirIndex= 0; X myPB.ioDirID = 0; X myPB.ioVRefNum = reply.vRefNum; X rc = PBGetCatInfo((CInfoPBPtr) &myPB,false); X if (rc != noErr) X return rc; X X /*Set the current volume to where the target application is*/ X rc = SetVol(nil, reply.vRefNum); X if (rc != noErr) X return rc; X X /*Set up the launch parameters*/ X myLaunch.pfName = (StringPtr)&reply.fName; /*pointer to our fileName*/ X myLaunch.param = 'LC'; /*we don't want alternate screen X or sound buffers*/ X /*set up LC so as to tell Launch that there is non-junk next*/ X myLaunch.extBlockLen = 6; /*length of param. block past X this long word*/ X /*copy flags; set bit 6 of low byte to 1 for RO access:*/ X myLaunch.fFlags = myPB.ioFlFndrInfo.fdFlags; /*from _GetCatInfo*/ X X /* Test subLaunch and set launchFlags accordingly */ X myLaunch.launchFlags = 0xC0000000; /*set BOTH hi bits for a sublaunch */ X X if ((rc = LaunchIt(&myLaunch)) < 0) { /* call _Launch */ X /* the launch failed, so put up an alert to inform the user */ X#if DEBUG X printf("Launch Failed"); X#endif X return rc; X } else { X return noErr; X } /*if reply.good*/ X subwait(); X} !-E-o-F echo "x - vol_getlabel.c" sed "s/^X//" > vol_getlabel.c <<'!-E-o-F' X Xchar *vol_getlabel(drive) char drive; { X static Str255 name; X int rnum = 0; X OSErr rc; X X if ((rc = GetVol(name, &rnum)) != 0) { X mac_err("vol_getlabel", rc); X return (char *)0; X } X#if DEBUG X printf("GetVol: %d -> %s, result: %x\n", rc, name, rnum); X#endif X return PtoCstr((char *)name); X} !-E-o-F -- -- Drew Sullivan, <drew@lethe.uucp>