Xcal is a calendar program. For more details see Part 1 of this posting

Part 4 of 8
--shar starts here--
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 8)."
# Contents:  CHANGES xcal_cal/Makefile.bsdi xcal_popup.c
#   xcalpr/xcalpr.c
# Wrapped by pc@hillside on Wed Nov 17 11:24:36 1993
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'CHANGES' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'CHANGES'\"
else
echo shar: Extracting \"'CHANGES'\" \(11603 characters\)
sed "s/^X//" >'CHANGES' <<'END_OF_FILE'
XChanges:      CHANGES     2.38     93/11/15
X
X--------------------------- 4.1
X	
X	Remove the `marked' resource. First, it was broken anyway and
X	second it got in the way of having different colours for each day.
X
X	Add a lot of code to cope with different systems. Remove mmap
X	from most programs except xcal_help.c. Some systems that
X	purport to support mmap would do well to remove it (Ultrix
X	seems one).
X
X	Grateful thanks to the several people who worked on the beta
X	releases for me.
X
X--------------------------- 4.1 (beta version of new features)
X	
X	Add in a scroll bar for the date strip, so if it doesn't fit on
X	the screen (or is larger than a named resource maxStripHeight)
X	then you get a scroll bar appearing. This uses a viewport
X	widget and has changed the widget structure of the date strip.
X	I am a little dubious of the height arithmetic here.
X
X	A nice thing to do would be to ensure that `today' was always in
X	the centre of the viewport. This doesn't seem possible.
X	------- 
X	Alter the NAME of the form widget in the strip to be the Short name of
X	the day. This allows resources to be used to change fonts and colours
X	for days of the week, eg:
X
X		XCal*Sat*Label*font: lucidasans-typewriterbold-12
X	-------
X	Regularise the use of dirent rather than the old 4.2 names. This may
X	need some changes for SYSV based systems, I am unsure. However, let's
X	start with clean code.
X	-------
X	Radically alter the way that date formats are done. 
X	The toplevel widget is now driven by strftime() - and a user defined
X	resource using standard time formats is used to set it. This is
X	replicated for the memo window. The dates at the top of edit windows
X	and strips are set by a modified version of strftime() - this one
X	just deals in days, months and years. Again a resource is used to
X	set it.
X	-------
X	Add the ability to insert a clock in the top level widget. Using the
X	date format string to decide the format that is needed. The code also
X	adapts the polling frequency depending on the clock that is needed.
X	If the string does not mention seconds, then the clock will be
X	pinged every minute. If you want the clock to tick every 30 secs,
X	then the resource clockTick can be set.
X	-------
X	Add limited support for group usage. If called with
X		-u user then it looks for the user's directory and
X	reads files from it. I found that some sites are sharing
X	calendars by using `cat', this is just a better interface than
X	that.
X
X	I don't want to make it setuid, so if there is no access
X	permission for the directory (or the user has hidden it my
X	moving it from the regular name) then it won't find the files.
X	The program is constrained not to write any files in this mode.
X	It will also not start any alarms.
X	
X	If a calendar file is read-only to the user, then the string
X	'Private entry' is displayed. Not much - but something. There
X	should be a private/public button on the edit box.
X
X	The user is reminded that this invocation is not reading their
X	files because the string (user) is added to various date
X	titles. (Someday, proper group usage should be done).
X	-------
X	Fix from Ed Gould. Add a new resource execAlarms to inhibit the
X	! and %cron commands from happening - even though the remaining
X	alarms will fire.
X	-------
X	Respond to some observations by Jaap Akkerhuis. Now when most buttons
X	are pressed they are made insensitive - so a further button press
X	causes no action. Previously you could get many invocations of dialogs
X	and questions - things could get messy when windows were removed in
X	non-logical orders. Has this fixed everything? Well time will tell.
X	The solution is perhaps a little messy. Still this is the trouble
X	with altering the code rather than re-writing it.
X	-------
X	Act on an idea from Mac Pigman - there is now an edit button on
X	the Memo panel that allows you to edit today's Calendar entry.
X	-------
X	Redo the way that help is done. Can now take the text from a file
X	and/or compile it in. This should help non-English speaking users
X	to have a local language help. A shell script is provided to take
X	the help file and translate it into some C.
X	-------
X	Rework various button handling so that buttons are made insensitive
X	when they are pressed. The main problem here is putting them back on
X	safely. This has added perhaps too much code - but it works better
X	--------
X	Redo the manual page
X	--------
X	Make the title bar widgets adjust their offset from the outside world
X	so that they are centred vertically
X	--------
X	Allow for the 12 hour clock in alarms. If the resource AlarmWarp is
X	set true and the time of the alarm is between zero and the value
X	in MinAlarmWarp then the time is taken as a pm time. This idea from
X	Mark Pawliger.
X	---------
X	When the Cmd resource is set, the command that is executed takes the
X	data from the remainder of the calendar line as an argument. Ensure
X	that 1) this is passed as a quoted single argument to the system routine
X	call. Cope with embedded single quotes.
X	---------
X	Fix memory leak when displaying the Weekly entry (leak spotted by
X	chet@arc.uucp - be nice to have his real name)
X	---------
X	Make a number of changes to the alarm system to attempt to stop
X	the races that happened when using ClockTick update polling. It turns
X	out that various bits of the old code was done without real regard
X	for the event driven nature of X applications. The code now appears
X	to trigger alarms OK - and will not break when the control files are
X	reloaded. While I was testing this the clocks went back an hour and
X	that caused some confusion until I realised what had happened.
X	
X	It's still the case that alarms need one minute to trigger properly.
X	----------
X	Provide xcalev, this should go somewhere to meet the needs of the
X	several people who mailed saying `it's great' but I cannot deal with
X	regular events... so I won't be using it. Their loss I feel :-)
X	----------
X	Provide xcalpr, print calendar entries to a text terminal.
X	Also generates input for the calendar program
X	----------
X	Put xcalev, xcalpr, xcal_cal into sub dirs, deal with the Imakefiles
X	to do that.
X	----------
X	Remove AT&T code and replace with code from the NetII tape.
X
X--------------------------- 3.4
X
X	Add Xos.h as a define in xcal.c and xcal_edit.c.
X
X	When the middle button is used to get a month/year selection
X	box, if you just type the month name, you will get the next month
X	with that name, not the month THIS year.
X
X	Fix in xcal_alarm.c that was freeing a non freeable area.
X	I bet this has caused some problems.
X	Fix from Julian Bradfield <jcb@dcs.ed.ac.uk>
X 
X	Fix in xcal_strip.c which is causing widgets to be named
X	incorrectly. Widgets were called `Day' rather than '1 Day' as
X	advertised. Bug spotted by James Matthew Farrow <matty@cs.su.oz.au>.
X	(This later removed to allow days to be specified in resources)
X
X	------- 
X	(These from Miles O'Neal <meo@pencom.com>)
X
X	Now builds for NeXTSTEP 3.0.
X
X	Compiler warnings were cleaned up.
X
X	Top level help now through button, not printed to tty.
X	Help boxes are reused, not created and destroyed every
X	time they are accessed.  This also prvents multiple
X	copies of the same help box from existing simultaneoulsy.
X
X	Added the calendar icon from bricons.
X	--------
X	I guess I have changed my C bracketing style in the last two
X	years. Ran the code through indent so I would feel a little happier.
X	--------
X	Well, I had this idea two years ago.
X
X	If you now make a selection using the mouse - select some text
X	on the screen - then it can be appended into a day file by
X	simply clicking with the MIDDLE mouse button on the day of your
X	choice. This makes it easy to set groups of dates up using the
X	mouse.
X
X
X--------------------------- 3.3
X
X	Implement the ability to deal with regular weekly events.
X	This is part of the memo system. Today's current events are
X	shown as part of the memo panel. They can be edited by hitting
X	a button and bringing up a special strip with an entry for
X	each day. These regular event files are integrated into
X	the alarm system.
X
X	Allow today's name: Monday, Tuesday etc to appear in the top
X	level widget, the header of an edit window and the title of
X	the memo box. This is controlled by the Order and Format
X	resources and so previous behaviour can be maintained. Beware
X	that this redefines the names of the days so
X		Sunday maps to Sunday
X	and a new short name is used for the abbreviated form
X		Sun maps to Sun
X	used in date strips.
X
X	Ensure that middle and right button translations work in the
X	memo button in the top level widget (suggested by Casey
X	Leedom).
X
X	New Imakefile from Casey Leedom. This has support for pscal.
X	New pscal/Imakefile.
X
X	Add initialMemo resource so the memo box can popup at startup
X	time - (suggested by G. W. Pigman III)
X
X	Steven Plite pointed out that the year display is
X	inconsistent. To allow choice, add three new resources:
X		dateYearIsTwoDigits
X		memoYearIsTwoDigits
X		editYearIsTwoDigits
X	You can now choose how you would like to have your year
X	displayed in the various places.
X	Defaults to showing four digits.
X
X	System V release 4 fixes from Dave McCraken.
X	Alters: xcal_alarm.c, xcal_cal.c, *.bm xcal.c
X
X	The memo box quit button causes a Save File
X	dialogue box to be popped if the memo data has been
X	altered and not saved. The behaviour of this was wrong
X	when there was no memo data.	Reported by Greg Bond.
X	Fixed by changing tests in xcal_memo.c.
X
X	Proper length of a directory entry under SYSV is 
X	strlen(dp->d_name) not strlen(dp->d_name)+1.
X	Changed xcal_edit.c 			(Dave McCraken)
X
X	Eliminated double definition of GetMemoFile() and incorrect
X	definition of MemoHelp() in xcal_memo.c (David C Lawrence)
X
X--------------------------- 3.2 
X
XXcal - Version 3.2 Issued to comp.sources.x
X
X	Fixes some stupid bugs
X	Ensures that update code works properly
X
X---------------------------- 3.1
X
XXcal - Version 3.1 Issued to comp.sources.x (un-intentionally)
X
X	Adds the memo functionality and the Stick/Unpin feature
X	for alarms.
X
X---------------------------- 2.1
X
XXcal - Version 2.1 Issued privately
X
X	Two main differences between version 1.1 and version 2.1
X	a)	Version 2.1 has alarms so that xcal can poll you
X		during the day - idea contributed by Mark Majhor, Sequent
X		and then unashame-edly hacked by me.
X	b)	Version 2.1 has a support program supplied by Ed Gould
X		from Mt Xinu allowing you to set up a file suitable for
X		driving UNIX's calendar program.
X
X---------------------------- 1.6
X
Xpscal/pscal.sh	Fix to make sed work better to truncate the calendar file
X		when printing.
X		From Gregory Bond, Burdett Buckeridge & Young Ltd, Melbourne, Australia
X		Internet: gnb@melba.bby.oz.au    non-MX: gnb%melba.bby.oz@uunet.uu.net
X
X---------------------------- 1.5
X
Xxcal.h		Add initialCalendar/initialEdit switches
X		Support for better start-up options... from
X		From: Rod Whitby <rwhitby@adl.austek.oz.au>
X
Xxcal.c		Add hooks and code to perform startuo
X
XImakefile	Corrected
X
Xxcal.man	Add new lines supporting initialCalendar/initialEdit
X
X---------------------------- 1.4
Xxcal_edit.c	Fix bug where colour mapping on days failed to change when
X		data is deleted or added.
X
Xxcal.h/xcal.c/xcal_strip.c
X		Add a new resource minStripWidth intended to allow
X		users to widen the strip to some value which seems
X		sensible. If zero the resource is unused.
X
XXCal.ad		Add colour map from wade@cs.utk.edu
X
Xxcal_edit.c	Changes to XBell calls due to typo
X		Steve Alexander, Software Technologies Group
X		INTERACTIVE Systems Corporation, Naperville, IL
X		 ...!{sun,ico}!laidbak!stevea
X		stevea@i88.isc.com
X
X
X	
XXcal - Version 1.1 Issued to the net comp.sources.x. 
X		xcal: Volume 7, Issue 1-2
X
END_OF_FILE
if test 11603 -ne `wc -c <'CHANGES'`; then
    echo shar: \"'CHANGES'\" unpacked with wrong size!
fi
# end of 'CHANGES'
fi
if test -f 'xcal_cal/Makefile.bsdi' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xcal_cal/Makefile.bsdi'\"
else
echo shar: Extracting \"'xcal_cal/Makefile.bsdi'\" \(9778 characters\)
sed "s/^X//" >'xcal_cal/Makefile.bsdi' <<'END_OF_FILE'
X# Makefile generated by imake - do not edit!
X# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $
X
X# -------------------------------------------------------------------------
X# Makefile generated from "Imake.tmpl" and <Imakefile>
X# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $
X#
X# Platform-specific parameters may be set in the appropriate <vendor>.cf
X# configuration files.  Site-specific parameters should be set in the file
X# site.def.  Full rebuilds are recommended if any parameters are changed.
X#
X# If your C preprocessor does not define any unique symbols, you will need
X# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
X# "make World" the first time).
X#
X
X# -------------------------------------------------------------------------
X# site-specific configuration parameters that need to come before
X# the platform-specific parameters - edit site.def to change
X
X# site:  $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
X
X# -------------------------------------------------------------------------
X# platform-specific configuration parameters - edit bsd.cf to change
X
X# platform:  $XConsortium: bsd.cf,v 1.18 91/07/30 12:10:52 rws Exp $
X
X# operating system:             4.3bsd
X
X# -------------------------------------------------------------------------
X# site-specific configuration parameters that go after
X# the platform-specific parameters - edit site.def to change
X
X# site:  $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
X
X            SHELL = 	/bin/sh
X
X              TOP = .
X      CURRENT_DIR = .
X
X               AR = ar clq
X  BOOTSTRAPCFLAGS =
X               CC = cc
X               AS = as
X
X         COMPRESS = compress
X              CPP = 	/usr/bin/cpp $(STD_CPP_DEFINES)
X    PREPROCESSCMD = cc -E $(STD_CPP_DEFINES)
X          INSTALL = install
X               LD = ld
X             LINT = lint
X      LINTLIBFLAG = -C
X         LINTOPTS = -axz
X               LN = ln -s
X             MAKE = make
X               MV = mv
X               CP = cp
X
X           RANLIB = ranlib
X  RANLIBINSTFLAGS =
X
X               RM = rm -f
X            TROFF = groff -Tps
X         MSMACROS = -ms
X              TBL = tbl
X              EQN = eqn
X     STD_INCLUDES =
X  STD_CPP_DEFINES =
X      STD_DEFINES =
X EXTRA_LOAD_FLAGS =
X  EXTRA_LIBRARIES =
X             TAGS = ctags
X
X    PROTO_DEFINES =
X
X     INSTPGMFLAGS = -s
X
X     INSTBINFLAGS = -m 0755
X     INSTUIDFLAGS = -m 4755
X     INSTLIBFLAGS = -m 0644
X     INSTINCFLAGS = -m 0444
X     INSTMANFLAGS = -m 0444
X     INSTDATFLAGS = -m 0444
X    INSTKMEMFLAGS = -m 4755
X
X      PROJECTROOT =  /usr/X11
X
X     TOP_INCLUDES = -I$(INCROOT)
X
X      CDEBUGFLAGS = -O
X        CCOPTIONS =
X
X      ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES)
X       ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES)
X           CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
X        LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
X
X           LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
X
X        LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR)
X
X   LDCOMBINEFLAGS = -X -r
X      DEPENDFLAGS =
X
X        MACROFILE = bsd.cf
X           RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
X
X    IMAKE_DEFINES =
X
X         IRULESRC = $(CONFIGDIR)
X        IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
X
X     ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules 			$(IRULESRC)/Project.tmpl $(IRULESRC)/site.def 			$(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
X
X# -------------------------------------------------------------------------
X# X Window System Build Parameters
X# $XConsortium: Project.tmpl,v 1.138.1.1 92/11/11 09:49:19 rws Exp $
X
X# -------------------------------------------------------------------------
X# X Window System make variables; this need to be coordinated with rules
X
X          PATHSEP = /
X        USRLIBDIR =  /usr/X11/lib
X           BINDIR =  /usr/X11/bin
X          INCROOT =  /usr/X11/include
X     BUILDINCROOT = $(TOP)
X      BUILDINCDIR = $(BUILDINCROOT)/X11
X      BUILDINCTOP = ..
X           INCDIR = $(INCROOT)/X11
X           ADMDIR = /usr/adm
X           LIBDIR = $(USRLIBDIR)/X11
X        CONFIGDIR = $(LIBDIR)/config
X       LINTLIBDIR = $(USRLIBDIR)/lint
X
X          FONTDIR = $(LIBDIR)/fonts
X         XINITDIR = $(LIBDIR)/xinit
X           XDMDIR = $(LIBDIR)/xdm
X           TWMDIR = $(LIBDIR)/twm
X          MANPATH =  /usr/X11/man
X    MANSOURCEPATH = $(MANPATH)/man
X        MANSUFFIX = n
X     LIBMANSUFFIX = 3
X           MANDIR = $(MANSOURCEPATH)$(MANSUFFIX)
X        LIBMANDIR = $(MANSOURCEPATH)$(LIBMANSUFFIX)
X           NLSDIR = $(LIBDIR)/nls
X        PEXAPIDIR = $(LIBDIR)/PEX
X      XAPPLOADDIR = $(LIBDIR)/app-defaults
X       FONTCFLAGS = -t
X
X     INSTAPPFLAGS = $(INSTDATFLAGS)
X
X            IMAKE = imake
X           DEPEND = makedepend
X              RGB = rgb
X
X            FONTC = bdftopcf
X
X        MKFONTDIR = mkfontdir
X        MKDIRHIER = 	/bin/sh $(BINDIR)/mkdirhier
X
X        CONFIGSRC = $(TOP)/config
X       DOCUTILSRC = $(TOP)/doc/util
X        CLIENTSRC = $(TOP)/clients
X          DEMOSRC = $(TOP)/demos
X           LIBSRC = $(TOP)/lib
X          FONTSRC = $(TOP)/fonts
X       INCLUDESRC = $(TOP)/X11
X        SERVERSRC = $(TOP)/server
X          UTILSRC = $(TOP)/util
X        SCRIPTSRC = $(UTILSRC)/scripts
X       EXAMPLESRC = $(TOP)/examples
X       CONTRIBSRC = $(TOP)/../contrib
X           DOCSRC = $(TOP)/doc
X           RGBSRC = $(TOP)/rgb
X        DEPENDSRC = $(UTILSRC)/makedepend
X         IMAKESRC = $(CONFIGSRC)
X         XAUTHSRC = $(LIBSRC)/Xau
X          XLIBSRC = $(LIBSRC)/X
X           XMUSRC = $(LIBSRC)/Xmu
X       TOOLKITSRC = $(LIBSRC)/Xt
X       AWIDGETSRC = $(LIBSRC)/Xaw
X       OLDXLIBSRC = $(LIBSRC)/oldX
X      XDMCPLIBSRC = $(LIBSRC)/Xdmcp
X      BDFTOSNFSRC = $(FONTSRC)/bdftosnf
X      BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf
X      BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf
X     MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir
X         FSLIBSRC = $(FONTSRC)/lib/fs
X    FONTSERVERSRC = $(FONTSRC)/server
X     EXTENSIONSRC = $(TOP)/extensions
X         XILIBSRC = $(EXTENSIONSRC)/lib/xinput
X        PEXLIBSRC = $(EXTENSIONSRC)/lib/PEXlib
X      PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX
X
X  DEPEXTENSIONLIB = $(USRLIBDIR)/libXext.a
X     EXTENSIONLIB = 			 -lXext
X
X          DEPXLIB = $(DEPEXTENSIONLIB) $(USRLIBDIR)/libX11.a
X             XLIB = $(EXTENSIONLIB) 			 -lX11
X
X      DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
X         XAUTHLIB = 			 -lXau
X      DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a
X         XDMCPLIB = 			 -lXdmcp
X
X        DEPXMULIB = $(USRLIBDIR)/libXmu.a
X           XMULIB = 			 -lXmu
X
X       DEPOLDXLIB = $(USRLIBDIR)/liboldX.a
X          OLDXLIB = 			 -loldX
X
X      DEPXTOOLLIB = $(USRLIBDIR)/libXt.a
X         XTOOLLIB = 			 -lXt
X
X        DEPXAWLIB = $(USRLIBDIR)/libXaw.a
X           XAWLIB = 			 -lXaw
X
X        DEPXILIB = $(USRLIBDIR)/libXi.a
X           XILIB = 			 -lXi
X
X       DEPPEXLIB = $(USRLIBDIR)/libPEX5.a
X          PEXLIB = 			 -lPEX5
X
X        DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a
X           PHIGSLIB = 			 -lphigs
X
X       DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a
X          XBSDLIB = 			 -lXbsd
X
X LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln
X         LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln
X          LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln
X        LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln
X          LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln
X           LINTXI = $(LINTLIBDIR)/llib-lXi.ln
X          LINTPEX = $(LINTLIBDIR)/llib-lPEX5.ln
X        LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln
X
X          DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
X
X         DEPLIBS1 = $(DEPLIBS)
X         DEPLIBS2 = $(DEPLIBS)
X         DEPLIBS3 = $(DEPLIBS)
X
X# -------------------------------------------------------------------------
X# Imake rules for building libraries, programs, scripts, and data files
X# rules:  $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $
X
X# -------------------------------------------------------------------------
X# start of Imakefile
X
XBINDIR=/usr/local/bin
X
XINSTPGMFLAGS=$(INSTBINFLAGS)
X
Xall:: xcal_cal
X
X OBJS = xcal_cal.o
X SRCS = xcal_cal.c
X
X PROGRAM = xcal_cal
X
Xall:: xcal_cal
X
Xxcal_cal: $(OBJS) $(DEPLIBS)
X	$(RM) $@
X	$(CC) -o $@ $(OBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS)
X
Xinstall:: xcal_cal
X	-@if [ -d $(DESTDIR)$(BINDIR) ]; then set +x; \
X	else (set -x; $(MKDIRHIER) $(DESTDIR)$(BINDIR)); fi
X	$(INSTALL) -c $(INSTPGMFLAGS)  xcal_cal $(DESTDIR)$(BINDIR)
X
Xinstall.man:: xcal_cal.man
X	-@if [ -d $(DESTDIR)$(MANDIR) ]; then set +x; \
X	else (set -x; $(MKDIRHIER) $(DESTDIR)$(MANDIR)); fi
X	$(INSTALL) -c $(INSTMANFLAGS) xcal_cal.man $(DESTDIR)$(MANDIR)/xcal_cal.$(MANSUFFIX)
X
Xdepend::
X	$(DEPEND) $(DEPENDFLAGS) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
X
Xlint:
X	$(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS)
Xlint1:
X	$(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS)
X
Xclean::
X	$(RM) $(PROGRAM)
X
Xdepend::
X	$(DEPEND) $(DEPENDFLAGS) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
X
X# -------------------------------------------------------------------------
X# common rules for all Makefiles - do not edit
X
Xemptyrule::
X
Xclean::
X	$(RM_CMD) "#"*
X
XMakefile::
X	-@if [ -f Makefile ]; then set -x; \
X	$(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
X	else exit 0; fi
X	$(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
X
Xtags::
X	$(TAGS) -w *.[ch]
X	$(TAGS) -xw *.[ch] > TAGS
X
X# -------------------------------------------------------------------------
X# empty rules for directories that do not have SUBDIRS - do not edit
X
Xinstall::
X	@echo "install in $(CURRENT_DIR) done"
X
Xinstall.man::
X	@echo "install.man in $(CURRENT_DIR) done"
X
XMakefiles::
X
Xincludes::
X
X# -------------------------------------------------------------------------
X# dependencies generated by makedepend
X
END_OF_FILE
if test 9778 -ne `wc -c <'xcal_cal/Makefile.bsdi'`; then
    echo shar: \"'xcal_cal/Makefile.bsdi'\" unpacked with wrong size!
fi
# end of 'xcal_cal/Makefile.bsdi'
fi
if test -f 'xcal_popup.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xcal_popup.c'\"
else
echo shar: Extracting \"'xcal_popup.c'\" \(9814 characters\)
sed "s/^X//" >'xcal_popup.c' <<'END_OF_FILE'
X#ifndef lint
Xstatic char    *sccsid = "@(#)xcal_popup.c	3.13 (Hillside Systems) 10/29/93";
Xstatic char    *copyright = "@(#)Copyright 1989,1990,1993 Peter Collinson, Hillside Systems";
X#endif				/* lint */
X/***
X
X* module name:
X	xcal_popup.c
X* function:
X	Deal with various popups for xcal
X	There are two main ones:
X	a)	the centre button causes a popup date selection popup
X	b)	the right button causes an exit popup
X* history:
X	Written November 1989
X	Peter Collinson
X	Hillside Systems
X* (C) Copyright: 1989 Hillside Systems/Peter Collinson
X	
X	For full permissions and copyright notice - see xcal.c
X***/
X#include <stdio.h>
X#include <ctype.h>
X#include <X11/Intrinsic.h>
X#include <X11/StringDefs.h>
X#include <X11/Shell.h>
X#include <X11/Xaw/Label.h>
X#include <X11/Xaw/Dialog.h>
X#include <X11/Xaw/AsciiText.h>
X#include <X11/Xaw/Command.h>
X#include "xcal.h"
X
Xstatic void     AskDialog();
Xstatic void     NoCal();
Xstatic void     YesCal();
Xstatic char    *DateParse();
Xstatic int      MonScan();
Xstatic void     LeaveDialog();
Xstatic void     NoLeave();
Xstatic void     YesLeave();
Xstatic void     NoEdit();
X
X#define argLD(N,V) { XtSetArg(args[nargs], N, V); nargs++; }
X
X/*
X * This routine deals with most of the work to create a dialog popup, it is
X * passed a function which is called to create the dialog box
X * 
X * The widget here is used for positioning, these popups are always children of
X * the toplevel widget
X *
X * These widgets are generally called from a Command widget button.
X * if this is the case, we make that button non-sensitive and
X * use the pop-down callback to turn them on again (see xcal_buts.c)
X */
Xvoid
XDialogPopup(w, fn, arg, but)
X	Widget          w;
X	void            (*fn) ();
X	caddr_t         arg;
X	Widget		but;
X{
X	Widget          pop;
X	Arg             args[10];
X	int		nargs;
X	Position        x, y;
X	Position        nx, ny;
X	Dimension       width, height, border;
X
X	/*
X	 * Get the position of the toplevel so we 
X	 * can position the dialog box properly
X	 */
X	XtSetArg(args[0], XtNwidth, &width);
X	XtSetArg(args[1], XtNheight, &height);
X	XtGetValues(w, args, 2);
X	XtTranslateCoords(w, (Position) (width / 2),
X			  (Position) (height / 2), &x, &y);
X
X	/*
X	 * Create a popup to hold the dialog
X	 */
X	nargs = 0;
X	argLD(XtNallowShellResize, True);
X	argLD(XtNinput, True);
X	argLD(XtNx, x);
X	argLD(XtNy, y);
X	argLD(XtNsaveUnder, FALSE);	/* was true but this caused */
X					/* me problems on OpenWindows */
X
X	pop = XtCreatePopupShell("question", transientShellWidgetClass, toplevel, args, nargs);
X
X	if (but && XtIsSubclass(but, commandWidgetClass))
X		ButtonOff(but, pop);
X
X	/*
X	 * Set up the dialog
X	 */
X	(*fn) (pop, arg);
X
X	XtRealizeWidget(pop);
X
X	/*
X	 * We can now worry if this box is actually off the screen
X	 */
X	XtSetArg(args[0], XtNwidth, &width);
X	XtSetArg(args[1], XtNheight, &height);
X	XtSetArg(args[2], XtNborderWidth, &border);
X	XtGetValues(pop, args, 3);
X
X	border <<= 1;
X	XtTranslateCoords(pop, (Position) 0, (Position) 0, &nx, &ny);
X
X	if ((int)(nx + width + border) > WidthOfScreen(XtScreen(toplevel)))
X		nx = WidthOfScreen(XtScreen(toplevel)) - width - border;
X	else
X		nx = x;
X
X	if ((int)(ny + height + border) > HeightOfScreen(XtScreen(toplevel)))
X		ny = HeightOfScreen(XtScreen(toplevel)) - height - border;
X	else
X		ny = y;
X
X	if (nx != x || ny != y) {
X		XtSetArg(args[0], XtNx, nx);
X		XtSetArg(args[1], XtNy, ny);
X		XtSetValues(pop, args, 2);
X	}
X	XtPopup(pop, XtGrabNone);
X}
X
X/************************************************************************/
X/*									*/
X/*									*/
X/*	Deals with middle button presses - ask for a date		*/
X/*									*/
X/*									*/
X/************************************************************************/
X
X/*
X * SetDate - ask for a date and start a calendar
X * This is an action routine
X */
X/* ARGSUSED */
Xvoid
XSetDate(w, event, params, numb)
X	Widget          w;
X	XEvent         *event;
X	String         *params;
X	Cardinal       *numb;
X{
X	DialogPopup(toplevel, AskDialog, NULL, w);
X}
X
X/* ARGSUSED */
Xstatic void
XAskDialog(pop, noop)
X	Widget          pop;
X	Cardinal        noop;
X{
X	Widget          dia;
X	Arg             args[2];
X	WidgetList      children;	/* which is Widget children[] */
X	Cardinal        num_children;
X	int             i;
X
X	/* Take from args: "Enter mm yyyy?" */
X	XtSetArg(args[0], XtNvalue, "");
X	dia = XtCreateManagedWidget("newdate", dialogWidgetClass, pop, args, 1);
X	XawDialogAddButton(dia, "ok", YesCal, dia);
X	XawDialogAddButton(dia, "cancel", NoCal, pop);
X	/*
X	 * I would like to add CR translations to the text box the only way
X	 * to get the widget seems to be to use an R4 feature to get the
X	 * WidgetList
X	 */
X	XtSetArg(args[0], XtNchildren, &children);
X	XtSetArg(args[1], XtNnumChildren, &num_children);
X	XtGetValues(dia, (ArgList) args, 2);
X	for (i = 0; i < num_children; i++) {
X		if (XtClass(children[i]) == asciiTextWidgetClass) {
X			/* Bingo */
X			XtOverrideTranslations(
X					       children[i],
X					       XtParseTranslationTable("<Key>Return: SetDateAction()")
X				);
X
X		} else
X		if (XtClass(children[i]) == labelWidgetClass) {
X			XtSetArg(args[0], XtNresizable, True);
X			XtSetValues(children[i], args, 1);
X		}
X	}
X
X}
X
X/*
X * No we don't want a specified date
X * Closure here is the pop shell
X */
X/* ARGSUSED */
Xstatic void
XNoCal(w, closure, call_data)
X	Widget          w;
X	caddr_t         closure;
X	caddr_t         call_data;
X{
X	XtDestroyWidget((Widget) closure);
X}
X
X/*
X * Yes we do want a specified date
X * Closure here is the dialog widget
X */
X/* ARGSUSED */
Xstatic void
XYesCal(w, closure, call_data)
X	Widget          w;
X	caddr_t         closure;
X	caddr_t         call_data;
X{
X	Widget          dia;
X	Arg             args[2];
X	Date            wanted;
X	char           *errstr;
X
X	dia = (Widget) closure;
X	/*
X	 * Parse the string
X	 */
X	if (errstr = DateParse(XawDialogGetValueString(dia), &wanted)) {
X		/*
X		 * insert an error							 * message in the widget
X		 */
X		XtSetArg(args[0], XtNlabel, errstr);
X		XtSetValues(dia, args, 1);
X		XBell(XtDisplay(toplevel), 0);
X		return;
X	}
X	XtDestroyWidget(XtParent(dia));
X	NewMonthStrip(&wanted, NULL);
X}
X
X/*
X * Action mapped to by CR in the dialog
X */
X/* ARGSUSED */
Xvoid
XTextCal(w, event, params, numb)
X	Widget          w;
X	XEvent         *event;
X	String         *params;
X	Cardinal       *numb;
X{
X	YesCal(w, (caddr_t) XtParent(w), 0);	/* parent of text widget is */
X						/* the dialog box */
X}
X
X/*
X * Parse a date string
X */
Xstatic char    *
XDateParse(str, da)
X	register char  *str;
X	Date           *da;
X{
X	register char  *wk;
X	int             lastc;
X	int             mo;
X
X	*da = today;
X
X	wk = str;
X	while (isspace(*wk))
X		wk++;
X	if (*wk == '\0')
X		return ("No data found");
X	str = wk;
X	if (isdigit(*str)) {
X		while (isdigit(*str))
X			str++;
X		lastc = *str;
X		*str++ = '\0';
X		mo = atoi(wk);
X		if (mo < 1 || mo > 12)
X			return ("Illegal month number");
X		da->month = mo - 1;
X	} else if (isalpha(*str)) {	/* be kind - allow month names */
X		while (isalpha(*str)) {
X			if (isupper(*str))
X				*str = tolower(*str);
X			str++;
X		}
X		lastc = *str;
X		*str++ = '\0';
X		mo = MonScan(wk);
X		if (mo < 0)
X			return ("Cannot find month name");
X		if (mo < da->month)
X			da->year++;
X		da->month = mo;
X	}
X	if (lastc) {
X		wk = str;
X		while (isspace(*wk))
X			wk++;
X		str = wk;
X		if (*str)
X			da->year = atoi(wk);
X	}
X	return (NULL);
X}
X
X/*
X * Given a string look in our database for a number
X */
Xstatic int
XMonScan(monstr)
X	char           *monstr;
X{
X	char           *a, *b;
X	int             ca, cb;
X	int             mon;
X
X	for (mon = 0; mon < 12; mon++)
X		for (a = monstr, b = appResources.mon[mon];;) {
X			ca = *a++;
X			if (ca == '\0')
X				return (mon);
X			if (isupper(ca))
X				ca = tolower(ca);
X			cb = *b++;
X			if (cb == '\0')
X				break;
X			if (isupper(cb))
X				cb = tolower(cb);
X			if (ca != cb)
X				break;
X		}
X	return (-1);
X}
X
X/************************************************************************/
X/*									*/
X/*									*/
X/*		Deals with right button presses - exit			*/
X/*									*/
X/*									*/
X/************************************************************************/
X/*
X * Get out - possibly
X */
X/* ARGSUSED */
Xvoid
XAskLeave(w, event, params, numb)
X	Widget          w;
X	XEvent         *event;
X	String         *params;
X	Cardinal       *numb;
X{
X
X	DialogPopup(toplevel, LeaveDialog, NULL, w);
X}
X
X/* ARGSUSED */
Xstatic void
XLeaveDialog(pop, noop)
X	Widget          pop;
X	Cardinal        noop;
X{
X	Widget          di;
X
X	/* Take "Really exit? from resources */
X	di = XtCreateManagedWidget("exit", dialogWidgetClass, pop, NULL, 0);
X	XawDialogAddButton(di, "yes", YesLeave, pop);
X	XawDialogAddButton(di, "no", NoLeave, pop);
X}
X
X/* ARGSUSED */
Xstatic void
XYesLeave(w, closure, call_data)
X	Widget          w;
X	caddr_t         closure;
X	caddr_t         call_data;
X{
X	Leave(0);
X}
X
X/* ARGSUSED */
Xstatic void
XNoLeave(w, closure, call_data)
X	Widget          w;
X	caddr_t         closure;
X	caddr_t         call_data;
X{
X	XtDestroyWidget((Widget) closure);
X}
X
X/************************************************************************/
X/* */
X/* */
X/* Deal with an attempt to double edit some data			 */
X/* */
X/* */
X/************************************************************************/
X
X
Xvoid
XNoEditIsPossible(w, da)
X	Widget          w;
X	Date           *da;
X{
X	static char     errmsg[256];
X
X	FmtDate(da, errmsg, sizeof errmsg, appResources.already);
X
X	DialogPopup(w, NoEdit, errmsg, w);
X
X}
X
Xvoid
XNoDayEditIsPossible(w, da)
X	Widget          w;
X	Date           *da;
X{
X	static char     errmsg[256];
X
X	FmtDate(da, errmsg, sizeof errmsg, appResources.alreadyWeekly);
X
X	DialogPopup(w, NoEdit, errmsg, w);
X
X}
X
Xstatic void
XNoEdit(pop, errmsg)
X	Widget          pop;
X	String          errmsg;
X{
X	Arg             args[2];
X	Widget          dia;
X
X	XtSetArg(args[0], XtNlabel, errmsg);
X	dia = XtCreateManagedWidget("noedit", dialogWidgetClass, pop, args, 1);
X	XawDialogAddButton(dia, "ok", NoCal, pop);
X}
END_OF_FILE
if test 9814 -ne `wc -c <'xcal_popup.c'`; then
    echo shar: \"'xcal_popup.c'\" unpacked with wrong size!
fi
# end of 'xcal_popup.c'
fi
if test -f 'xcalpr/xcalpr.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xcalpr/xcalpr.c'\"
else
echo shar: Extracting \"'xcalpr/xcalpr.c'\" \(11836 characters\)
sed "s/^X//" >'xcalpr/xcalpr.c' <<'END_OF_FILE'
X#ifndef lint
Xstatic char    *sccsid = "@(#)xcalpr.c	1.11 (Hillside Systems) 11/15/93";
Xstatic char    *copyright = "@(#)Copyright 1993 Peter Collinson, Hillside Systems";
X#endif                          /* lint */
X#include "version.h"
X/***
X 
X* program name:
X        xcalpr.c
X* function:
X	Prints xcal calendar entries
X* switches:
X	-v	print version number, then exit
X	-f	name of output file
X	-d dir	Use "dir" instead of Calendar
X	-c	be compatible with the X calendar program
X		(ie flat structure in the Calendar directory)
X	-u user	Look at the calendar for that user
X	
X		followed by a date spec.
X		If no date spec then do this week
X		If date spec is just a number of month names, then
X			print those months
X			If month is `next' do the next month
X		If the months are followed by a year, then do those months
X			in that year
X		If the argument is just a year then do that year.
X		
X* libraries used:
X        standard
X* compile time parameters:
X        standard
X* history:
X        Written October 1993
X        Peter Collinson
X        Hillside Systems
X* (C) Copyright: 1993 Hillside Systems/Peter Collinson
X 
X        Permission to use, copy, modify, and distribute this software
X        and its documentation for any purpose is hereby granted to
X        anyone, provided that the above copyright notice appear
X        in all copies and that both that copyright notice and this
X        permission notice appear in supporting documentation, and that
X        the name of Peter Collinson not be used in advertising or
X        publicity pertaining to distribution of the software without
X        specific, written prior permission.  Hillside Systems makes no
X        representations about the suitability of this software for any
X        purpose.  It is provided "as is" without express or implied
X        warranty.
X 
X        Peter Collinson DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
X        SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
X        AND FITNESS, IN NO EVENT SHALL Peter Collinson BE LIABLE FOR
X        ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
X        WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
X        WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
X        ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
X        PERFORMANCE OF THIS SOFTWARE.
X 
X***/
X#include <stdio.h>
X#include <ctype.h>
X#include <string.h>
X#include <time.h>
X#include <pwd.h>
X#include <unistd.h>
X#if defined(NeXT)
X#include <sys/fcntl.h>
X#endif
X#include <sys/stat.h>
X
Xstatic char	*progname = "xcalpr";	/* name of program */
Xstatic char	*calendar = "Calendar";	/* name of calendar directory */
Xstatic int	compat;			/* if non-zero use calendar */
X					/* compatible files */
Xstatic int	calcompat;		/* write calendar format output */
Xstatic char	*calfmt;		/* printf format of a calendar file */
Xstatic char	*caldir;		/* name of a calendar directory */
Xstatic char	*user;			/* name of a user */
X
Xstatic char	*months[]	= {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
X				   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
X
Xstatic char	*daynames[]	= {"Sun", "Mon", "Tue", "Wed",
X				   "Thu", "Fri", "Sat"};
X
Xstatic char	*dayfiles[7];		/* connected contents of any dayfiles */
X
Xstatic FILE	*fout = stdout;
X	
Xstatic int mon[] = { 
X    31, 28, 31, 30,
X    31, 30, 31, 31,
X    30, 31, 30, 31,
X};
X
X/*
X * various strings
X */
Xstatic char	*memerr = "No more memory\n";
Xstatic char	*usage = "Usage: xcalpr [-d dir][-x][-c][-u user][-f file] [month list]\n";
X
Xchar	*malloc();
X
X/*
X * Routines
X */
Xstatic void	thisweek();
Xstatic void	showmonth();
Xstatic void	showyear();
Xstatic void	filenames();
Xstatic void	connectdaily();
Xstatic void	yearformat();
Xstatic void	outputday();
Xstatic void	outputdaily();
Xstatic char 	*connect_file();
Xstatic int	monthmatch();
Xstatic char 	*Strdup();
Xstatic void	fatal();
Xstatic void	error();
Xstatic char	*readbfile();
X
Xmain(argc, argv)
X	int	argc;
X	char	*argv[];
X{
X	register int	c;
X	extern char 	*optarg;
X	extern int	optind;
X	int		i;
X	char		**av;
X	int		ac;
X	int		yr;
X
X	while ((c = getopt(argc, argv, "d:u:f:cxv")) != EOF) {
X
X		switch (c) {
X		case 'c':
X			calcompat = 1;
X			break;
X		case 'd':
X			calendar = optarg;
X			break;
X		case 'f':
X			fout = fopen(optarg, "w");
X			if (fout == NULL)
X				fatal("Cannot open %s for writing\n", optarg);
X			break;
X		case 'u':
X			user = optarg;
X			break;
X		case 'v':
X			fprintf(stderr, "%s\n", version);
X			exit(0);
X		case 'x':
X			compat = 1;
X			break;
X		default:
X			fatal(usage);
X		}
X	}
X	filenames();
X	connectdaily();
X
X	if (optind == argc)
X		thisweek();
X	else {
X		/* 
X		 * this is a little complicated
X		 * the idea is to allow
X		 * xcalcat month
X		 * xcalcat month year
X		 * xcalcat year
X		 * the strategy is to scan forward for a year, storing any
X		 * months, if we find a year then output the months for
X		 * that year.
X		 */
X		av = (char **)calloc(argc, sizeof (char *));
X		if (av == NULL)
X			fatal(memerr);
X		ac = 0;
X		for (; optind < argc; optind++) {
X			if (!isdigit(*argv[optind])) {
X				av[ac++] = argv[optind];
X			} else {
X				yr = atoi(argv[optind]);
X				if (ac == 0)
X					showyear(yr);
X				else {
X					for (i = 0; i < ac; i++)
X						showmonth(av[i], yr, 0);
X					ac = 0;
X				}
X			}
X		}
X		if (ac) {
X			for (i = 0; i < ac; i++)
X				showmonth(av[i], 0, 1);
X		}
X	}
X	exit(0);	
X}
X
X/*
X *	Do this week
X */
Xstatic void
Xthisweek()
X{	
X	time_t		ti;
X	struct	tm	*tm;
X	int		yr;
X	int		i;
X
X	time(&ti);
X
X	for (i = 0; i < 7; i++) {
X		tm = localtime(&ti);
X		yr = tm->tm_year + 1900;
X		yearformat(yr);
X		outputday(yr, tm->tm_mon, tm->tm_mday, tm->tm_wday);
X		ti += 86400;
X	}
X}
X
X/*
X *	Do a month
X */
Xstatic void
Xshowmonth(mstr, yrval, autoinc)
X	char	*mstr;
X	int	yrval;
X	int	autoinc;
X{
X	time_t		ti;
X	struct	tm	*tm;
X	int		yr;
X	int		mn;
X	int		i;
X	int		wday;
X	int		startday = 1;
X
X	time(&ti);
X	tm = localtime(&ti);
X	yr = yrval ? yrval : tm->tm_year + 1900;
X
X	if (strcasecmp(mstr, "next") == 0) {
X		mn = tm->tm_mon+1;
X		if (mn == 12) {
X			mn = 0;
X			yr++;
X		}
X	} else
X	if (yrval == 0 && strcasecmp(mstr, "rest") == 0) {
X		mn = tm->tm_mon;
X		wday = FirstDay(mn, yr);	/* get number of days in month */
X		startday = tm->tm_mday+1;
X		if (startday > mon[mn]) {
X			startday = 1;
X			mn++;
X			if (mn == 12) {
X				mn = 0;
X				yr++;
X
X			}
X		}
X	} else {
X		mn = monthmatch(mstr);
X		if (mn == -1)
X			fatal("Cannot recognise month: %s\n", mstr);
X		if (autoinc && mn < tm->tm_mon)
X			yr++;
X	}
X
X	wday = FirstDay(mn, yr);
X	wday = wday + startday - 1;
X	wday %= 7;
X
X	yearformat(yr);
X
X	for (i = startday; i < mon[mn]; i++) {
X		outputday(yr, mn, i, wday);
X		wday++;
X		wday %= 7;
X	}
X}
X
X/*
X * do a year
X */
Xstatic void
Xshowyear(yr)
X	int	yr;
X{
X	int	m;
X
X	for (m = 0; m < 12; m++)
X		showmonth(months[m], yr, 0);
X}
X
X/*
X * organise filenames
X */
Xstatic void
Xfilenames()
X{
X	struct	passwd	*pw;
X	char		buf[256];
X	time_t		ti;
X	struct	tm	*tm;
X
X	if (user) {
X		pw = getpwnam(user);
X		if (pw == NULL)
X			fatal("Cannot get password information for %s\n", user);
X	} else {
X		pw = getpwuid(getuid());
X		if (pw == NULL)
X			fatal("Cannot get password information\n");
X	}
X	/*
X	 * get filename of Calendar directory
X	 */
X	if (*calendar != '.' && *calendar != '/') {
X		/* need to prepend the home directory */
X		(void) sprintf(buf, "%s/%s", pw->pw_dir, calendar);
X		calendar = Strdup(buf);
X	}
X
X	/*
X	 * See if we have a calendar directory
X	 */
X	if (access(calendar, F_OK) < 0)
X		fatal("%s does not exist\n", calendar);
X	
X}
X
X/*
X * Connect any daily files in memory
X */
Xstatic void
Xconnectdaily()
X{
X	int	i;
X	char	filename[256];
X	int	len;
X
X	for (i = 0; i < 7; i++) {
X		(void) sprintf(filename, "%s/xw%s", calendar, daynames[i]);
X
X		dayfiles[i] = connect_file(filename, &len);
X	}
X}
X
X/*
X * Make file formats from a year
X *
X * xcalendar files are all
X * xc<d><Mon><Year>
X * or
X * xc<dd><Mon><Year>
X *
X * where d or dd is the day (%02d would have been better)
X * <Mon> is a capitalised first three letters of the
X *         English month name. If you need compatibility
X *         don't redefine the short names in the resources
X *         for this program.
X * <Year> is the full numeric year.
X *
X * We will follow this BUT we will also make this program
X * create subdirectories for new years
X *         xy<Year>
X * to speed up file access
X */
Xstatic void
Xyearformat(year)
X	int	year;
X{
X	char	buf[256];
X
X	if (compat) 
X		(void) sprintf(buf, "%s/xc%%d%%s%d", calendar, year);
X	else	(void) sprintf(buf, "%s/xy%d/xc%%d%%s%d", calendar, year, year);
X	if (calfmt)
X		free(calfmt);
X	calfmt = Strdup(buf);
X	if (compat)
X		caldir = calendar;
X	else {
X		(void) sprintf(buf, "%s/xy%d", calendar, year);
X		if (caldir)
X			free(caldir);
X		caldir = Strdup(buf);
X	}
X}
X
X/*
X * Print data for one day
X */
Xstatic void
Xoutputday(year, mn, day, wday)
X	int	year;
X	int	mn;
X	int	day;
X	int	wday;
X{
X	char	filename[256];
X	char	line[BUFSIZ];
X	char	*p;
X	FILE	*fin;
X	
X	(void) sprintf(filename, calfmt, day, months[mn]);
X	if (fin = fopen(filename, "r")) {
X		while (fgets(line, sizeof line, fin) != NULL) {
X			p = strchr(line, '\n');
X			if (p)
X				*p = '\0';
X			for (p = line; isspace(*p); p++);
X			if (*p == '\0')
X				continue;
X			if (calcompat)
X				fprintf(fout, "%s %02d\t%s\n",
X				        months[mn], day, p);
X			else
X				fprintf(fout, "%s %02d %s %4d\t%s\n",
X				        daynames[wday], day, months[mn],
X					year, p);
X		}
X		fclose(fin);
X	}
X
X	/* check on daily file */
X	if (p = dayfiles[wday])
X		outputdaily(year, mn, day, wday, p);
X
X}
X
X/*
X * Output a daily file
X */
Xstatic void
Xoutputdaily(year, mn, day, wday, txt)
X	int	year;
X	int	mn;
X	int	day;
X	int	wday;
X	char	*txt;
X{
X	char	prefix[256];
X	char	*sol;
X	char	*eol;
X
X	if (calcompat)
X		(void) sprintf(prefix, "%s %02d\t", months[mn], day);
X	else
X		(void) sprintf(prefix, "%s %02d %s %4d\t", daynames[wday],
X			       day, months[mn], year);
X	
X	while (*txt) {
X		sol = txt;
X		while (*txt != '\n' && *txt != '\0')
X			txt++;
X		eol = txt;
X		while (*sol == ' ' || *sol == '\t')
X			sol++;
X		if (sol != eol) {
X			fputs(prefix, fout);
X			while (sol != eol) {
X				putc(*sol, fout);
X				sol++;
X			}
X			putc('\n', fout);
X		}
X		if (*eol == '\n')
X			txt++;
X	}	
X}
X	
Xstatic char *
Xconnect_file(filename, bytes)
X        char    *filename;
X        int     *bytes;
X{
X        int     fd;
X        struct  stat statb;
X        char    *fibase;
X 
X        if ((fd = open(filename, 0)) < 0) {
X		return NULL;
X	}
X 
X        if (fstat(fd, &statb) < 0)
X                fatal("Cannot fstat %s (shouldn't happen)\n", filename);
X 
X        if (statb.st_size == 0) {
X		*bytes = 0;
X		return;
X	}
X
X	fibase = readbfile(fd, statb.st_size);
X        if ((int)fibase == -1)
X                fatal("Cannot map %s into memory\n", filename);
X 
X        close(fd);      /* we have it now */
X
X	fibase[statb.st_size] = '\0';
X
X        *bytes = statb.st_size;
X        return(fibase);
X}
X
X/*
X * Attempt to recognise a month string
X * return a month (0-11) if OK
X * else -1
X */
Xstatic int
Xmonthmatch(str)
X	char	*str;
X{
X	register int i;
X	
X	for (i = 0; i < 12; i++) {
X		if (strncasecmp(str, months[i], 3) == 0)
X			return i;
X	}
X	return -1;
X}
X
X/*
X * private strdup this used to call the system strdup()
X * and fail on an error, but it seems that some systems don't a strdup()
X */
Xstatic char *
XStrdup(str)
X	char	*str;
X{
X	int	len;
X	char	*ret;
X
X	len = strlen(str) + 1;
X	ret = malloc(len);
X	if (ret == NULL)
X		fatal(memerr);
X	(void) memcpy(ret, str, len);
X	return ret;
X}
X
X/*
X * fatal routine
X * print an error message and exit
X * should use vprintf I guess
X */
Xstatic void
Xfatal(fmt, a, b, c)
X	char	*fmt;
X{
X	fprintf(stderr, "%s: ", progname);
X	fprintf(stderr, fmt, a, b, c);
X	exit(1);
X}
X
X/*
X * error routine
X */
Xstatic void
Xerror(fmt, a, b, c, d)
X	char	*fmt;
X{
X	fprintf(stderr, "%s: ", progname);
X	fprintf(stderr, fmt, a, b, c, d);
X}
X
X/*
X * malloc some memory and
X * read the file into it
X */
Xstatic char *
Xreadbfile(fd, len)
X	int	fd;
X	int	len;
X{
X	char	*base;
X	
X	base = (char *) malloc(len+1);
X	if (read(fd, base, len) != len)
X		return ((char *)-1);
X	return base;
X}
END_OF_FILE
if test 11836 -ne `wc -c <'xcalpr/xcalpr.c'`; then
    echo shar: \"'xcalpr/xcalpr.c'\" unpacked with wrong size!
fi
# end of 'xcalpr/xcalpr.c'
fi
echo shar: End of archive 4 \(of 8\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 8 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
