Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!wuarchive!zaphod.mps.ohio-state.edu!uakari.primate.wisc.edu!aplcen!haven!adm!news From: postmaster@ecf.ncsl.nist.gov (SMTP MAILER) Newsgroups: comp.unix.wizards Subject: Mail Delivery Problem Message-ID: <24112@adm.BRL.MIL> Date: 11 Aug 90 11:21:49 GMT Sender: news@adm.BRL.MIL Lines: 1793 ----Reason for mail failure follows---- Sending mail to host ecf.ncsl.nist.gov : Fatal reply code to command 'RCPT TO:': 550 User "ise.ncsl.nist.gov" Unknown. ----Transcript of message follows---- Date: 11 Aug 90 06:45:00 EST From: unix-wizards@BRL.MIL Subject: UNIX-WIZARDS Digest V10#113 To: "ise.ncsl.nist.gov" Return-Path: Received: from SEM.BRL.MIL by ecf.ncsl.nist.gov with SMTP ; Sat, 11 Aug 90 06:44:47 EST Received: from SEM.BRL.MIL by SEM.BRL.MIL id aa03279; 11 Aug 90 5:57 EDT Received: from sem.brl.mil by SEM.BRL.MIL id aa03234; 11 Aug 90 5:45 EDT Date: Sat, 11 Aug 90 05:45:11 EST From: The Moderator (Mike Muuss) To: UNIX-WIZARDS@BRL.MIL Reply-To: UNIX-WIZARDS@BRL.MIL Subject: UNIX-WIZARDS Digest V10#113 Message-ID: <9008110545.aa03234@SEM.BRL.MIL> UNIX-WIZARDS Digest Sat, 11 Aug 1990 V10#113 Today's Topics: Re: Cron - First Saturday of the month Re: Streams message allocation nested loops Re: nested loops waitpid() ??? unix sys v - uptime question Interesting keyboard read problem (ioctl, function keys) sockets and signals (in C) Re: sockets and signals (in C) Re: Re.: UNdeleting files seeking information about file system details. evaluating ${10} and above in sh/ksh Re: How variables can be specified as arguments Re: ln -f ----------------------------------------------------------------- From: Bob Strait Subject: Re: Cron - First Saturday of the month Date: 9 Aug 90 17:13:32 GMT To: unix-wizards@sem.brl.mil In article <19744@orstcs.CS.ORST.EDU> curt@oce.orst.edu (Curt Vandetta) writes: > I'm wondering if anyone has a way of making cron run a job on the > first Saturday of every month? > How about running your job each of the first seven days of every month, and have the job first test whether it's Saturday and exit if it's not. There are several easy ways to do the test: 'date | grep Sat' comes to mind. -- BUBBA (aka Bob Strait) ...!mips!svcs1!rls Silicon Valley Computer Society Sunnyvale, CA -- ----------------------------- From: Bob McGowen x4312 dept208 Subject: Re: Cron - First Saturday of the month Date: 10 Aug 90 02:40:29 GMT Sender: news@wyse.wyse.com To: unix-wizards@sem.brl.mil In article <1990Aug8.185745.16606@iwarp.intel.com> merlyn@iwarp.intel.com (Randal Schwartz) writes: >In article <19744@orstcs.CS.ORST.EDU>, curt@oce (Curt Vandetta) writes: >| I'm wondering if anyone has a way of making cron run a job on the >| first Saturday of every month? > >3 4 1-7 * 6 command > >to make 'command' run at 4:03am... adjust the first two fields as >necessary. Remember, the parameters are "and"-ed together. ...flame deleted My documentation states that a line like the one you have provided would cause the command to run on EVERY Saturday as well as on each of the first seven days in the month. My flame-- I would be very interested if you could provide a cron only method of getting my cron to execute on the first Saturday (or any other day) such that it executes on that single day only. My attempts at solving this have been to combine cron to run the command on Saturday and have command be a script that checks the date to be sure it is less than or equal to 7. But this only works for the first 13 days so I have to figure out the next exclusion, probably to limit between a start and stop. In any case, getting cron to do what Curt wants is a little more difficult. Possibly (probably, I think) even wizard caliber. Bob McGowan (standard disclaimer, these are my own ...) Product Support, Wyse Technology, San Jose, CA ..!uunet!wyse!bob bob@wyse.com ----------------------------- From: Michael van Elst Subject: Re: Cron - First Saturday of the month Date: 10 Aug 90 14:28:35 GMT Posted: Fri Aug 10 15:28:35 1990 To: unix-wizards@sem.brl.mil In article <1990Aug8.185745.16606@iwarp.intel.com> merlyn@iwarp.intel.com (Randal Schwartz) writes: >In article <19744@orstcs.CS.ORST.EDU>, curt@oce (Curt Vandetta) writes: >| I'm wondering if anyone has a way of making cron run a job on the >| first Saturday of every month? >3 4 1-7 * 6 command >to make 'command' run at 4:03am... adjust the first two fields as >necessary. Remember, the parameters are "and"-ed together. From the SunOS4.03 Manual: Note: the specification of days may be made by two fields (day of the month and day of the week). If both are specified as a list of elements, both are adhered to. For example: 0 0 1,15 * 1 command would run a command on the first and the fifteenth of each month, as well as on every Monday. . . Seems that, at least here, your suggestion doesn't work. -- Michael van Elst UUCP: universe!local-cluster!milky-way!sol!earth!uunet!unido!mpirbn!p554mve Internet: p554mve@mpirbn.mpifr-bonn.mpg.de "A potential Snark may lurk in every tree." ----------------------------- From: Ed Anselmo Subject: Re: Cron - First Saturday of the month Date: 10 Aug 90 16:42:38 GMT Sender: news@cs.yale.edu Nntp-Posting-Host: bigbird.cf.cs.yale.edu To: unix-wizards@sem.brl.mil I peeked at the sources -- the BSD cron "ands" all the fields together. I don't have Sun 4.x sources, but under SunOS 4.0.3, I saw the same behavior as David Canzi saw. So, with a crontab like: 28 12 1-5 * 5 anselmo date > /homes/facility/anselmo/temp/www 28 12 7-11 * 1 anselmo date > /homes/facility/anselmo/temp/xxx 28 12 1-5 * 1 anselmo date > /homes/facility/anselmo/temp/yyy 28 12 7-11 * 5 anselmo date > /homes/facility/anselmo/temp/zzz running on Fri Aug 10, under the BSD cron, only zzz got created. Running under Sun 4.x cron (with the crontab entries suitably modified), www, xxx, and zzz got created. -- Ed Anselmo anselmo-ed@cs.yale.edu {harvard,cmcl2}!yale!anselmo-ed ----------------------------- From: Maarten Litmaath Subject: Re: Cron - First Saturday of the month Date: 10 Aug 90 17:26:39 GMT Sender: news@cs.vu.nl To: unix-wizards@sem.brl.mil The manual (man 5 crontab on SunOS 4.0.3c): [...] Note: the specification of days may be made by two fields (day of the month and day of the week). If both are speci- fied as a list of elements, both are adhered to. For exam- ple, 0 0 1,15 * 1 would run a command on the first and fifteenth of each month, as well as on every Monday. To specify days by only one field, the other field should be set to *. For example, 0 0 * * 1 would run a command only on Mondays. [...] The code: int match(cp, loct) register char **cp; register struct tm *loct; { int cancel_ex = 0; *cp = cmp(*cp, loct->tm_min, &cancel_ex); *cp = cmp(*cp, loct->tm_hour, &cancel_ex); *cp = cmp(*cp, loct->tm_mday, &cancel_ex); *cp = cmp(*cp, loct->tm_mon, &cancel_ex); *cp = cmp(*cp, loct->tm_wday, &cancel_ex); return(!cancel_ex); } char * cmp(p, v, cancel_ex) char *p; int *cancel_ex; { register char *cp; cp = p; switch(*cp++) { case EXACT: if (*cp++ != v) (*cancel_ex)++; return(cp); case ANY: return(cp); case LIST: while(*cp != LIST) if(*cp++ == v) { while(*cp++ != LIST) ; return(cp); } (*cancel_ex)++; return(cp+1); case RANGE: if(cp[0] < cp[1]) { if(!(cp[0]<=v && cp[1]>=v)) (*cancel_ex)++; } else if(!(v>=cp[0] || v<=cp[1])) (*cancel_ex)++; return(cp+2); } if(cp[-1] != v) (*cancel_ex)++; return(cp); } The conclusion: the manual and the code contradict each other! The example 0 0 1,15 * 1 ...will run the job on each monday whose date is either the 1st or the 15th! It might be too late to fix the manual... (Grrrr!) -- "UNIX was never designed to keep people from doing stupid things, because that policy would also keep them from doing clever things." (Doug Gwyn) ----------------------------- From: Chip Salzenberg Subject: Re: Cron - First Saturday of the month Date: 10 Aug 90 17:46:26 GMT To: unix-wizards@sem.brl.mil According to dmcanzi@watserv1.waterloo.edu (David Canzi): >if [ `date | sed 's/^... ... *\([^ ]*\) .*/\1/'` -le 7 ] At least on SysV, this is working too hard! Use this instead: if [ "`date +%d`" -le 7 ] Manual pages are wonderful things... -- Chip Salzenberg at ComDev/TCT , ----------------------------- From: Maarten Litmaath Subject: Re: Cron - First Saturday of the month Date: 10 Aug 90 18:13:28 GMT 6@star.cs.vu Sender: news@cs.vu.nl To: unix-wizards@sem.brl.mil In article <7286@star.cs.vu.nl>, I wrote: )The manual (man 5 crontab on SunOS 4.0.3c): )... )The code: )... I forgot to mention the code is _not_ SunOS 4.0.3c (still no up to date sources...) Anyway, my point still stands: _anding_ the fields is preferred (as Randal already explained), but it might be too late to fix the specifications... -- "UNIX was never designed to keep people from doing stupid things, because that policy would also keep them from doing clever things." (Doug Gwyn) ----------------------------- From: Ronald S H Khoo Subject: Re: Cron - First Saturday of the month Date: 10 Aug 90 19:05:17 GMT To: unix-wizards@sem.brl.mil In article <1990Aug10.063819.5253@iwarp.intel.com> merlyn@iwarp.intel.com (Randal Schwartz) writes: > Sigh. Sorry. I'll crawl under my rock now. Cron's only for the > heavyweights, anyway. System V cron isn't just for heavyweights, though, it's got per-user crontabs, remember, so joe-random-non-wizard who has his own crontab has to understand the manpage. Sigh. Someone once mentioned wanting to write a System V-like cron in perl so he could have per-user crontabs on his machine. I wonder who it was, and how he parsed the manpage ? -- Eunet: Ronald.Khoo@robobar.Co.Uk Phone: +44 81 991 1142 Fax: +44 81 998 8343 Paper: Robobar Ltd. 22 Wadsworth Road, Perivale, Middx., UB6 7JD ENGLAND. ----------------------------- From: Randal Schwartz Subject: Re: Cron - First Saturday of the month Date: 10 Aug 90 22:43:31 GMT 6@star.cs.vu Sender: news@iwarp.intel.com To: unix-wizards@sem.brl.mil In article <7286@star.cs.vu.nl>, maart@cs (Maarten Litmaath) writes: | The code: [deleted to protect my eyes, but it *is* the code I remember ...] | The conclusion: the manual and the code contradict each other! | The example | | 0 0 1,15 * 1 | | ...will run the job on each monday whose date is either the 1st or the 15th! | It might be too late to fix the manual... (Grrrr!) Yes, this is my point. Actually, what I think happened is that you posted the V7-derived cron, and Sunos4.1 went to the user-crontab System (blech) V cron, and I suspect that they put some widgets in there to do this stupid "OR" logic that I complained about in my last two postings. Anyone with access to system V source care to comment? Are there some yucky kludges in there? Just another System V disliker, -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/ ----------------------------- From: David Canzi Subject: Re: Cron - First Saturday of the month Date: 11 Aug 90 03:08:18 GMT To: unix-wizards@sem.brl.mil In article <1990Aug8.214539.1264@watserv1.waterloo.edu> I wrote: >In a sh script, it can be done by: > >if [ `date | sed 's/^... ... *\([^ ]*\) .*/\1/'` -le 7 ]; then > ... >fi This is better done using awk: if [ `date | awk '{print $3}'` -le 7 ]; then ... fi -- David Canzi ----------------------------- From: Larry McVoy Subject: Re: Streams message allocation Keywords: streams deadlock Date: 9 Aug 90 17:21:06 GMT Sender: news@sun.eng.sun.com To: unix-wizards@sem.brl.mil In article <1990Aug2.043059.578@cbnewsl.att.com> sar0@cbnewsl.att.com (stephen.a.rago) writes: >The number of messages needed per buffer class (size) is something that >can only be determined statistically or empirically. In the absence of >information like inter-arrival rate of allocation requests and message >hold times, the best way to proceed is to start with an educated guess >of how many messages you may need. Here's a package I wrote a few years ago when tuning STREAMS for SCO XENIX (I was porting the LAI TCP/IP to XENIX and tuning was really critical). Use this while your system is under a "normal" load and it will give you a pretty good idea of where to set things. No promises that it works - it worked on SCO XENIX a while ago, beyond that you're on your own. If you have SCO XENIX & TCP/IP you should have this program already. # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # Makefile mode.c sw.1 sw.c term.h termcap.c echo x - Makefile cat > "Makefile" << '//E*O*F Makefile//' O = sw.o termcap.o mode.o S = Makefile sw.1 sw.c termcap.c mode.c term.h #CFLAGS=-DUNIX=\"/xenix\" -DKMEM=\"/dev/mem\" -DSAVECNT=0 BIN=/usr/local/bin all sw: $O cc $O -ltermlib -o sw install: sw cp sw $(BIN) chown root $(BIN)/sw chmod 4755 $(BIN)/sw clean: rm -f $O a.out core shar clobber: clean rm -f sw shar: shar $S > shar //E*O*F Makefile// echo x - mode.c cat > "mode.c" << '//E*O*F mode.c//' /* * copyright (C) 1986 by Larry McVoy * MUST be distributed in source form only. */ # include # include # include static struct sgttyb buf; static done = 0; delay(on) { if (on) { int flags; fcntl(0, F_GETFL, &flags); flags &= ~O_NDELAY; return fcntl(0, F_SETFL, flags); } else { return fcntl(0, F_SETFL, O_NDELAY); } } cbreak(on) { if (!done) { ioctl(fileno(stdin), TIOCGETP, &buf); done++; } if (on) { buf.sg_flags |= CBREAK; ioctl(fileno(stdin), TIOCSETP, &buf); } else { buf.sg_flags &= ~CBREAK; ioctl(fileno(stdin), TIOCSETP, &buf); } } echo(on) { if (!done) { ioctl(fileno(stdin), TIOCGETP, &buf); done++; } if (on) { buf.sg_flags |= ECHO; ioctl(fileno(stdin), TIOCSETP, &buf); } else { buf.sg_flags &= ~ECHO; ioctl(fileno(stdin), TIOCSETP, &buf); } } //E*O*F mode.c// echo x - sw.1 cat > "sw.1" << '//E*O*F sw.1//' .TH SW 1 .UC 4 .SH NAME sw - (stream watch) watch streams resources on System V .SH SYNOPSIS .B sw .SH DESCRIPTION .I Sw digs into kmem to find out how many streams, queues, message blocks, and data blocks are in use. It find this in the \fIstruct strstat strst\fR variable. For each category mentioned above the following fields are printed: .IP Use (strst.use) How many of the resource in question are in use. .IP "Ave10, Ave30, Ave60, Ave120" As above, only the value is averaged over the last N iterations (an iteration is about one second). .IP Total (strst.total) The total number of the resource used since boot time or the last time it was cleared. .IP Max (strst.max) The maximum number of the resource allocated at the same time. .IP Fail (strst.fail) The number of times a request was made, for the resource, that could not be granted. .PP The data block section is further broken down into sub classes. This section has a slightly different format; in the title section the field is \fISiz<#> Count <#>\fR, where the first number is the data block size and the second number is the number of data blocks statically allocated. .PP The screen is managed by curses. It will respond to: .IP c clear the total max & fail fields (you have to have write permission on /dev/mem). .IP ^L redraw the screen. .IP N Where N is 0-9. Set the number of seconds between interations. .IP q (quit) Quit the program. .IP ^L (Control-L) Refresh the screen. .SH FILES .DT /dev/kmem kernel memory .br /unix for getting variable addresses .SH BUGS The definitions of the various fields is my best guess, they do not reflect any AT&T documentation that I've read. .SH COPYRIGHT \fBSw\fR is copyright 1988 by Larry McVoy. Permission is hereby granted to publish strings in source or object form as long as all copyright notices are retained. Object-only distributions are permitted only if the source is also freely available from the distributer. Any fee charged for such publication may consist only of a reasonable charge for any media used. .SH AUTHOR Larry McVoy (lm@eng.sun.com) //E*O*F sw.1// echo x - sw.c cat > "sw.c" << '//E*O*F sw.c//' /* * copyright 1988 by Larry McVoy. All rights reserved. * If you redistribute this you must distribute in source form. */ #include "term.h" #include #ifdef M_XENIX #include #else #include #endif #include #include #include #include #include #include #include #if defined(M_XENIX) || defined(sys5) #include #endif #ifndef UNIX #define UNIX "/vmunix" #endif #ifndef KMEM #define KMEM "/dev/kmem" #endif #ifdef M_XENIX #define v_nblk4096 v_nblk8192 #endif #ifdef sun #define NCLASS 9 #endif #ifndef SAVECNT #define SAVECNT 121 #endif #define kbytes(x) ( ((x)+1023) >> 10) #ifdef M_XENIX #define nlist xlist #define n_value xl_value #define n_name xl_name struct nlist nl[] = { #define NL_STRST 0 {0,0,0,"_strst"}, #define NL_RBSIZE 1 {0,0,0,"_rbsize"}, #define NL_V 2 {0,0,0,"_v"}, #define NL_DBALLOC 3 {0,0,0,"_dballoc"}, #define NL_NMBLOCK 4 {0,0,0,"_nmblock"}, {0,0,0,(char *) 0}, }; #else #ifdef sys5 struct nlist nl[] = { #define NL_STRST 0 {"_strst"}, #define NL_RBSIZE 1 {"_rbsize"}, #define NL_V 2 {"_v"}, #define NL_DBALLOC 3 {"_dballoc"}, #define NL_NMBLOCK 4 {"_nmblock"}, { 0 }, }; #else #ifdef sun char* nl_names[] = { #define NL_STRST 0 "_strst", #define NL_RBSIZE 1 "_rbsize", #define NL_NDBLKS 2 "_ndblks", #define NL_DBALLOC 3 "_dballoc", #define NL_NMBLOCK 4 "_nmblock", "", }; struct nlist nl[sizeof(nl_names)/sizeof(char*)]; #endif /* sun */ #endif /* sys5 */ #endif /* M_XENIX */ ushort rbsize[NCLASS]; short cnt[NCLASS]; struct dbalcst dballoc[NCLASS]; int total, ndblock, nmblock, fd, sleeptime = 1; #ifndef sun struct var v; #endif typedef struct { alcdat stream; alcdat queue; alcdat mblock; alcdat dblock; alcdat dblk[NCLASS]; } Strstat; Strstat strst; /* * It's the main thing... */ main(ac, av) char** av; { int* p; int i; int done(); for (i=1; i 0 sprintf(buf, "%11s%5s%6s%6s%6s%6s%7s%8s%8s%8s", "Resource", "Cnt", "Use", "Ave10", "Ave30", "Ave60", "Ave120", "Total", "Max", "Fail"); # else sprintf(buf, "%11s%5s%10s%8s%8s%8s", "Resource", "Cnt", "Use", "Total", "Max", "Fail"); # endif tprint(buf, 0, 2); # ifdef sun sprintf(buf, "%11s:%4s", "stream", "?"); tprint(buf, 0, 3); sprintf(buf, "%11s:%4s", "queue", "?"); tprint(buf, 0, 4); # else sprintf(buf, "%11s:%4d", "stream", v.v_nstream); tprint(buf, 0, 3); sprintf(buf, "%11s:%4d", "queue", v.v_nqueue); tprint(buf, 0, 4); # endif sprintf(buf, "%11s:%4d", "mblock", nmblock); tprint(buf, 0, 5); sprintf(buf, "%11s:%4d", "dblk totals", ndblock); tprint(buf, 0, 6); # if SAVECNT > 0 sprintf(buf, "%4s%4s%4s%4s%6s%6s%6s%6s%7s%8s%8s%8s", "Size", "Cnt", "Med", "Low", "Use", "Ave10", "Ave30", "Ave60", "Ave120", "Total", "Max", "Fail"); # else sprintf(buf, "%-4s%4s%4s%4s%4s%6s%8s%8s%8s", "Mem", "Size", "Cnt", "Med", "Low", "Use", "Total", "Max", "Fail"); # endif tprint(buf, 0, 8); for (total=i=0; i 0 sprintf(buf, "%4d %3d %3d %3d", rbsize[i], cnt[i], med, lo); # else sprintf(buf, "%3d %4d %3d %3d %3d", kbytes(rbsize[i] * cnt[i]), rbsize[i], cnt[i], med, lo); # endif tprint(buf, 0, 9 + i); } sprintf(buf, "Buffers (used/total) = "); tprint(buf, 0, 23); Pause(); } Pause() { char buf[40]; sprintf(buf, "Pause=%d", sleeptime); tprint(buf, 0, 0); } # if SAVECNT == 0 /* * display the information, called once per second (about) * * No averaging version */ dump(s) register struct strstat* s; { char buf[80]; register i, mem = 0; static calls = 0; sprintf(buf, "%6d%8d%8d%8d", s->stream.use, s->stream.total, s->stream.max, s->stream.fail); tprint(buf, 20, 3); sprintf(buf, "%6d%8d%8d%8d", s->queue.use, s->queue.total, s->queue.max, s->queue.fail); tprint(buf, 20, 4); sprintf(buf, "%6d%8d%8d%8d", s->mblock.use, s->mblock.total, s->mblock.max, s->mblock.fail); tprint(buf, 20, 5); sprintf(buf, "%6d%8d%8d%8d", s->dblock.use, s->dblock.total, s->dblock.max, s->dblock.fail); tprint(buf, 20, 6); for (i=0; idblk[i].use * rbsize[i]; sprintf(buf, "%6d%8d%8d%8d", s->dblk[i].use, s->dblk[i].total, s->dblk[i].max, s->dblk[i].fail); tprint(buf, 20, 9 + i); } sprintf(buf, "%d/%d Kbytes", kbytes(mem), kbytes(total)); tprint(buf, 23, 23); calls++; sprintf(buf, "Calls=%d", calls); tprint(buf, 10, 0); } # else /* * display the information, called once per second (about) * * Averaging version */ dump(s) register struct strstat* s; { char buf[80]; register i, j, b10, b30, b60, b120, mem = 0; static struct strstat pst[SAVECNT]; static struct strstat sum10, sum30, sum60, sum120; static calls = 0; j = calls % SAVECNT; b10 = (j + SAVECNT - 10) % SAVECNT; b30 = (j + SAVECNT - 30) % SAVECNT; b60 = (j + SAVECNT - 60) % SAVECNT; b120 = (j + SAVECNT - 120) % SAVECNT; memcpy(&pst[j], s, sizeof(struct strstat)); addstrst(s, &sum10); addstrst(s, &sum30); addstrst(s, &sum60); addstrst(s, &sum120); if (!calls) { mulstrst(&sum10, 10); mulstrst(&sum30, 30); mulstrst(&sum60, 60); mulstrst(&sum120, 120); for (i=1; istream.use, sum10.stream.use / 10, sum30.stream.use / 30, sum60.stream.use / 60, sum120.stream.use / 120, s->stream.total, s->stream.max, s->stream.fail); tprint(buf, 16, 3); sprintf(buf, "%6d%6d%6d%6d%7d%8d%8d%8d", s->queue.use, sum10.queue.use / 10, sum30.queue.use / 30, sum60.queue.use / 60, sum120.queue.use / 120, s->queue.total, s->queue.max, s->queue.fail); tprint(buf, 16, 4); sprintf(buf, "%6d%6d%6d%6d%7d%8d%8d%8d", s->mblock.use, sum10.mblock.use / 10, sum30.mblock.use / 30, sum60.mblock.use / 60, sum120.mblock.use / 120, s->mblock.total, s->mblock.max, s->mblock.fail); tprint(buf, 16, 5); sprintf(buf, "%6d%6d%6d%6d%7d%8d%8d%8d", s->dblock.use, sum10.dblock.use / 10, sum30.dblock.use / 30, sum60.dblock.use / 60, sum120.dblock.use / 120, s->dblock.total, s->dblock.max, s->dblock.fail); tprint(buf, 16, 6); for (i=0; idblk[i].use * rbsize[i]; sprintf(buf, "%6d%6d%6d%6d%7d%8d%8d%8d", s->dblk[i].use, sum10.dblk[i].use / 10, sum30.dblk[i].use / 30, sum60.dblk[i].use / 60, sum120.dblk[i].use / 120, s->dblk[i].total, s->dblk[i].max, s->dblk[i].fail); tprint(buf, 16, 9 + i); } sprintf(buf, "%d/%d Kbytes", kbytes(mem), kbytes(total)); tprint(buf, 23, 23); calls++; sprintf(buf, "Calls=%d", calls); tprint(buf, 10, 0); } /* * add a to be, leave result in b * * N.B. Assumes that elements are ints */ addstrst(a, b) register alcdat* a; register alcdat* b; { register i; for (i=sizeof(struct strstat)/sizeof(*a); i--; (b++)->use += (a++)->use) ; } /* * subtract a from be, result in b */ substrst(a, b) register alcdat* a; register alcdat* b; { register i; for (i=sizeof(struct strstat)/sizeof(*a); i--; (b++)->use -= (a++)->use) ; } /* * multiply a by b, result in a */ mulstrst(a, b) register alcdat* a; register int b; { register i; for (i=sizeof(struct strstat)/sizeof(*a); i--; (a++)->use *= b) ; } # endif /* SAVECNT */ /* * nasty cleanup */ error(s) char* s; { perror(s); done(); } /* * nice cleanup */ done() { echo(1); cbreak(0); delay(1); tprint("", cols -1, lines - 1); printf("\n"); exit(0); } /* * read all once only stuff from kmem */ readstuff() { register i; if (!nl[NL_RBSIZE].n_value) { printf("%s: no value\n", nl[NL_RBSIZE].n_name); exit(1); } if (!nl[NL_STRST].n_value) { printf("%s: no value\n", nl[NL_STRST].n_name); exit(1); } # ifdef sun if (!nl[NL_NDBLKS].n_value) { printf("%s: no value\n", nl[NL_NDBLKS].n_name); # else if (!nl[NL_V].n_value) { printf("%s: no value\n", nl[NL_V].n_name); # endif exit(1); } if (!nl[NL_DBALLOC].n_value) { printf("%s: no value\n", nl[NL_DBALLOC].n_name); exit(1); } if (!nl[NL_NMBLOCK].n_value) { printf("%s: no value\n", nl[NL_NMBLOCK].n_name); exit(1); } if (lseek(fd, nl[NL_RBSIZE].n_value, 0) == -1) error("lseek"); if (read(fd, rbsize, sizeof(rbsize)) != sizeof(rbsize)) error("read"); # ifdef sun if (lseek(fd, nl[NL_NDBLKS].n_value, 0) == -1) error("lseek"); if (read(fd, cnt, sizeof(cnt)) != sizeof(cnt)) error("read"); # else if (lseek(fd, nl[NL_V].n_value, 0) == -1) error("lseek"); if (read(fd, &v, sizeof(v)) != sizeof(v)) error("read"); # endif # ifdef sun if (lseek(fd, nl[NL_DBALLOC].n_value, 0) == -1) error("lseek"); if (read(fd, &nl[NL_DBALLOC].n_value, sizeof(int)) != sizeof(int)) error("read"); # endif if (lseek(fd, nl[NL_DBALLOC].n_value, 0) == -1) error("lseek"); if (read(fd, dballoc, sizeof(dballoc)) != sizeof(dballoc)) error("read"); if (lseek(fd, nl[NL_NMBLOCK].n_value, 0) == -1) error("lseek"); if (read(fd, &nmblock, sizeof(nmblock)) != sizeof(nmblock)) error("read"); # ifdef sun if (lseek(fd, nl[NL_STRST].n_value, 0) == -1) error("lseek"); if (read(fd, &nl[NL_STRST].n_value, sizeof(int)) != sizeof(int)) error("read"); # endif } //E*O*F sw.c// echo x - term.h cat > "term.h" << '//E*O*F term.h//' # ifndef _TERM_H_ #include #include char *getenv(); char *tgetstr(); char PC; short ospeed; short lines; short cols; char ceolbuf[20]; char clbuf[20]; char pcbuf[20]; char cmbuf[20]; #undef putchar int putchar(); char term_buf[1024]; # endif _TERM_H_ //E*O*F term.h// echo x - termcap.c cat > "termcap.c" << '//E*O*F termcap.c//' /* * copyright (C) 1986 by Larry McVoy * MUST be distributed in source form only. */ # include "term.h" char* tgoto(); /*------------------------------------------------------------------15/Dec/86-* * init_term - read in the termcap stuff *----------------------------------------------------------------larry mcvoy-*/ termcap() { char *cp = getenv("TERM"); char *foo; char garbage[10]; struct sgttyb tty; gtty(1, &tty); ospeed = tty.sg_ospeed; if (cp == (char *) 0) return -1; if (tgetent(term_buf, cp) != 1) exit(1); foo = garbage; foo = tgetstr("pc", &foo); if (foo) PC = *foo; foo = clbuf; tgetstr("cl", &foo); foo = ceolbuf; tgetstr("ce", &foo); foo = cmbuf; tgetstr("cm", &foo); lines = tgetnum("li"); cols = tgetnum("co"); return 0; } /* clear to end of line */ ceol(col, row) { char *foo = tgoto(cmbuf, col, row); write(1, foo, strlen(foo)); tputs(ceolbuf, 1, putchar); } /* clear screen */ clear() { tputs(clbuf, lines, putchar); } /*------------------------------------------------------------------15/Dec/86-* * tputchar(c, col, row) - put a single char on the screen * * Inputs ----> (char), (int), (int) * * Bugs ------> Assumes that the coords make sense * * Revisions: *----------------------------------------------------------------larry mcvoy-*/ tputchar(c, col, row) char c; { register char* foo; foo = tgoto(cmbuf, col, row); tputs(foo, lines, putchar); write(1, &c, 1); } /*------------------------------------------------------------------15/Dec/86-* * tprint(s, col, row) - put a string on the screen * * Inputs ----> (char), (int), (int) * * Results ---> Puts the string out iff it will fit. * * Revisions: *----------------------------------------------------------------larry mcvoy-*/ tprint(s, col, row) register char* s; { register char* foo; if (row > lines || col > cols) return -1; if (strlen(s) > cols - col) return -2; foo = tgoto(cmbuf, col, row); tputs(foo, lines, putchar); return write(1, s, strlen(s)); } /* fake putchar for tputs */ putchar(c) char c; { write(1, &c, 1); } //E*O*F termcap.c// echo Possible errors detected by \'wc\' [hopefully none]: temp=/tmp/shar$$ trap "rm -f $temp; exit" 0 1 2 3 15 cat > $temp <<\!!! 17 53 336 Makefile 57 120 878 mode.c 63 359 2087 sw.1 563 1521 12403 sw.c 19 36 278 term.h 104 281 2203 termcap.c 823 2370 18185 total !!! wc Makefile mode.c sw.1 sw.c term.h termcap.c | sed 's=[^ ]*/==' | diff -b $temp - exit 0 --- Larry McVoy, Sun Microsystems (415) 336-7627 ...!sun!lm or lm@sun.com ----------------------------- From: iccad Subject: nested loops Date: 9 Aug 90 19:17:28 GMT To: unix-wizards@sem.brl.mil Hi, We are trying to write a Bourne shell script that includes two nested loops as follows !# /bin/sh this="one two three" that="four five six seven" them="eight nine ten" all="this that them" # for i in $all do for j in $`echo $i` do echo $i $j done done we want (and expected!) the output: this one this two this three that four that five that six that seven them eight them nine them ten The problem lies in the $`echo $i` statment the `echo $i` preforms as expected and the result is one of this, that, or them the $ infront of this statment however is taken as a literal $ and does not return the value of the variable this or that or them instead it returns $this or $that or $them. Does anybody know why this happens or how we can get the results that would be expected here (with the exception of doing it in a C shell or in a C program). Thanks. ----------------------------- From: Gilles Courcoux Subject: Re: nested loops Date: 10 Aug 90 16:15:51 GMT Sender: root@risky.convergent.com To: unix-wizards@sem.brl.mil In article <4103@herbie.misemi> you wrote: >The problem lies in the $`echo $i` statment Right, double variable expansion like that is resolved through the use of the eval(1) command as in : eval echo '$'$i When the shell read the command, it expands it into eval echo $them # the first time ! and then eval(1) do his job : evaluating its arguments, including variables expansion and then execute the command which is by now : echo one two three The echo(1) command is needed because eval(1) then exec(2)utes its first argument. Your script become : this="one two three" that="four five six seven" them="eight nine ten" all="this that them" # for i in $all do for j in `eval echo '$'$i` do echo $i $j done done Have a nice day, Gilles Courcoux E-mail: sun!pyramid!ctnews!pase60!gilles Unisys Network Computing Group Phone: (408) 435-7692 ----------------------------- From: Chet Ramey Subject: Re: nested loops Date: 10 Aug 90 19:28:41 GMT Sender: news@usenet.ins.cwru.edu To: unix-wizards@sem.brl.mil In article <4103@herbie.misemi> adley@herbie.misemi ( iccad) writes: $ !# /bin/sh $ this="one two three" $ that="four five six seven" $ them="eight nine ten" $ all="this that them" $ # $ for i in $all $ do $ for j in $`echo $i` $ do $ echo $i $j $ done $ done $ The problem lies in the $`echo $i` statment $ the `echo $i` preforms as expected and the result is one of this, $ that, or them $ the $ infront of this statment however is taken as a literal $ $ and does not return the value of the variable this or that or them $ instead it returns $this or $that or $them. Use `eval'. Chet -- Chet Ramey ``Levi Stubbs' tears run down Network Services Group his face...'' Case Western Reserve University chet@ins.CWRU.Edu ----------------------------- From: Mitch Wright Subject: waitpid() ??? Date: 10 Aug 90 04:20:07 GMT Sender: mitch@hq.af.mil To: unix-wizards@sem.brl.mil Greetings! I was recently flipping through the source of ksh(1), humbly admiring the work of David Korn, when I came across a function called waitpid(). I quickly grep'ed through the code to see if I could find where this function was defined, since I was not aware of a system call by this name. Well, I found no definition for this call in the code or in the few SYSV programming manuals that I have. Does anyone have an idea exactly what this call does? Since it is in the middle of the job control routines, I'd assume it was similar to wait3() in the Bezerkely world, but the parameters seem to be out of whack, and all three of them are integers instead of 1 int, 1 union wait *, and a struct rusage *. A man-page would be fine, but I'd prefer not only a man page, but a *real* description of what this puppy does. Thanks! -- ..mitch mitch@hq.af.mil (Mitch Wright) | The Pentagon, 1B1046 | (202) 695-0262 The two most common things in the universe are hydrogen and stupidity, but not necessarily in that order. ----------------------------- From: Boy named Superuser Subject: unix sys v - uptime question Date: 10 Aug 90 06:00:43 GMT To: unix-wizards@sem.brl.mil Does anyone out there know how to get Unix sys V/386 (sco) to display load averages. The man pages say that uptime "displays the load averages over 1 5 and 15 minutes" on "systems that maintain the necessary data." However, I cannot seem to find out how to get the system to keep the necessary data. Can anyone out there help? Thanks! root@storm.uucp@skinner.cs.uoregon.edu ----------------------------- From: Devon Tuck Subject: Interesting keyboard read problem (ioctl, function keys) Date: 10 Aug 90 08:10:33 GMT Sender: usenet@ucdavis.ucdavis.edu To: unix-wizards@sem.brl.mil Hey wizards, I have been working with an intersting problem... How to write a keyboard input routine that does not mess up its' transmission of repeated function keys. You might have noticed that even in vi, and in the C-shell, if you sit on an arrow key or some other function key that maps to a character sequence, you get intermittent beeps, or stray characters, respectively. I am porting an editor for a bunch of users who are in deep wedlock with their function keys, and they MUST be able to sit on their little arrow keys and not lose any characters, BUT character throughput must be VERY FAST. The problem is that this editor is very bulky, and spends too much time away from the keyboard input routine, so that if I do the logical thing and set VMIN=1 and VTIME=0, portions of the home key sequence ([H), for example, get split across network packets and arrive with too much gap for the keyboard driver to consider it a valid screen movement sequence. Has anyone solved this problem? I think I might have it with a routine that forks on its' first call, after setting up a pipe and ioctl calls, (VMIN=0, VTIME=0) and thus leaves a small subprocess running alongside the editor acting as a slave to the keyboard and sending all characters into a pipe to be read at the leasure of the main character input routine. How do other editors do it? How do Crisp, emacs, etc. handle this? (as I mentioned, vi doesn't..) Thanks, Devon Tuck tuck@iris.ucdavis.edu PS - Incidentally, when I use a straight character read with VMIN>=1, VTIME=1 the input is still too slow. ----------------------------- From: Steve Perryman Subject: sockets and signals (in C) Date: 10 Aug 90 08:45:16 GMT Sender: news@stl.stc.co.uk To: unix-wizards@sem.brl.mil Does anyone know of a way to set up a signal handler such that if a flood of data comes in to a socket, the SIGIO/SIGPOLL (maybe even SIGURG) signal can invoke a handler fast enough such that a variable can be incremented to represent the correct number of data items at the socket. The signal handler will be : void catch() { signal(SIGIO,catch) ; count++ ; ... /* Process the signal */ ... } I've used fcntl to allow the socket to interrupt : fcntl(sock,F_SETOWN,getpid()) ; fcntl(sock,F_SETFL,F_ASYNC) ; ... ... This works but it can't log the correct number of items received if they come in as bursts of data (5+ items per burst). Can this timing problem be resolved using SIGIO , or is another way required ??? skp ----------------------------- From: Larry McVoy Subject: Re: sockets and signals (in C) Date: 10 Aug 90 18:49:12 GMT Sender: news@sun.eng.sun.com To: unix-wizards@sem.brl.mil In article <3304@stl.stc.co.uk> "Steve Perryman " writes: > >Does anyone know of a way to set up a signal handler such that if a flood >of data comes in to a socket, the SIGIO/SIGPOLL (maybe even SIGURG) signal >can invoke a handler fast enough such that a variable can be incremented to >represent the correct number of data items at the socket. > >This works but it can't log the correct number of items received if they come >in as bursts of data (5+ items per burst). Can this timing problem be resolved >using SIGIO , or is another way required ??? This can't be done with Unix signals. Unix signals don't stack, i.e., if you hit yout interrupt character several times before the kernel delivers the signal, the application will only see one signal. About the best you can do for you application is to use sigio as a hint that there is data waiting and schedule a timeout every second or so to collect what you might have missed. It's also a good idea to code your processing like so: for ( ;; ) { sigpause(0); while (more_data()) { process_data(); } } rather than for ( ;; ) { sigpause(0); if (more_data()) { process_data(); } } --- Larry McVoy, Sun Microsystems (415) 336-7627 ...!sun!lm or lm@sun.com ----------------------------- From: Kishore Seshadri Subject: Re: Re.: UNdeleting files Date: 10 Aug 90 14:51:06 GMT Sender: news@inews.intel.com To: unix-wizards@sem.brl.mil In article <7410002@hpfcmgw.HP.COM>, munir@hpfcmgw (Munir Mallal) writes: >>>A similar thing has just happened here, and we don't have fsdb either. >>>The machine has been untouched since the directory was deleted. >>>Any suggestions ? >> > >Whether done with fsdb or not, the task is to read the disk > >partition block by block, check each block to determine whether > >it's part of the data to be recovered, and reassemble the recovered > >blocks. > >You can use adb if you have it, but will have to do a lot of math to determine >offsets etc. > I have a binary file modifier called fm that I pulled off comp.sources.misc that can be used to edit devices and binary files. Once again if you do the math beforehand this program may be of help in this situation. The devices can be edited in either hex or ascii modes and simple string searches can be handled. You should probably have a good understanding of the way the file system has been implemented before fooling with this. Kishore Seshadri ---------------------------------------------------------------------------- Kishore Seshadri or <..!intelca!mipos3!kseshadr> "The nice thing about standards is that you have so many to choose from." ----------------------------- From: Scott McGregor Subject: seeking information about file system details. Date: 10 Aug 90 17:12:33 GMT Sender: news@athertn.atherton.com To: unix-wizards@sem.brl.mil I am curious as to how accesses to multiple concurrent types of file systems are implemented under SysV and BSD. I've read the Bach book and the BSD book, as well as books on device drivers. But what I am more interested in is at the switchable file system layer. Explanations of what goes on in the following example are welcome, recommendations of books that cover this stuff is even more heartily desired. I know that mount takes a file type. I know how the file system tree is traced using inodes, and I have heard of vnodes (which is what I think I want to know more about) but I haven't found anything written on vnodes. I am aware that several vendors support multiple varieties of file systems (Bell, BSD, NFS, MS-DOS) all accessable on the same system, and the files on them can be accessed using standard o/s calls and stdio library routines. I guess what I am interested in is if I have a non-unix file system and I want to allow the this file system to be mounted as a unix file system, and accessed using open, creat, read, write, close, et al, what interface translators would I have to create between my own file system and the unix system calls, and how and where would I add typically add these translators. I presume that a new type would have to be tested for in mount, and that the open, etc. commands would have to know what type of file system they were operating on and that a case statement switch would have to be supported by them for each new type of file system to be supported. Is this correct, or is there some other way that the switching between file systems is handled. Mail can be directed to: mcgregor@atherton.com or ...!sun!atherton!mcgregor Scott McGregor Atherton Technology ----------------------------- From: Chris Bertin Subject: evaluating ${10} and above in sh/ksh Keywords: sh, ksh, eval Date: 10 Aug 90 17:58:37 GMT To: unix-wizards@sem.brl.mil There doesn't seem to be a way, in sh or ksh, to evaluate $10 and higher. $10 and higher are evaluated as ${1}0, ${1}1, etc... instead of ${10}, ${11}, etc... I have tried many different ways and they all fail. Do you know one that will work? #! /bin/sh set a b c d e f g h i j k l arg=0 while [ $arg -le $# ]; do echo "evaluating \$$arg" eval echo $"$arg" eval echo $"${arg}" eval echo "$`eval echo $arg`" # Now, some of the crazy things I tried. # ( The parens are there when eval causes an error ) echo "\${$arg} results in \c" ( eval echo "\${$arg}" ) echo "$`echo '{'``eval echo $arg``echo '}'` results in \c" ( eval echo "$`echo '{'``eval echo $arg``echo '}'`" ) arg=`expr $arg + 1` done -- Chris Bertin | chrisb@risky.Convergent.COM Unisys | or (408) 435-3762 | ...!uunet!pyramid!ctnews!risky!chrisb ----------------------------- From: Chet Ramey Subject: Re: How variables can be specified as arguments Date: 10 Aug 90 19:24:41 GMT Sender: news@usenet.ins.cwru.edu To: unix-wizards@sem.brl.mil In article <7298@helios.TAMU.EDU> skdutta@cs.tamu.edu (Saumen K Dutta) writes: $ read_KEY1 "key" $ $ should define a new variable called key and $ assigns it's value according to what user types. $ $ I am not able to solve this ! Please help me Use `eval'. Chet -- Chet Ramey ``Levi Stubbs' tears run down Network Services Group his face...'' Case Western Reserve University chet@ins.CWRU.Edu ----------------------------- From: Guy Harris Subject: Re: ln -f Date: 10 Aug 90 20:19:01 GMT To: unix-wizards@sem.brl.mil >Why don't the versions of ln that you know of on 4.3 BSD and SunOS 4 >use the rename system call? Because they're named "ln", not "mv". "rename()" is *NOT* an atomic operation that removes the target and makes an *additional* link from the source with the name of the target. It's an atomic operation that *renames* the source to the target, and if it succeeds does *not* leave the source behind. ----------------------------- From: "David J. MacKenzie" Subject: Re: ln -f Date: 10 Aug 90 22:54:43 GMT Sender: The News System To: unix-wizards@sem.brl.mil > Why don't the versions of ln that you know of on 4.3 BSD and SunOS 4 > use the rename system call? Because rename doesn't do the same thing as ln. If before you run ln, the file has n links, after you run ln successfully the file will have n + 1 links. If you just rename the file, it will still have n links, but one of them will be different from before. -- David J. MacKenzie ----------------------------- End of UNIX-WIZARDS Digest **************************