home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-01-25 | 39.2 KB | 1,429 lines |
- Newsgroups: alt.hackers
- Path: sparky!uunet!zaphod.mps.ohio-state.edu!sol.ctr.columbia.edu!news.cs.columbia.edu!news!bm
- From: bm@shadow.columbia.edu (Blair MacIntyre)
- Subject: Re: .plan pipe to backfinger.
- In-Reply-To: gezelter@neon.cchem.berkeley.edu's message of 25 Jan 1993 22:12:36 GMT
- Message-ID: <C1Fy82.Lqx@cs.columbia.edu>
- Sender: news@cs.columbia.edu (The Daily News)
- Reply-To: Blair MacIntyre <bm@cs.columbia.edu>
- Organization: Columbia University
- References: <1k1okk$beu@agate.berkeley.edu>
- Date: Tue, 26 Jan 1993 03:12:01 GMT
- Approved: ack.
- Lines: 1414
-
- >>>>> On 25 Jan 1993 22:12:36 GMT, gezelter@neon.cchem.berkeley.edu (Dan
- >>>>> Gezelter) said:
-
- dan> Here's the latest version of the .plan pipe program that I've
- dan> inherited from numerous other people.
-
- I have a similar .plan pipe program (based on a simple version by Rich
- Salz which was modified and given to me by my old officemate Hamish
- MacDonald, which I then hacked to death) which uses TCL to parse a
- .planinit file in the users home dir and execute a certain function
- within it to create the output for the .plan
-
- There is no documentation, but it seems fairly clean. Like Dan, I
- haven't used this in a while in the FIFO version, since we are NFS'd
- like crazy here and pipes don't dig NFS access. However, a compile time
- switch allows it to become a program which rewrites your .plan every N
- seconds (which is what I currently use.)
-
- If anyone wants to play with it, I make no guarantees. There are two
- sample .planinit files in here, which you should be able to get the
- right idea from. And, of course, you need to grab a copy of TCL from
- somewhere. Nothing that's a problem for a hacker ...
-
- It currently compiles to the non-FIFO version, so the trivial change to
- get it to compile the FIFO version is left as an exercise to the reader.
-
- Have fun. If you do anything cool with it, let me know! (like
- figuring out how to do a complete ID of people fingering you)
-
- ----snippity snip----
- : This is a shar archive. Extract with sh, not csh.
- : The rest of this file will extract:
- :
- : .planinit
- : .planinit2
- : Makefile
- : plan_proto.h
- : plantcl.c
- : tcl_cmds.c
- : tcl_cmds.h
- : uniqueproc.c
- :
- echo x - .planinit
- sed 's/^X//' > .planinit << '//go.sysin dd *'
- Xproc time12 hour24 {
- X if {($hour24 % 12) == 0} \
- X {return [format 12]} \
- X else \
- X {return [expr {$hour24 % 12}]}
- X}
- X
- Xproc timeampm hour24 {
- X if {($hour24 < 12) || ($hour24 == 24)} \
- X {return am} \
- X else \
- X {return pm}
- X}
- X
- Xproc timestr hour24 {
- X set ampm [timeampm $hour24]
- X case $hour24 in \
- X {0 24} {return [format midnight]} \
- X {12} {return [format noon]} \
- X default {return [format "%d o'clock %s" [time12 $hour24] $ampm]}
- X}
- X
- Xproc daysuffix monthday {
- X case $monthday in \
- X {1 21 31} {return st} \
- X {2 22 32} {return nd} \
- X {3 23 33} {return rd} \
- X default {return th}
- X}
- X
- Xproc getload {} {
- X global _load _load1 _load5 _load15
- X
- X scan [exec loadaverage] "%*d %*d %*d %f %f %f" _load1 _load5 _load15
- X
- X set _load [format "%.2f (%.2f, %.2f)" $_load1 $_load5 $_load15]
- X
- X set _load1 [format "%.2f" $_load1]
- X set _load5 [format "%.2f" $_load5]
- X set _load15 [format "%.2f" $_load15]
- X}
- X
- Xproc timecomment {hour24 minute} {
- X set hour12 [time12 $hour24]
- X set ampm [timeampm $hour24]
- X
- X proc ecomment {epsilon} {
- X case $epsilon in \
- X {0 1} {return "almost "} \
- X {2 4} {return "around "} \
- X {3} {return ""}
- X }
- X
- X set fiveminute [expr {(($minute + 3) / 5) * 5}]
- X set e [expr {($minute + 3) % 5}]
- X
- X # first do the 15 minute intervals, then do the rest
- X
- X if {$fiveminute == 0} \
- X {return [format "%s%s" [ecomment $e] [timestr $hour24]]} \
- X else { if {$fiveminute == 15} \
- X {return [format "%squarter after %s (%s)" [ecomment $e] $hour12 $ampm]} \
- X else { if {$fiveminute == 30} \
- X {return [format "%shalf past %s (%s)" [ecomment $e] $hour12 $ampm]} \
- X else { if {$fiveminute == 45} \
- X {return [format "%squarter to %s (%s)" [ecomment $e] \
- X [expr {($hour24 % 12) + 1}] $ampm]} \
- X else { if {$fiveminute == 60} \
- X {return [format "%s%s" [ecomment $e] \
- X [timestr [expr {$hour24 + 1}]]]} \
- X else {if {$minute < 30} \
- X {return [format "%s%d after %s (%s)" [ecomment $e] \
- X $fiveminute $hour12 $ampm]} \
- X {return [format "%s%d to %s (%s)" [ecomment $e] \
- X [expr {60 - $fiveminute}] [expr {($hour24 % 12) + 1}] $ampm]} \
- X }}}}}
- X}
- X
- Xset fingercount 0
- X
- Xproc main {} {
- X global _year _month _day _hour12 _hour24 _minute _second fingercount\
- X _weekdaystring _monthstring
- X
- X set fingercount [expr {$fingercount + 1}]
- X
- X done
- X
- X# echo -n Thesis:
- X# echo [fill 8 75 -h Computer Aided Colour Selection for People Who Have
- X# Better Things to Do With Their Time Than Play With Colour.]
- X
- X # **** OLD Code, kept around for the heck of it, in case I reuse it ***
- X
- X #set host [toupper [getenv SHORTHOST]]
- X #getload
- X
- X #echo -n Commentary:\
- X #fill 12 75 -h It's $comment here in Waterloo. \ etc etc etc
- X
- X #set netstat [exec grep "128.84.237" < [exec netstat -n]]
- X #set netstat [exec netstat -n]
- X #echo $netstat
- X #set cornell [string match "* 128.84.237.*" $netstat]
- X #echo $cornell
- X #if {$cornell == 1} {echo "(Katy, you deadbeat, get to work! Like me!)"}
- X #if {$cornell >= 0} {echo $cornell [index $netstat $cornell]}
- X
- X #echo \nFortune #$fingercount:
- X #echo [exec fortune -s]
- X
- X set comment [format "Local Time: %s" [timecomment $_hour24 $_minute]]
- X echo -n $comment
- X set tabchars ""
- X
- X set commentlength [length $comment chars]
- X set tabs [expr {(38 - $commentlength) / 8 + 1}]
- X #echo $commentlength $tabs
- X for {} {$tabs > 0} {set tabs [expr {$tabs - 1}]} \
- X {set tabchars [format "%s\t" $tabchars]}
- X
- X echo [format "%s%s" $tabchars Date:] $_weekdaystring, the \
- X [format "%d%s" $_day [daysuffix $_day]] of $_monthstring
- X
- X# set _sked [exec month -B1]
- X# if {[length $_sked] > 0} \
- X# { set temp1 [range $_sked 2 end]
- X# set length1 [expr {[length $temp1 chars] - 3}]
- X# echo Schedule for today: \n " " [range $temp1 0 $length1 chars]
- X# } \
- X# {
- X# echo Nothing scheduled for today.
- X# }
- X
- X# echo \nAnswer this skill testing question and win valuable prizes!
- X# echo \t\t\t ( $fingercount * \
- X# [expr {(($_day * ($_second + 1)) * ($fingercount)) % 137 + 1}] + \
- X# [expr {$_year % ($_second + 10) + 1}] ) / \
- X# [expr {($_hour24 * $fingercount * ($_second + 1)) % 23 + 1}]
- X
- X# echo "\nCurrent State of the Thesis:"
- X# echo [exec cat /u/bmacinty/.thesistoc]
- X# echo " "
- X# echo [fill 4 74 As my above finger info shows, I am not longer
- X# gracing the halls of the DC. I am now in the Big Apple,
- X# doing a PhD at Columbia University. My address is]
- X# echo "\t435 W 119th St. Apt. 4B\n\tNew York, NY, 10027"
- X# echo "\n\tPhone: 212-932-1911"
- X# echo [fill 4 74 If you are in new York, phone me and we can get
- X# together.]
- X# echo " "
- X#
- X# echo
- X# echo [fill 0 65 I'll be at Cornell for the weekend. If you
- X# need me, I'll be at (607) 277-1788. Of course, I'll log on
- X# as much as possible.]
- X
- X echo \nRandom Space Filling Quotation:
- X echo [exec fortune -s]
- X
- X set cc [exec randterm dummyarg]
- X # this shit to get around the ld.so: warning!
- X if {([string match "ld.so:" [index $cc 0]]) == 1} {
- X set cc [range $cc 9 end]
- X }
- X set colour1 [index $cc 3]
- X set colour1v [format "(%d,%d,%d)"
- X [index $cc 0] [index $cc 1] [index $cc 2]]
- X set colour1f [index $cc 4]
- X
- X set colour2 [index $cc 8]
- X set colour2v [format "(%d,%d,%d)"
- X [index $cc 5] [index $cc 6] [index $cc 7]]
- X set colour2f [index $cc 9]
- X
- X echo "Scientifically Selected Colour Scheme for the Aesthetically Challenged:"
- X echo [fill 4 74 $colour1 $colour1v text on a field of
- X $colour2 $colour2v. This gives a luminance contrast of about
- X [index $cc 10]% on a standard NTSC display.]
- X echo Try it out like this:
- X echo [format " xterm -fg %s -bg %s" $colour1f $colour2f ]
- X}
- X
- Xproc done {} {
- X echo [ fill 2 75 I'm a Phd student in graphics, advised by Steven \
- X Feiner. This term's fun includes TAing CS4160, Computer Graphics. \
- X Office hours are Tuesday and Wednesday, 11 till 12. I'm also \
- X thinking of taking the software qual.\n]
- X
- X echo [ fill 2 75 I live in 1122D Fairchild right now, phone x43614. \
- X The phone number in the graphics lab x48699.\n]
- X
- X echo [ fill 2 75 My home phone number is 222-5315, but don't bother \
- X trying to reach me there, since I'm usually not at home. \
- X Email is your best bet.\n]
- X}
- //go.sysin dd *
- echo x - .planinit2
- sed 's/^X//' > .planinit2 << '//go.sysin dd *'
- Xproc time12 hour24 {
- X if {($hour24 % 12) == 0} \
- X {return [format 12]} \
- X else \
- X {return [expr {$hour24 % 12}]}
- X}
- X
- Xproc timestr hour24 {
- X case $hour24 in \
- X {0 24} {return [format midnight]} \
- X {12} {return [format noon]} \
- X default {return [format "%d o'clock" [time12 $hour24]]}
- X}
- X
- Xproc daysuffix monthday {
- X case {$monthday} in \
- X {1 21 31} {return st} \
- X {2 22 32} {return nd} \
- X {3 23 33} {return rd} \
- X default {return th}
- X}
- X
- Xproc getload {} {
- X global _load _load1 _load5 _load15
- X
- X scan [exec loadaverage] "%*d %*d %*d %f %f %f" _load1 _load5 _load15
- X
- X set _load [format "%.2f (%.2f, %.2f)" $_load1 $_load5 $_load15]
- X
- X set _load1 [format "%.2f" $_load1]
- X set _load5 [format "%.2f" $_load5]
- X set _load15 [format "%.2f" $_load15]
- X}
- X
- Xproc timecomment {hour24 minute} {
- X set hour12 [time12 $hour24]
- X
- X proc ecomment {epsilon} {
- X case $epsilon in \
- X {0 1} {return "almost "} \
- X {2 4} {return "around "} \
- X {3} {return ""}
- X }
- X
- X set fiveminute [expr {(($minute + 3) / 5) * 5}]
- X set e [expr {($minute + 3) % 5}]
- X
- X # first do the 15 minute intervals, then do the rest
- X
- X if {$fiveminute == 0} \
- X {return [format "%s%s" [ecomment $e] [timestr $hour24]]} \
- X else { if {$fiveminute == 15} \
- X {return [format "%squarter after %s" [ecomment $e] $hour12]} \
- X else { if {$fiveminute == 30} \
- X {return [format "%shalf past %s" [ecomment $e] $hour12]} \
- X else { if {$fiveminute == 45} \
- X {return [format "%squarter to %s" [ecomment $e] \
- X [expr {($hour24 % 12) + 1}]]} \
- X else { if {$fiveminute == 60} \
- X {return [format "%s%s" [ecomment $e] \
- X [timestr [expr {$hour24 + 1}]]]} \
- X else {if {$minute < 30} \
- X {return [format "%s%d after %s" [ecomment $e] \
- X $fiveminute $hour12]} \
- X {return [format "%s%d to %s" [ecomment $e] \
- X [expr {60 - $fiveminute}] [expr {($hour24 % 12) + 1}]]} \
- X }}}}}
- X}
- X
- Xproc main {} {
- X global _year _month _day _hour12 _hour24 _minute _second _fingercount \
- X _weekdaystring _monthstring
- X echo To actually do some work this term ... and keep my plan up to date!
- X echo Skill Testing Question: \
- X [expr {$_year % $_fingercount + 1}] * \
- X [expr {($_day * ($_second + 1) * ($_month + 10) * ($_minute + 1)) % $_fingercount + 1}] + \
- X [expr {$_year % ($_second + 1) + 1}] / \
- X [expr {(($_hour24 * $_fingercount) % $_second) + 1}]
- X
- X #for {set i 0} {$i < 60} {set i [expr {$i+1}]} {echo [timecomment 4 $i]}
- X #set comment [timecomment $_hour24 $_minute]
- X #set host [toupper [getenv SHORTHOST]]
- X #getload
- X
- X #echo -n Commentary:\
- X #fill 12 75 -h It's $comment here in Waterloo. \ etc etc etc
- X
- X set comment [format "Local Time: %s" [timecomment $_hour24 $_minute]]
- X echo -n $comment
- X set tabchars ""
- X
- X set fred [length $comment chars]
- X set tabs [expr {(38 - $fred) / 8 + 1}]
- X #echo $fred $tabs
- X for {} {$tabs > 0} {set tabs [expr {$tabs - 1}]} \
- X {set tabchars [format "%s\t" $tabchars]}
- X
- X echo [format "%s%s" $tabchars Date:] $_weekdaystring, the \
- X [format "%d%s" $_day [daysuffix $_day]] of $_monthstring
- X
- X set _sked [exec month -B1]
- X if {[length $_sked] > 0} \
- X { set temp1 [range $_sked 2 end]
- X set length1 [expr {[length $temp1 chars] - 3}]
- X echo Schedule for today: \n " " [range $temp1 0 $length1 chars]
- X } \
- X { echo Nothing scheduled for today. }
- X
- X #set netstat [exec grep "128.84.237" < [exec netstat -n]]
- X set netstat [exec netstat -n]
- X #echo $netstat
- X set cornell [string match "* 128.84.237.*" $netstat]
- X #echo $cornell
- X if {$cornell == 1} {echo "(Katy, you deadbeat, get to work! Like me!)"}
- X #if {$cornell >= 0} {echo $cornell [index $netstat $cornell]}
- X}
- //go.sysin dd *
- echo x - Makefile
- sed 's/^X//' > Makefile << '//go.sysin dd *'
- XTCLOBJS = plantcl.o tcl_cmds.o
- X#uniqueproc.o
- XCC = gcc
- XCFLAGS = -O -g -I${TCLINCLUDE} -Wall
- XTCLLIBSDIR = /u/foria/bm/lib
- XTCLINCLUDE = /u/foria/bm/include
- X
- Xtclplan : ${TCLOBJS}
- X gcc -o tclplan ${CFLAGS} ${TCLOBJS} -L${TCLLIBSDIR} -ltcl
- X
- Xlexplan : ${OLDOBJS}
- X gcc -o lexplan ${CFLAGS} ${OLDOBJS}
- X
- Xplanmain.o : plan.h
- X
- Xplantcl.o : plantcl.c tcl_cmds.h plan_proto.h ${TCLINCLUDE}/tcl.h
- X
- Xuniqueproc.o : uniqueproc.c
- X
- Xtcl_cmds.o : tcl_cmds.c ${TCLINCLUDE}/tcl.h
- X
- Xlex.yy.o : lex.yy.c plan.h
- X
- Xlex.yy.c : plan.l
- X flex -i plan.l
- X
- Xclean:
- X rm -f ${TCLOBJS} ${OLDOBJS} tclplan lexplan
- //go.sysin dd *
- echo x - plan_proto.h
- sed 's/^X//' > plan_proto.h << '//go.sysin dd *'
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/time.h>
- X#include <sys/file.h>
- X#include <sgtty.h>
- X#include <signal.h>
- X#include <errno.h>
- X#include <string.h>
- X#include <ctype.h>
- X#include "tcl.h"
- X
- Xextern int puts();
- Xextern int stat(char*, struct stat*);
- X
- Xextern char getopt(int, char**, const char*);
- Xextern char *getenv(const char*);
- Xextern int chdir(const char*);
- Xextern int unlink(const char*);
- Xextern int mknod(const char*, int, int);
- Xextern int access(const char*, int);
- Xextern int select(int, fd_set*,fd_set*,fd_set*,struct timeval*);
- Xextern int fprintf(FILE*, char*,...);
- X#if !defined(sun)
- Xextern int umask(int);
- X#endif SUN4_1
- Xextern int fclose(FILE*);
- Xextern int getppid(void), getpid(void);
- Xextern int getpgrp(int);
- Xextern FILE *popen(const char*, const char*);
- Xextern int pclose(FILE*), fscanf(FILE*,const char*,...);
- Xextern int fork(void);
- Xextern int setpgrp(int,int);
- Xextern int ioctl(int,int,void*);
- Xextern int close(int);
- Xextern void perror(const char*);
- Xextern void fputs(const char*, FILE*);
- Xextern void sleep(unsigned int);
- Xextern void bzero(void*,int);
- Xextern int fread(void*,unsigned,unsigned,FILE*);
- Xextern int dup2(int,int);
- Xextern int open(char*, int,int);
- X
- Xextern int unique_proc();
- //go.sysin dd *
- echo x - plantcl.c
- sed 's/^X//' > plantcl.c << '//go.sysin dd *'
- X/* -*- Mode: c -*-
- X * plantcl.c -- the mainline for my tcl-based dynamic plan program
- X * Author : Blair MacIntyre
- X * Last Modified By: Blair MacIntyre
- X * Last Modified On: Wed Apr 15 13:49:59 1992
- X * Update Count : 446
- X * Status : Version 3.
- X *
- X * $Source: /u/foria/bm/src/plan/RCS/plantcl.c,v $
- X * $Date: 1992/04/15 17:50:44 $
- X * $Author: bm $
- X * $Revision: 1.12 $
- X */
- X
- X/*
- X** A process to create dynamic .plan files. Two programs in one:
- X** 1) Creates a fifo, waits for someone to connect to it. Redo .plan info
- X** each time.
- X** 2) Runs in the background and rewrites the plan file evey N seconds.
- X** Needed for NFS environments, since fifo's can't be read over NFS.
- X**
- X** Original version: Rich Salz
- X** Prints out the time, and a guess-timate of the temperature,
- X** based on the day of the year and the time.
- X**
- X** Major Revision: (Blair MacIntyre, Oct 1, 1990)
- X** Accepts a configuration file
- X**
- X** Major Revision: (Blair MacIntyre, April 11, 1992)
- X** Doesn't have to use a fifo. Seems like a step backwards toward the dark
- X** ages, but they use NFS for everything here at Columbia.
- X*/
- X
- X#include <stdio.h>
- X#include <stdlib.h>
- X#include <sys/file.h>
- X#include "plan_proto.h"
- X#include "tcl_cmds.h"
- X
- X/* beats the heck out of me why these aren't prototyped */
- Xint rename(char*, char*);
- Xint flock(int, int);
- X
- X/* default FIFO name and initialization files */
- X#define PLAN ".plan"
- X#define PLANINIT ".planinit"
- X
- X/* various defines for variable contents */
- X#define TIME_DEFAULT "%2d:%02d:%02d"
- X#define DATE_DEFAULT "%d %.3s %d"
- X#define INFO_DEFAULT "proc main {} {\n\
- X global _time _date\n\
- X echo \"I've got the time ....\"\n\
- X echo \"Time: $_time \t\t\tDate: $_date\"\n\
- X }\n"
- X#define INFO_ERROR "proc main {} {\n\
- X global _time _date errorInfo\n\
- X echo \" Plan init file contained an error near:\"\n\
- X echo $errorInfo\n\
- X echo \"Time: $_time \t\t\tDate: $_date\"\n\
- X }\n"
- X#define INFO_READ_ERROR "proc main {} {\n\
- X global _time _date\n\
- X echo \" Error Reading plan init file.\"\n\
- X echo \"Time: $_time \t\t\tDate: $_date\"\n\
- X }\n"
- X#define INFO_NOMAIN "proc main {} {\n\
- X global _time _date\n\
- X echo \" Plan init file did not define a 'main' procedure.\"\n\
- X echo \"Time: $_time \t\t\tDate: $_date\"\n\
- X }\n"
- X
- X#define INFO_NO_DONE "proc done {} {\n\
- X echo \"Plan? Plan? We don't need no stinking plan!\"\
- X }\n"
- X
- X#ifndef FIFO
- X/* the default amount of time to sleep between plan file recreates (2 minues)*/
- X#define DEFAULT_SLEEP_TIME (120)
- X#endif
- X
- X/* global variables */
- Xstatic char *fifo = NULL;
- Xstatic char lockname[255];
- Xstatic char* tempfile;
- Xstatic char lockfd;
- X
- XFILE *FingerOutput; /* needed in tcl_cmds.c */
- X
- Xstatic Tcl_Interp *my_interp;
- Xstatic void Setup();
- Xstatic Tcl_Interp *GetConfig(char *, int);
- Xstatic void SetState(Tcl_Interp *interp);
- X
- X/***********************************************************************
- X * general Exit routine
- X ***********************************************************************/
- Xint Exit(void)
- X{
- X int fd;
- X int result;
- X
- X /* Close and remove the current FingerOutput tempfile */
- X (void)fclose(FingerOutput);
- X if (unlink(tempfile) < 0 && errno != ENOENT) {
- X perror("Can't unlink tempfile");
- X }
- X
- X /* Remove the lockfile */
- X close(lockfd);
- X if (unlink(lockname) < 0 && errno != ENOENT) {
- X perror("Can't unlink lockfile");
- X }
- X
- X#ifdef FIFO
- X /* Remove the FIFO. */
- X if (unlink(fifo) < 0 && errno != ENOENT) {
- X perror("Can't unlink");
- X exit(1);
- X }
- X#endif
- X
- X /* Open the fifo for writing. Attempt to create a simple file, so there
- X is something reasonable left lying around when we are gone */
- X if ((FingerOutput = fopen(fifo, "w")) == NULL) {
- X perror("Can't fopen");
- X exit(1);
- X }
- X fd = fileno(FingerOutput);
- X
- X /* execute the TCL "done" procedure to (presumably) dump a final message */
- X SetState(my_interp);
- X result = Tcl_Eval(my_interp, "done", 0, NULL);
- X if (result == TCL_OK) {
- X if (*my_interp->result != 0) {
- X fprintf(FingerOutput, "TCL Result: %s\n", my_interp->result);
- X }
- X } else {
- X if (result == TCL_ERROR) {
- X fprintf(FingerOutput, "TCL Error");
- X } else {
- X fprintf(FingerOutput, "TCL Error %d", result);
- X }
- X if (*my_interp->result != 0) {
- X fprintf(FingerOutput, ": %s\n", my_interp->result);
- X } else {
- X fprintf(FingerOutput, "\n");
- X }
- X }
- X
- X /* Close it */
- X (void)fclose(FingerOutput);
- X
- X exit(0);
- X /*NOTREACHED*/
- X return 0;
- X}
- X
- X/***********************************************************************
- X * read the config file into Config_buffer and Tcl_Eval it.
- X ***********************************************************************/
- XTcl_Interp *GetConfig(char *initfile, int filesize)
- X{
- X int count, result;
- X FILE *ConfigFile = fopen(initfile, "r");
- X Tcl_Interp *interp = NULL;
- X char *Config_buffer = NULL;
- X
- X /*
- X * initialize the TCL interpretter and add our custom functions
- X */
- X interp = Tcl_CreateInterp();
- X Tcl_CreateCommand(interp, "getenv", cmdGetEnv, (ClientData) 0, 0);
- X Tcl_CreateCommand(interp, "echo", cmdEcho, (ClientData) 0, 0);
- X Tcl_CreateCommand(interp, "toupper", cmdToUpper, (ClientData) 0, 0);
- X Tcl_CreateCommand(interp, "tolower", cmdToLower, (ClientData) 0, 0);
- X Tcl_CreateCommand(interp, "fill", cmdFill, (ClientData) 0, 0);
- X
- X /*
- X * we must do this so that our variables are always defined, even the
- X * first time the init file is executed
- X */
- X SetState(interp);
- X
- X /* use default plan */
- X if (!ConfigFile) {
- X (void)Tcl_Eval(interp, INFO_DEFAULT, 0, NULL);
- X (void)Tcl_Eval(interp, INFO_NO_DONE, 0, NULL);
- X }
- X else
- X {
- X Config_buffer = malloc(filesize+1);
- X count = fread(Config_buffer, sizeof(char), filesize, ConfigFile);
- X if (count == 0)
- X {
- X (void)Tcl_Eval(interp, INFO_READ_ERROR, 0, NULL);
- X (void)Tcl_Eval(interp, INFO_NO_DONE, 0, NULL);
- X }
- X else
- X {
- X Config_buffer[count] = '\0';
- X result = Tcl_Eval(interp, Config_buffer, 0, NULL);
- X if (result == TCL_OK) {
- X /* check for main */
- X result = Tcl_Eval(interp, "info procs main", 0, NULL);
- X
- X if (result == TCL_OK && strcmp(interp->result,"main") != 0) {
- X /* no main procedure defined */
- X (void)Tcl_Eval(interp, INFO_NOMAIN, 0, NULL);
- X }
- X
- X /* check for done */
- X result = Tcl_Eval(interp, "info procs done", 0, NULL);
- X
- X if (result == TCL_OK && strcmp(interp->result,"done") != 0) {
- X /* no done procedure defined */
- X (void)Tcl_Eval(interp, INFO_NO_DONE, 0, NULL);
- X }
- X } else {
- X (void)Tcl_Eval(interp, INFO_ERROR, 0, NULL);
- X (void)Tcl_Eval(interp, INFO_NO_DONE, 0, NULL);
- X }
- X }
- X
- X free(Config_buffer);
- X fclose(ConfigFile);
- X
- X } /* if */
- X
- X return interp;
- X}
- X
- X/***********************************************************************
- X * This function sets up signal handlers for the HUP and TERM signals.
- X * The signal handlers remove the named pipe and exit, rewriting a simple
- X * .plan on exit.
- X * This function sets up ignoring of INT, PIPE and QUIT signals.
- X * It also ensure that the forked process is in the process group of
- X * the parent.
- X ***********************************************************************/
- Xvoid Setup()
- X{
- X int pid,fd;
- X
- X /*
- X * Arrange for handling or ignoring of signals
- X */
- X signal( SIGTERM, Exit );
- X signal( SIGPIPE, SIG_IGN );
- X signal( SIGHUP, SIG_IGN );
- X signal( SIGINT, SIG_IGN );
- X signal( SIGQUIT, SIG_IGN );
- X
- X /* fork.. the parent dies, the child lives on */
- X#ifndef DEBUG
- X switch( fork() )
- X {
- X case -1: /* fail */
- X /* fork failed */
- X perror( "fork" );
- X Exit();
- X break;
- X
- X case 0: /* child */
- X#ifdef FIFO
- X /*
- X * If the FIFO exists, unlink it.
- X */
- X if (access(fifo,F_OK) == 0)
- X {
- X (void)unlink(fifo);
- X }
- X
- X (void)umask(0);
- X if (mkfifo(fifo, (mode_t)0644) < 0)
- X {
- X perror("Can't mknod");
- X Exit();
- X }
- X#else
- X /* see if we can write to the .plan file */
- X if (access(fifo,W_OK))
- X {
- X if (errno != ENOENT)
- X {
- X perror("can't write to file");
- X Exit();
- X }
- X }
- X#endif
- X pid = getpid();
- X
- X if( setpgrp(0,pid) < 0 )
- X {
- X perror( "setpgrp" );
- X Exit();
- X }
- X
- X /* disassociate controlling terminal */
- X if( (fd = open( "/dev/tty", O_RDONLY, 0 ) ) == -1 ) {
- X perror( "open /dev/tty" );
- X Exit();
- X }
- X
- X if( ioctl( fd, TIOCNOTTY, 0 ) == -1 ) {
- X perror( "ioctl" );
- X }
- X
- X close( fd );
- X
- X /*
- X * close the I/O files opened by C and redirect them to /dev/null
- X * for TCL.
- X */
- X close(0);
- X close(1);
- X close(2);
- X
- X if (fd = open("/dev/null", O_RDWR, 0) == -1)
- X {
- X perror( "open /dev/null");
- X Exit();
- X }
- X
- X if (dup2(fd,0) == -1)
- X {
- X perror( "dup2 stdin");
- X Exit();
- X }
- X
- X if (dup2(fd,1) == -1)
- X {
- X perror( "dup2 stdout");
- X Exit();
- X }
- X
- X if (dup2(fd,2) == -1)
- X {
- X perror( "dup2 stderr");
- X Exit();
- X }
- X
- X return;
- X default: /* parent */
- X exit(0);
- X }
- X#endif
- X}
- X
- X/**********************************************************************
- X * month and day variables for setting the TCL variables
- X **********************************************************************/
- Xchar *months[12] = { "January", "Febuary", "March", "April", "May", "June",
- X "July", "August", "September", "October",
- X "November", "December" };
- Xchar *dayofweek[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
- X "Friday", "Saturday" };
- X
- X/**********************************************************************
- X * the good stuff: set the TCL variables!
- X **********************************************************************/
- Xvoid SetState(Tcl_Interp *interp)
- X{
- X time_t time(time_t*), curr;
- X struct tm parts;
- X
- X char F[BUFSIZ]; /* temporary buffer. the name is historical */
- X
- X curr = time(0);
- X parts = *localtime(&curr);
- X
- X#ifdef DEBUG
- X#ifdef FIFO
- X fprintf(stderr, "Someone is fingering me!\n");
- X#endif
- X#endif
- X
- X sprintf( F, TIME_DEFAULT, parts.tm_hour, parts.tm_min, parts.tm_sec);
- X Tcl_SetVar(interp, "_time", F, 1);
- X
- X sprintf( F, "%d", parts.tm_hour);
- X Tcl_SetVar(interp, "_hour24", F, 1);
- X
- X if (parts.tm_hour == 0)
- X sprintf( F, "12");
- X else if (parts.tm_hour < 13)
- X sprintf( F, "%d", parts.tm_hour);
- X else
- X sprintf( F, "%d", parts.tm_hour - 12);
- X Tcl_SetVar(interp, "_hour12", F, 1);
- X
- X sprintf( F, "%d", parts.tm_min);
- X Tcl_SetVar(interp, "_minute", F, 1);
- X
- X sprintf( F, "%d", parts.tm_sec);
- X Tcl_SetVar(interp, "_second", F, 1);
- X
- X sprintf( F, DATE_DEFAULT, parts.tm_mday, months[parts.tm_mon],
- X parts.tm_year + 1900 );
- X Tcl_SetVar(interp, "_date", F, 1);
- X
- X sprintf( F, "%d", parts.tm_mday);
- X Tcl_SetVar(interp, "_day", F, 1);
- X
- X sprintf( F, "%d", parts.tm_mon + 1);
- X Tcl_SetVar(interp, "_month", F, 1);
- X
- X sprintf( F, "%s", months[parts.tm_mon]);
- X Tcl_SetVar(interp, "_monthstring", F, 1);
- X
- X sprintf( F, "%d", parts.tm_year + 1900 );
- X Tcl_SetVar(interp, "_year", F, 1);
- X
- X sprintf( F, "%d", parts.tm_wday );
- X Tcl_SetVar(interp, "_weekday", F, 1);
- X
- X sprintf( F, "%d", parts.tm_yday );
- X Tcl_SetVar(interp, "_yearday", F, 1);
- X
- X sprintf( F, "%s", dayofweek[parts.tm_wday]);
- X Tcl_SetVar(interp, "_weekdaystring", F, 1);
- X}
- X
- X/***********************************************************************
- X * the mainline, where the work is done
- X ***********************************************************************/
- Xvoid
- Xmain(int argc, char *argv[])
- X{
- X int fd;
- X#ifdef FIFO
- X fd_set writers;
- X#endif
- X struct stat stat_buf;
- X time_t mod_time;
- X int result;
- X int c;
- X extern char *optarg;
- X char *initfile = NULL, *directory = NULL;
- X#ifndef FIFO
- X int sleeptime = 0;
- X#endif
- X char tempheader[6];
- X
- X#ifdef FIFO
- X while ((c = getopt (argc, argv, "f:i:d:")) != EOF)
- X#else
- X while ((c = getopt (argc, argv, "f:i:d:s:")) != EOF)
- X#endif
- X switch (c)
- X {
- X case 'f':
- X fifo = optarg;
- X break;
- X case 'i':
- X initfile = optarg;
- X break;
- X case 'd':
- X directory = optarg;
- X break;
- X#ifndef FIFO
- X case 's':
- X sleeptime = atoi(optarg);
- X break;
- X
- X case '?':
- X fprintf(stderr,"usage: %s [-f outputfile] [-i initfile] [-d dir] [-s sleeptime]\n",
- X argv[0]);
- X#else
- X case '?':
- X fprintf (stderr,"usage: %s [-f fifofile] [-i initfile] [-d dir]\n",
- X argv[0]);
- X#endif
- X exit(1);
- X }
- X
- X /* use defaults if the options aren't specified */
- X if (!fifo)
- X fifo = PLAN;
- X if (!initfile)
- X initfile = PLANINIT;
- X if (sleeptime == 0)
- X sleeptime = DEFAULT_SLEEP_TIME;
- X
- X /* Go to the right directory. */
- X if (!directory && ((directory = getenv("HOME")) == NULL))
- X {
- X fprintf(stderr, "No $HOME.\n");
- X exit(1);
- X }
- X
- X if (chdir(directory) < 0) {
- X perror("Can't cd home directory");
- X exit(1);
- X }
- X
- X /*
- X * Check for existence of the FIFO, and
- X * that the current "plan" program isn't running.
- X * Setup signal handlers for HUP and TERM signals,
- X * to ignore INT and QUIT, and fork
- X */
- X stat(initfile, &stat_buf);
- X mod_time = stat_buf.st_mtime;
- X FingerOutput = stdout;
- X
- X /* lock out lockfile */
- X sprintf(lockname, "%s.lock", fifo);
- X if ((lockfd = open(lockname, O_RDONLY | O_CREAT, 0600)) < 0)
- X {
- X perror("Can't open lockfile");
- X exit(1);
- X }
- X if (flock(lockfd, LOCK_EX | LOCK_NB))
- X {
- X fprintf(stderr, "%s already running for %s\n", argv[0], fifo);
- X exit(1);
- X }
- X
- X#ifndef FIFO
- X /* get a temporary name */
- X strncpy(tempheader, fifo, 5);
- X tempheader[5] = '\0';
- X tempfile = tempnam (".", tempheader);
- X#endif
- X
- X /* do the initial setup */
- X Setup();
- X
- X /*
- X * read in the config file
- X * This initializes the TCL interpreter as well.
- X * If the config file cannot be read, or there are
- X * TCL errors when eval'ing it, a default "main" procedure
- X * is set up.
- X */
- X my_interp = GetConfig(initfile, stat_buf.st_size);
- X
- X /* Enter the server loop. */
- X for (;;) {
- X
- X /* Open the fifo for writing. */
- X#ifdef FIFO
- X if ((FingerOutput = fopen(fifo, "w")) == NULL) {
- X#else
- X if ((FingerOutput = fopen(tempfile, "w")) == NULL) {
- X#endif
- X perror("Can't fopen");
- X Exit();
- X }
- X fd = fileno(FingerOutput);
- X
- X#ifdef FIFO
- X /* Wait until someone else opens it for reading, so that we can
- X * write on it. */
- X FD_ZERO(&writers);
- X FD_SET(fd, &writers);
- X if (select(fd + 1, (fd_set *)NULL, &writers, (fd_set *)NULL,
- X (struct timeval *)NULL) < 0) {
- X if (errno != EINTR)
- X perror("Can't select");
- X continue;
- X }
- X if (!FD_ISSET(fd, &writers))
- X /* "Can't happen" */
- X continue;
- X#endif
- X /* if the config file has changed, reread it */
- X stat(initfile, &stat_buf);
- X if (mod_time != stat_buf.st_mtime)
- X {
- X mod_time = stat_buf.st_mtime;
- X /*
- X * re-initialize the TCL interpreter from the config file.
- X */
- X Tcl_DeleteInterp(my_interp);
- X my_interp = GetConfig(initfile, stat_buf.st_size);
- X }
- X
- X /* execute the TCL "main" procedure to (presumably) dump the message */
- X SetState(my_interp);
- X result = Tcl_Eval(my_interp, "main", 0, NULL);
- X if (result == TCL_OK) {
- X if (*my_interp->result != 0) {
- X fprintf(FingerOutput, "TCL Result: %s\n", my_interp->result);
- X }
- X } else {
- X if (result == TCL_ERROR) {
- X fprintf(FingerOutput, "TCL Error");
- X } else {
- X fprintf(FingerOutput, "TCL Error %d", result);
- X }
- X if (*my_interp->result != 0) {
- X fprintf(FingerOutput, ": %s\n", my_interp->result);
- X } else {
- X fprintf(FingerOutput, "\n");
- X }
- X }
- X
- X /* Close it so they stop reading, and pause to make sure of it. */
- X (void)fclose(FingerOutput);
- X
- X#ifndef FIFO
- X /* move the temp file to the fifo */
- X if (rename(tempfile, fifo))
- X {
- X perror("error renaming tempfile to output file");
- X Exit();
- X }
- X#endif
- X#ifdef FIFO
- X (void)sleep(5);
- X#else
- X (void)sleep(sleeptime);
- X#endif
- X }
- X
- X /* NOTREACHED */
- X}
- X
- X/* Local Variables: */
- X/* compile-command: "make" */
- X/* End: */
- //go.sysin dd *
- echo x - tcl_cmds.c
- sed 's/^X//' > tcl_cmds.c << '//go.sysin dd *'
- X/*
- X** A process to create dynamic .plan files. Creates a fifo, waits for
- X** someone to connect to it. Optional first argument is the directory
- X** to chdir(2) to, as in "plan ~rsalz &"; default is value of $HOME.
- X**
- X** Original version:
- X** Prints out the time, and a guess-timate of the temperature,
- X** based on the day of the year and the time.
- X**
- X** Major Revision: (Blair MacIntyre, Oct 1, 1990)
- X** Accepts a configuration file
- X**
- X** Major Revision 2: (Blair MacIntyre, Nov 1, 1990)
- X** Uses TCL to interpret the configuration file
- X*/
- X
- X#include <stdio.h>
- X#include <stdlib.h>
- X#include <string.h>
- X#include <ctype.h>
- X#include "tcl.h"
- X
- Xextern char *getenv(const char*);
- Xextern int fputc(int, FILE*);
- X#if defined(ultrix) | defined(sun)
- Xextern int toupper(int);
- Xextern int tolower(int);
- X#endif
- Xextern int fprintf(FILE*, char*,...);
- X
- Xextern FILE *FingerOutput;
- X
- Xint
- XcmdToUpper( clientData, interp, argc, argv )
- X char *clientData;
- X Tcl_Interp *interp;
- X int argc;
- X char **argv;
- X{
- X int j;
- X char *buffer;
- X
- X if (argc != 2) {
- X sprintf(interp->result,
- X "incorrect number of parameters to \"%s\" command", argv[0]);
- X return (TCL_ERROR);
- X }
- X
- X if ((buffer = malloc(strlen(argv[1]) + 1)) == NULL) {
- X sprintf(interp->result,
- X "out of memory while executing \"%s\" command", argv[0]);
- X return (TCL_ERROR);
- X }
- X
- X for (j = 0; argv[1][j] != NULL; j++ )
- X#if defined(ultrix)
- X buffer[j] = toupper(argv[1][j]);
- X#else
- X buffer[j] = islower( argv[1][j] ) ? toupper( argv[1][j] ) : argv[1][j];
- X#endif
- X buffer[j] = 0;
- X
- X Tcl_Return(interp, buffer, TCL_DYNAMIC);
- X
- X return (TCL_OK);
- X}
- X
- Xint
- XcmdToLower( clientData, interp, argc, argv )
- X char *clientData;
- X Tcl_Interp *interp;
- X int argc;
- X char **argv;
- X{
- X int j;
- X char *buffer;
- X
- X if (argc != 2) {
- X sprintf(interp->result,
- X "incorrect number of parameters to \"%s\" command", argv[0]);
- X return (TCL_ERROR);
- X }
- X
- X if ((buffer = malloc(strlen(argv[1]) + 1)) == NULL) {
- X sprintf(interp->result,
- X "out of memory while executing \"%s\" command", argv[0]);
- X return (TCL_ERROR);
- X }
- X
- X for (j = 0; argv[1][j] != NULL; j++ )
- X#if defined(ultrix)
- X buffer[j] = tolower(argv[1][j]);
- X#else
- X buffer[j] = isupper( argv[1][j] ) ? tolower( argv[1][j] ) : argv[1][j];
- X#endif
- X buffer[j] = 0;
- X
- X Tcl_Return(interp, buffer, TCL_DYNAMIC);
- X
- X return (TCL_OK);
- X}
- X
- Xint
- XcmdGetEnv(clientData, interp, argc, argv)
- X char *clientData;
- X Tcl_Interp *interp;
- X int argc;
- X char **argv;
- X{
- X if (argc != 2) {
- X sprintf(interp->result,
- X "incorrect number of parameters to \"%s\" command", argv[0]);
- X return (TCL_ERROR);
- X }
- X
- X Tcl_Return(interp, getenv(argv[1]), TCL_STATIC);
- X
- X return TCL_OK;
- X}
- X
- Xint
- XcmdEcho(clientData, interp, argc, argv)
- X char *clientData;
- X Tcl_Interp *interp;
- X int argc;
- X char **argv;
- X{
- X int i = 1, newline = 1;
- X
- X if (argc > 1 && (strcmp(argv[1], "-n") == 0)) {
- X newline = 0;
- X i++;
- X }
- X
- X for (; i < argc ; i++)
- X fprintf(FingerOutput, "%s ", argv[i]);
- X
- X if (newline)
- X fprintf(FingerOutput, "\n");
- X
- X return TCL_OK;
- X}
- X
- Xint
- XcmdFill(clientData, interp, argc, argv)
- X char *clientData;
- X Tcl_Interp *interp;
- X int argc;
- X char **argv;
- X{
- X int i, linelen, indent, j, length, hanging = 0;
- X
- X if (argc < 4) {
- X sprintf(interp->result,
- X "incorrect number of parameters to \"%s\" command", argv[0]);
- X return (TCL_ERROR);
- X }
- X
- X indent = atoi(argv[1]);
- X linelen = atoi(argv[2]);
- X
- X i = 3;
- X if (argc > 4 && (strcmp(argv[3], "-h") == 0)) {
- X hanging = 1;
- X i++;
- X }
- X
- X for (; i < argc ; ) {
- X /* if there's a hanging indent, don't pad first time */
- X if (i != 4 || !hanging)
- X for (j = 1; j <= indent; j++)
- X fputc(' ', FingerOutput);
- X
- X /* length is the length after the second word */
- X length = strlen(argv[i]);
- X fprintf(FingerOutput, "%s", argv[i++]);
- X if (i == argc)
- X break;
- X
- X length += strlen(argv[i]) + indent + 1;
- X
- X /* while the _next_ word fits, do this ... */
- X while (length <= linelen && i < argc) {
- X /* print the next word, add length for following word */
- X fprintf(FingerOutput, " %s", argv[i]);
- X if (++i == argc)
- X break;
- X length += strlen(argv[i]) + 1;
- X }
- X
- X if (i == argc)
- X break;
- X
- X fputc('\n', FingerOutput);
- X }
- X
- X return TCL_OK;
- X}
- X
- X/* Local Variables: */
- X/* compile-command: "make" */
- X/* End: */
- //go.sysin dd *
- echo x - tcl_cmds.h
- sed 's/^X//' > tcl_cmds.h << '//go.sysin dd *'
- Xextern int cmdToUpper( char *, Tcl_Interp *, int, char ** );
- Xextern int cmdToLower( char *, Tcl_Interp *, int, char ** );
- Xextern int cmdGetEnv( char *, Tcl_Interp *, int, char ** );
- Xextern int cmdEcho( char *, Tcl_Interp *, int, char ** );
- Xextern int cmdFill( char *, Tcl_Interp *, int, char ** );
- //go.sysin dd *
- echo x - uniqueproc.c
- sed 's/^X//' > uniqueproc.c << '//go.sysin dd *'
- X/*
- X * This file contains a function "unique_proc" which ensures that the
- X * process calling it is the only instance of this program running
- X * under this userid.
- X *
- X * It returns TRUE if this process is the only one, and FALSE otherwise.
- X *
- X * It uses a PID file and the "ps" program to do its job. It is not
- X * bulletproof.
- X */
- X
- X#include <stdlib.h>
- X#include <stdio.h>
- X#include <errno.h>
- X#include <string.h>
- X#include "plan_proto.h"
- X
- Xvoid writepid(const char*, int);
- X
- X#define BUFFER_SIZE (512)
- X#define FALSE (0)
- X#define TRUE (!FALSE)
- X
- Xint unique_proc() {
- X int mypid, procpid, n;
- X FILE *ps_out, *pid_file;
- X static char buf[BUFFER_SIZE], cmd_name[BUFFER_SIZE];
- X static char pid_cmd_name[BUFFER_SIZE], pid_file_name[BUFFER_SIZE];
- X char *home;
- X
- X /* create the command to get the ps output for this process */
- X mypid = getpid();
- X sprintf( buf, "ps -c%d", mypid );
- X
- X /* open the command for read */
- X if( (ps_out = popen( buf, "r" )) == NULL ) {
- X fprintf( stderr, "unique_proc: popen #1 failed. errno=%d\n", errno );
- X return FALSE;
- X } /* if */
- X
- X /* suck up the header line */
- X fgets( buf, BUFFER_SIZE, ps_out );
- X
- X /* scan the command name */
- X n = fscanf( ps_out, "%*20c%s", cmd_name );
- X if( pclose(ps_out) == -1 ) {
- X fprintf( stderr, "unique_proc: pclose #1 failed, errno =%d\n", errno );
- X return FALSE;
- X } /* if */
- X
- X if( n != 1 ) {
- X fprintf( stderr, "unique_proc: cannot scan command name (n=%d)\n", n );
- X return FALSE;
- X } /* if */
- X
- X /* get the home directory for this user */
- X if( (home = getenv("HOME")) == NULL ) {
- X fprintf( stderr, "unique_proc: getenv(\"HOME\") failed\n" );
- X return FALSE;
- X } /* if */
- X
- X /* create the pidfile name for this command */
- X sprintf( pid_file_name, "%s/.%spid", home, cmd_name );
- X
- X /* open the pid file */
- X if( (pid_file = fopen( pid_file_name, "r" )) == NULL ) {
- X /* assume this is the only instance, and write pid to file */
- X writepid( pid_file_name, mypid );
- X return TRUE;
- X } /* if */
- X
- X /* read the pid */
- X if( (n = fscanf( pid_file, "%d", &procpid )) != 1 ) {
- X /* can't scan pid, assume this is only process, write pid to file */
- X fclose( pid_file );
- X writepid( pid_file_name, mypid );
- X return TRUE;
- X } /* if */
- X
- X /* check out the pid read */
- X sprintf( buf, "ps -c%d", procpid );
- X
- X /* open the command for read */
- X if( (ps_out = popen( buf, "r" )) == NULL ) {
- X fprintf( stderr, "unique_proc: popen #2 failed. errno=%d\n", errno );
- X return FALSE;
- X } /* if */
- X
- X /* suck up the header line */
- X fgets( buf, BUFFER_SIZE, ps_out );
- X
- X /* scan the command name */
- X n = fscanf( ps_out, "%*20c%s", pid_cmd_name );
- X if( pclose(ps_out) == -1 ) {
- X fprintf( stderr, "unique_proc: pclose #2 failed, errno =%d\n", errno );
- X return FALSE;
- X } /* if */
- X
- X if( n == EOF ) {
- X /*
- X * no such process...
- X * therefore old process is dead
- X * write new pid
- X */
- X writepid( pid_file_name, mypid );
- X return TRUE;
- X } else if( strcmp( cmd_name, pid_cmd_name ) != 0 ) {
- X /*
- X * names do not match, so pid match is a coincidence.
- X * write new pid
- X */
- X writepid( pid_file_name, mypid );
- X return TRUE;
- X } else {
- X /*
- X * found an old instance of this program
- X */
- X return FALSE;
- X } /* if */
- X} /* unique_proc */
- X
- Xvoid writepid( const char* pidfilename, int pid ) {
- X FILE *pid_file;
- X
- X if( (pid_file = fopen( pidfilename, "w" )) == NULL ) {
- X fprintf( stderr, "unique_proc: cannot open pid file ('%s') for write\n", pidfilename );
- X } else {
- X fprintf( pid_file, "%d\n", pid );
- X fclose( pid_file );
- X } /* if */
- X} /* writepid */
- //go.sysin dd *
- exit
-
- --
- Blair MacIntyre --- bm@cs.columbia.edu --- CS Department, Columbia University
-