This is djf.c in view mode; [Download] [Up]
/* Hacked 9/91 by D. Beatty for HP DeskJet. */ /* Hacked 2/92 to support resolution & paper feed options. * Includes printer setup and pswrap from Djf--Deskjet 500 printer filter * Reimer Mellin & Uwe Meyer-Gruhl August 1991 with help of Christian Baur. * Hacked 4-July-92 to fix EPS inclusion bug. */ /* djf--DeskJet line printer filter * from iwf--Imagewriter II line printer filter by * Eric P. Scott, San Francisco State University, November 1990 * Copyright 1990, 1991 by Eric P. Scott. All rights reserved. * * This file (and the accompanying iwwraps.psw) are freely * redistributable in their original, unmodified forms. The * author grants you a nonexclusive, royalty-free license to use * this software, and modify it as needed provided that this * copyright notice remains, and any changes are clearly * indicated as such. No part may be incorporated in products or * packages sold for profit without express permission of the * copyright holder. * * Send bug reports, enhancements, etc. to <beatty+@cs.cmu.edu> * * This software makes certain assumptions that are valid in NeXT * Software Release 2.0, and may not hold in future releases. * NO WARRANTY is expressed or implied--use at your own risk! * * It's not the best code in the world--far from it--such is the * price of working under time pressure... * * What it doesn't do: * 8-bit ASCII * use RLE (ESC V nnnn b) to reduce number of characters output * trap SIGINT to guarantee writing accounting record * * Revision History * 11/ 6/90 EPS 1.0 release * 11/ 7/90 EPS 1.1 release * fixed "creeping pixel" bug * changed ysize default from 792 to length*12 * internal EPS 1.2 * <streams/error.h> => <objc/error.h> * recognize R (Resolution) argument * 3/28/91 EPS 2.0 release * significant rewrite to use machportdevice * instead of offscreen window * add "sidedoor" code for no PublicWindowServer */ #include <stdio.h> #include <pwd.h> #include <signal.h> #include <cthreads.h> #include <servers/netname.h> #include <windowserver/printmessage.h> #import <dpsclient/dpsclient.h> #import <objc/error.h> #ifndef lint static char sccsid[]="@(#)iwf.c\t2.0 (SFSU) 3/28/91"; #endif int literal; char *host; int indent; int length; char *name; int width; int xsize, ysize; int xbytes; int resolution; /* dpi */ #ifdef DJCOMPRESS char *out_row; char *end_p; #endif /* DJCOMPRESS */ int out_count; int linect, pagect; int status; /* exit status (0=ok; 1=reprint; 2=flush) */ port_t pport; /* port for machportdevice */ netname_name_t djfportname; /* name for machportdevice */ NXPrintPageMessage ppm; /* Mach messaging area */ #define KODMSGID 0xdeadbeef mutex_t mutex1; int seen_setup= 0; /* flag for parsing only the first setup section we see! */ /* DeskJet setup: * ASCII characters * normal placement * 12 point (will change later per -l option) * upright characters * normal stroke weight * 66 lines on a page (will change later per -l option) * no top margin * clear margins (will set left margin later per -i option) * 6 lpi (will change per -l option) * graphics resolution 300dpi (will change later if -R specified) * cancel underline * display off * perforation skip off * no wrap at end of line * add CR at LF or FF * enhancement not line-by-line * si/so not line-by-line * bidirectional printing * text scale off (will turn on later for text mode) * paper size US letter * Deliberately omitted so as to be selectable from printer front panel: * Fixed or proportional spacing, * typeface selection, * draft mode * Set later: * Graphics compression mode * text pitch (per -w option) * Type size limits assume original Deskjet with Prestige cartridge. */ static char setup[]="\ \033(0U\ \033(s0U\ \033(s12V\ \033(s0S\ \033(s0B\ \033&l66P\ \033&l0E\ \0339\ \033&l6D\ \033*t300R\ \033&d@\ \033Z\ \033&l0L\ \033&s1C\ \033&k2G\ \033&k1E\ \033&k1F\ \033&k1W\ \033&k5W\ \033&l2A"; #define UNPRINTABLE 32 /* total unprintable height on page, in points */ int match(char *pattern, char *data) { int r= !strncmp(pattern,data,strlen(pattern)); #ifdef DEBUG if (r) fprintf(stderr,"DJF: matched %s\n", pattern); #endif return r; } char *skip_token(char *p) /* skip token and following spaces */ { while (*p && *p!=' ') p++; while (*p && *p==' ') p++; return p; } main(int argc, char *argv[]) { extern void *malloc(); /* stupid ANSI!!! */ extern void minit75( int w, int h, char *portname); extern void minit100( int w, int h, char *portname); extern void minit150( int w, int h, char *portname); extern void minit300( int w, int h, char *portname); extern int optind; extern char *optarg; void _textpl(DPSContext ctx, char *buf, unsigned long count); int c, l; int in_setup, res, pgwi, pghi, man; char *b; FILE *af; DPSContext pctx; struct passwd *pw; cthread_t rthread; /* reader thread */ static msg_header_t kod; char buf[8192]; while ((c=getopt(argc, argv, "cf:h:i:l:n:p:w:x:y:R:"))!=EOF) switch (c) { case 'c': literal++; break; case 'f': /* file--NeXT extension */ break; case 'h': host=optarg; break; case 'i': indent=atoi(optarg); break; case 'l': length=atoi(optarg); if (length>198) length=198; /* 72pt/" * 11" / 4pt */ break; case 'n': name=optarg; break; case 'p': /* printer--NeXT extension */ break; case 'w': width=atoi(optarg); if (width>266) width=266; /* 8" * 33.33 cpi */ break; case 'x': xsize=atoi(optarg); if (xsize>2400) xsize=2400; /* 8" * 300 dpi */ break; case 'y': ysize=atoi(optarg); if (ysize>3150) ysize=3150; /* 10.5" * 300dpi */ break; case 'R': /* Resolution--NeXT extension [2.0] */ resolution=atoi(optarg); if (resolution <= 75) resolution= 75; else if (resolution <= 100) resolution= 100; else if (resolution <= 150) resolution= 150; else resolution= 300; break; default: usage: (void)fprintf(stderr, "Usage: %s [options] [acctfile]\n", *argv); (void)fputs("\t-c don't interpret control characters\n", stderr); (void)fputs("\t-hhost host name of job owner\n", stderr); (void)fputs("\t-i# indent\n", stderr); (void)fputs("\t-l# page length in lines\n", stderr); (void)fputs("\t-nname login name of job owner\n", stderr); (void)fputs("\t-w# page width in characters\n", stderr); (void)fputs("\t-x# horizontal page size in pixels\n", stderr); (void)fputs("\t-y# vertical page size in pixels\n", stderr); (void)fputs("\t-R# resolution (pixels/inch: 75/100/150/300)\n", stderr); exit(2); /* can't use <sysexits.h>!!! */ break; } af=(FILE *)NULL; switch (argc-optind) { case 0: break; case 1: if (argv[optind][0]&&!(af=fopen(argv[optind], "a"))) { perror(argv[optind]); exit(2); } break; default: goto usage; } if (length<=0) length=66; if (width<=0) width=132; if (indent>=width) indent=width-1; if (xsize<=0) xsize=2400; /* 8" * 300dpi */ if (ysize<=0) ysize=3150; /* 10.5" * 300dpi */ if (resolution<=0) resolution= 150; /* compromise */ /* adjust bitmap size according to resolution */ xsize *= resolution; xsize /= 300; ysize *= resolution; ysize /= 300; xbytes= (xsize+7)/8; /* <stdio.h> declares this as int but man page says void */ (void)setvbuf(stdout, (char *)NULL, _IOFBF, 8192); (void)fwrite(setup, 1, (sizeof setup)-1, stdout); (void)printf("\033&a%uL\033&l%uD", indent, length/11); if ((c=getchar())==EOF) exit(0); if (c!='%') { normal: /* text mode filter */ (void)seteuid(getuid()); printf("\033(s%uH", (width+7)/8); /* set pitch, over 8" line */ printf("\033(s%uV", (72*11)/length); /* (point size) */ printf("\033&k6W"); /* set deskjet text scale on */ do { rerun: switch (c) { /* "but it's one instr. on a VAX" */ case '\0': case '\001': case '\002': case '\003': case '\004': case '\005': case '\006': case '\007': case '\013': case '\016': case '\017': case '\020': case '\021': case '\022': case '\023': case '\024': case '\025': case '\026': case '\027': case '\030': case '\032': case '\033': case '\034': case '\035': case '\036': case '\037': putchar(literal ? c : ' '); break; case '\031': /* Only at Berkeley... */ if ((c=getchar())==EOF) { l='\031'; putchar(literal ? l : ' '); goto done; } if (c=='\001') { (void)fflush(stdout); (void)kill(getpid(), SIGSTOP); continue; } putchar(literal ? '\031' : ' '); goto rerun; case '\n': linect++; if (linect<length) goto anyway; /*FALL THROUGH*/ case '\f': pagect++; linect=0; /*FALL THROUGH*/ case '\b': /* you expected intelligence? */ case '\t': /* may be wrong for deskjet */ case '\r': default: anyway: putchar(c); break; } l=c; } while ((c=getchar())!=EOF); done: switch (l) { default: putchar('\n'); linect++; if (linect>=length) pagect++; /*FALL THROUGH*/ case '\n': case '\r': putchar('\f'); pagect++; /*FALL THROUGH*/ case '\f': break; } } else { int reader(any_t arg); if ((c=getchar())==EOF) { (void)seteuid(getuid()); l='%'; putchar(l); goto done; } if (c!='!') { putchar('%'); goto normal; } /* At this point, we are committed to PostScript */ pctx=(DPSContext)NULL; NX_DURING /* attempt to connect to Window Server using defaults */ pctx=DPSCreateContext((void *)NULL, (void *)NULL, _textpl, DPSDefaultErrorProc); NX_HANDLER if (NXLocalHandler.code!=dps_err_cantConnect) NX_RERAISE(); NX_DURING void sidedoor(); sidedoor(); /* try to climb in through side door */ pctx=DPSCreateContext((void *)NULL, (void *)NULL, _textpl, DPSDefaultErrorProc); NX_HANDLER if (NXLocalHandler.code!=dps_err_cantConnect) NX_RERAISE(); NX_ENDHANDLER if (!pctx) { /* This is so lame. NeXT should make _NXDpsReporter public!!! */ (void)fputs( "DPS client library error: Could not form connection, host ", stderr); (void)fputs((char *)NXLocalHandler.data2, stderr); putc('\n', stderr); } NX_ENDHANDLER if (!pctx) exit(2); DPSSetContext(pctx); /* per postscript.321 this is unneeded */ (void)seteuid(getuid()); if ((c=port_allocate(task_self(), &pport))!=KERN_SUCCESS) { mach_error("port_allocate failed", c); exit(2); } (void)sprintf(djfportname, "djf-%d", getpid()); if ((c=netname_check_in(name_server_port, djfportname, PORT_NULL, pport))!=KERN_SUCCESS) { mach_error("netname_check_in failed", c); exit(2); } /* printf("\033&k0W"); */ /* unidirectional printing */ printf("\033*t%dR", resolution); if (pw=getpwnam(name ? name : "nobody")) DPSPrintf(pctx, "%d %d setjobuser\n", pw->pw_uid, pw->pw_gid); /* endpwent() ? */ /* call function from djwraps.psw: */ switch (resolution) { case 75: minit75( xsize, ysize, djfportname); break; case 100: minit100( xsize, ysize, djfportname); break; case 150: minit150( xsize, ysize, djfportname); break; case 300: minit300( xsize, ysize, djfportname); break; } DPSWaitContext(pctx); /* I don't want to rewrite things to use DPSAddPort() * and friends, and C Threads are probably the lesser * of several evils. */ mutex1=mutex_alloc(); rthread=cthread_fork((cthread_fn_t)reader, (any_t)0); mutex_lock(mutex1); DPSPrintf(pctx, "/-saveIW-%d- save def\n/note {} def\n\ /envelope {} def\n%%%%BeginDocument: IWGraphic\n", getpid()); mutex_unlock(mutex1); NX_DURING b=buf; *b++='%'; *b++='!'; l=0; /* sick, disgusting! */ in_setup=0; while ((c=getchar())!=EOF) { *b++=c; if (c=='\n'||b>&buf[sizeof buf]) { /* what a crock... */ if (buf[0]=='%') { if (buf[1]=='%') { if (!l) DPSWaitContext(pctx); l=1; } /* here's where to interpret comments such as: * %%BeginSetup * %%PaperSize: Executive * %%Feature: *ManualFeed True * %%Feature: *Resolution 150 * %%EndSetup * to set up the printer, and then call minit() again. * (I think this might work.) * How do you get these comments into your postscript file? * PaperSize is from Page Layout, but where did the Feature lines come from? * Copy /usr/shlib/libNeXT_s.C.shlib twice (once as a backup). * Change some strings in one copy (! denotes null bytes): * from "Cassette" "Manual" "NeXT 400 dpi Laser Printer" "400 dpi" "300 dpi" * to "Tray!!!!" "Envlop" "Hewlett-Packard DeskJet!!!" "300 dpi" "150 dpi" * (Use "DeskJet+!!" or "DeskJet500" if you like.) * Login as root on the Console (not in NeXTStep!) and copy the edited file * over the original. * (If you screw up, boot single-user and restore from your backup.) * You must match this string exactly in the Printer Type field of your * printer entry. (Use NetInfoManager to edit your printer entry.) * This enables the Paper Feed and Resolution buttons in Print panels. */ if ( (!seen_setup) && match("%%BeginSetup\n",buf)) { in_setup= 1; seen_setup= 1; pgwi=612; pghi=792; man=0; res= 300; /* default US letter, tray, 300dpi */ } else if (in_setup && match("%%PaperSize: ",buf)) { if (match("Letter\n", buf+13)) { pgwi=612; pghi=792; } else if (match("Legal\n", buf+13)) { pgwi=612; pghi=1008; } else if (match("Executive\n", buf+13)) { pgwi=540; pghi= 720; } else if (match("A4\n", buf+13)) { pgwi= 595; pghi= 842; } else if (match("A5\n", buf+13)) { pgwi= 420; pghi= 595; } else if (match("B5\n", buf+13)) { pgwi= 516; pghi= 729; } else /* default to US Letter */ { pgwi= 612; pghi= 792; } } else if (in_setup && match("%%Feature: *CustomPaperSize ", buf)) { /* This shows up when you print Landscape. */ pgwi= atoi(buf+28); pghi= atoi(skip_token(buf+28)); } else if (in_setup && match("%%Feature: *ManualFeed ",buf)) { if (match("True\n", buf+23)) { man= 1; } else if (match("False\n", buf+23)) { man= 0; } else /* default to tray feed */ { man= 0; } } else if (in_setup && match("%%Feature: *Resolution ",buf)) { if (match("300\n", buf+23)) { res= 300; } else if (match("150\n", buf+23)) { res= 150; } else /* default to 300 dpi */ { res = 300; } } else if (in_setup && match("%%EndSetup\n",buf)) { in_setup= 0; mutex_lock(mutex1); /* size paper based on height */ switch (pghi) { case 792: printf("\033&l2A"); break; /* letter */ case 1008: printf("\033&l3A"); break; /* legal */ case 842: printf("\033&l26A"); break; /* A4 */ case 297: printf("\033&l81A"); break; /* #10 envelope */ default: printf("\033&l26A"); break; } /* now try the German hack of setting height by setting lines: * set page length, top margin, and text length */ printf("\033&%dp0e%dF", pghi/12+2, pghi/12+1); #ifdef DEBUG fprintf(stderr,"DJF: page size %d x %d pt.\n", pgwi, pghi); #endif /* select envelope or paper tray */ printf("\033&l%dH", man ? 3 : 1); #ifdef DEBUG fprintf(stderr,"DJF: manual feed %d\n", man); #endif /* Select resolution; use draft mode at 150dpi and below */ printf("\033*t%dR", res); printf("\033(s%dQ", res > 150 ? 2 : 1); #ifdef DEBUG fprintf(stderr,"DJF: resolution %d\n", res); #endif mutex_unlock(mutex1); /* Finally, tell PostScript about all this nonsense. */ /* Of course, UNPRINTABLE might really vary with paper size, * but we'll assume not unless proven wrong... */ switch (res) { case 75: minit75( (pgwi*res)/72, ((pghi-UNPRINTABLE)*res)/72, djfportname); break; case 100: minit100( (pgwi*res)/72, ((pghi-UNPRINTABLE)*res)/72, djfportname); break; case 150: minit150( (pgwi*res)/72, ((pghi-UNPRINTABLE)*res)/72, djfportname); break; case 300: default: minit300( (pgwi*res)/72, ((pghi-UNPRINTABLE)*res)/72, djfportname); break; } DPSWaitContext(pctx); } } else l=0; DPSWritePostScript(pctx, buf, b-buf); b=buf; } } if (b>buf) { *b++='\n'; DPSWritePostScript(pctx, buf, b-buf); } DPSWaitContext(pctx); if (pagect==0) { /* wrong, but expected */ mutex_lock(mutex1); DPSPrintf(pctx, "\nshowpage\n"); mutex_unlock(mutex1); DPSWaitContext(pctx); } NX_HANDLER if (NXLocalHandler.code!=dps_err_ps) NX_RERAISE(); else { mutex_lock(mutex1); DPSPrintError(stderr, (DPSBinObjSeq)(NXLocalHandler.data2)); putc('\n', stderr); mutex_unlock(mutex1); } status=2; NX_ENDHANDLER mutex_lock(mutex1); DPSPrintf(pctx, "%%%%EndDocument\n-saveIW-%d- restore\n", getpid()); mutex_unlock(mutex1); DPSWaitContext(pctx); PSnulldevice(); DPSWaitContext(pctx); /* fake "EOF" on port */ kod.msg_simple=TRUE; kod.msg_size=sizeof kod; kod.msg_type=MSG_TYPE_NORMAL; kod.msg_local_port=PORT_NULL; kod.msg_remote_port=pport; kod.msg_id=KODMSGID; if ((c=msg_send(&kod, MSG_OPTION_NONE, 0))!=SEND_SUCCESS) { mutex_lock(mutex1); mach_error("msg_send failed", c); mutex_unlock(mutex1); } else pagect=(int)cthread_join(rthread); if (*djfportname&& (c=netname_check_out(name_server_port, djfportname, PORT_NULL))!=KERN_SUCCESS) { mutex_lock(mutex1); mach_error("netname_check_out failed", c); mutex_unlock(mutex1); } (void)port_deallocate(task_self(), pport); DPSDestroySpace(DPSSpaceFromContext(pctx)); } if (af) { if (name) { mutex_lock(mutex1); (void)fprintf(af, "%4d.00\t", pagect); if (host) (void)fprintf(af, "%s:", host); (void)fprintf(af, "%s\n", name); mutex_unlock(mutex1); } (void)fclose(af); } exit(status); } /* msg_receive blocks until something happens, so this runs in * its own thread. I'm trying to do a minimum amount of mutex * locking (set fingers=crossed). * * This code could stand a serious rethink... */ int reader(any_t arg) { register int rmask; register char *p, *r, *w, *eop; register msg_return_t m; char *cmax; #ifdef DJCOMPRESS extern int mode2compress(char *strt, char *end, char *buf); #endif /* DJCOMPRESS */ for (;;) { ppm.msgHeader.msg_size=sizeof ppm; ppm.msgHeader.msg_local_port=pport; if ((m=msg_receive(&ppm.msgHeader, RCV_INTERRUPT| RCV_NO_SENDERS, 0))!=RCV_SUCCESS) { mutex_lock(mutex1); mach_error("msg_receive failed", m); mutex_unlock(mutex1); break; } if (ppm.msgHeader.msg_id==KODMSGID) break; if (ppm.msgHeader.msg_id!=NX_PRINTPAGEMSGID|| ppm.printPageVersion!=3) continue; /* munchers */ if (*djfportname) { /* recall send rights */ register kern_return_t s; if ((s=netname_check_out(name_server_port, djfportname, PORT_NULL))!=KERN_SUCCESS) { mutex_lock(mutex1); mach_error("netname_check_out failed", s); mutex_unlock(mutex1); } *djfportname='\0'; if (ppm.oolImageParam.msg_type_long_size!=8) { /* woke up in the wrong universe... */ if (port_deallocate(task_self(), pport)== KERN_SUCCESS) pport=PORT_NULL; return(0); } } #ifdef OBSOLETE_JUNK if (ppm.pixelsWide>xsize) ppm.pixelsWide=xsize; /* uh-oh! */ if (ppm.oolImageParam.msg_type_long_number /ppm.bytesPerRow > ysize) ppm.oolImageParam.msg_type_long_number= ysize * ppm.bytesPerRow; #endif /* OBSOLETE_JUNK */ xbytes= (ppm.pixelsWide+7)/8; mutex_lock(mutex1); /* position cursor horiz 0 dots, vert 1 dot; start graphics at current cursor position */ /* From DJ500 driver: *p0x1yr1a gives yet another 1/8" 'headroom' Cant beat German engineers. */ printf("\033*p0xp1yr1A"); #ifdef DJCOMPRESS printf("\033*b2M"); /* mode 2 compression */ out_row= (char*) malloc(2*xbytes); #endif /* DJCOMPRESS */ mutex_unlock(mutex1); /* The Window Server returns horizontal scan-lines. */ p=(char *)ppm.printerData; r=p+ppm.bytesPerRow; eop=p+ppm.oolImageParam.msg_type_long_number; while (p<eop) { mutex_lock(mutex1); #ifdef DJCOMPRESS end_p= p+xbytes; /* Remove trailing 0s. */ while ( end_p > p && end_p[-1] == 0 ) end_p--; out_count= mode2compress(p,end_p,out_row); printf("\033*b%dW", out_count); fwrite(out_row, sizeof(char), out_count, stdout); #else /* ndef DJCOMPRESS */ printf("\033*b%uW", ppm.bytesPerRow); fwrite(p,sizeof(char), xbytes, stdout); #endif /* def/ndef DJCOMPRESS */ mutex_unlock(mutex1); p=r; /* raster could be padded */ r=p+ppm.bytesPerRow; } mutex_lock(mutex1); printf("\033*rB\033&l0H"); /* end raster graphics; new page */ fflush(stdout); mutex_unlock(mutex1); pagect++; /* unmap and ACK page */ (void)vm_deallocate(task_self(), (vm_address_t)ppm.printerData, (vm_size_t)ppm.oolImageParam.msg_type_long_number); ppm.msgHeader.msg_simple=TRUE; ppm.msgHeader.msg_size=sizeof ppm.msgHeader; ppm.msgHeader.msg_type=MSG_TYPE_NORMAL; ppm.msgHeader.msg_local_port=PORT_NULL; ppm.msgHeader.msg_id=NX_PRINTPAGEMSGID; if ((m=msg_send(&ppm.msgHeader, MSG_OPTION_NONE, 0))!= SEND_SUCCESS) { mutex_lock(mutex1); mach_error("msg_send failed", m); mutex_unlock(mutex1); break; } } return(pagect); } /* DPSCreateContext[WithTimeoutFromZone] looks in two places for * a port to the Window Server: * * 1) The Bootstrap Server for "WindowServer" * 2) The Network Name Server for "NextStep(tm) Window Server" * * If PublicWindowServer is *not* set, then (2) won't be checked * in, and (1) will be checked in with a subset bootstrap port * and available only to descendents of loginwindow (i.e. * Workspace and its descendents). * * This horrible hack set us up to inherit from loginwindow, as * if we were a proper descendent. * * Most is lifted straight from the 2.0 Reference. * table() is undocumented according to NextAnswers. * * N.B. when a user with PublicWindowServer==No logs out, the * subset port is destroyed and neither (1) nor (2) will work. * No one said life was fair. * * This code *must* run as root; djf must be set-uid root if * we're to be standalone (not running under control of lpd). * */ #include <sys/table.h> #include <servers/bootstrap.h> #ifndef lint static char sccsid_[]="@(#)sidedoor.c\t1.0 (SFSU) 3/27/91"; #endif void sidedoor() { register host_priv_t hpriv; register unsigned int hidx, tidx; processor_set_name_array_t hlist; unsigned int hcount; processor_set_t ppriv; task_array_t tlist; unsigned int tcount; int pid, mypid; port_t b; struct tbl_procinfo pi; if (!(hpriv=host_priv_self())) { /* must run as root! */ (void)fputs("couldn't get host privileged port\n", stderr); return; } /* superuser privileges are not required beyond this point */ if (host_processor_sets(hpriv, &hlist, &hcount)!=KERN_SUCCESS) (void)fputs("couldn't get processor sets\n", stderr); else { mypid=getpid(); for (hidx=0;hidx<hcount;hidx++) { if (host_processor_set_priv(hpriv, hlist[hidx], &ppriv)!= KERN_SUCCESS) ppriv=hlist[hidx]; if (processor_set_tasks(ppriv, &tlist, &tcount)==KERN_SUCCESS) { for (tidx=0;tidx<tcount;tidx++) { if (unix_pid(tlist[tidx], &pid)==KERN_SUCCESS&&pid>3) { if (pid==mypid) continue; if (table(TBL_PROCINFO, pid, (char *)&pi, 1, sizeof pi)==1&& pi.pi_status==PI_ACTIVE&&pi.pi_ppid==1&& pi.pi_ttyd<0&&pi.pi_uid==0&& !strncmp(pi.pi_comm, "loginwindow", PI_COMLEN)&& task_get_bootstrap_port(tlist[tidx], &b)== KERN_SUCCESS&&b!=PORT_NULL) { if (task_set_bootstrap_port(task_self(), b)== KERN_SUCCESS) bootstrap_port=b; else (void)port_deallocate(task_self(), b); } } (void)port_deallocate(task_self(), tlist[tidx]); } (void)vm_deallocate(task_self(), (vm_address_t)tlist, tcount*sizeof (port_t)); } else (void)fprintf(stderr, "couldn't get tasks for processor set %d\n", hidx); (void)port_deallocate(task_self(), ppriv); if (hlist[hidx]!=ppriv) (void)port_deallocate(task_self(), hlist[hidx]); } (void)vm_deallocate(task_self(), (vm_address_t)hlist, hcount*sizeof (processor_set_name_t)); } (void)port_deallocate(task_self(), hpriv); /* have I deallocated everything I should? */ } /* this shouldn't ever be called... */ void _textpl(DPSContext ctx, char *buf, unsigned long count) { (void)write(2, buf, count); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.