home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / 3b1 / volume02 / pcmgr / part01 < prev    next >
Encoding:
Internet Message Format  |  1992-07-14  |  56.0 KB

  1. Path: comp-sources-3b1
  2. From: davegalaxia.network23.com (David H. Brierley)
  3. Subject:  v02i017:  pcmgr: replacement status and window manager, Part01/03
  4. Newsgroups: comp.sources.3b1
  5. Approved: dave@galaxia.network23.com
  6. X-Checksum-Snefru: 6c85d2cd 702496d8 dea7b359 4ab2f9dd
  7.  
  8. Submitted-by: davegalaxia.network23.com (David H. Brierley)
  9. Posting-number: Volume 2, Issue 17
  10. Archive-name: pcmgr/part01
  11.  
  12. This is the replacement for the status manager (smgr) and the window
  13. manager (wmgr) that I have alluded to several times in the past.  I
  14. would probably still consider this software to be at the beta-test
  15. level, but the program is pretty solid and well tested.  In it's basic
  16. form, I have been running this software for almost 3 years on my 3b1.
  17. During that time it has undergone sporadic development to incorporate
  18. things like the /dev/error processing and the pcal alarm handling.
  19.  
  20. Read the README and INSTALL files for all the sordid details, try out
  21. the program on your machine, and send me any suggestions you have for
  22. making it better.
  23.  
  24. #! /bin/sh
  25. # This is a shell archive.  Remove anything before this line, then unpack
  26. # it by saving it into a file and typing "sh file".  To overwrite existing
  27. # files, type "sh file -c".  You can also feed this as standard input via
  28. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  29. # will see the following message at the end:
  30. #        "End of archive 1 (of 3)."
  31. # Contents:  INSTALL MANIFEST Makefile README config.dist display.c
  32. #   getid.c pcmgr.c pcmgr.h
  33. # Wrapped by dave@galaxia on Tue Jul 14 21:15:42 1992
  34. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  35. if test -f 'INSTALL' -a "${1}" != "-c" ; then 
  36.   echo shar: Will not clobber existing file \"'INSTALL'\"
  37. else
  38. echo shar: Extracting \"'INSTALL'\" \(1456 characters\)
  39. sed "s/^X//" >'INSTALL' <<'END_OF_FILE'
  40. XInstallation instructions for the pcmgr program.
  41. X
  42. X0. Read the README file before proceeding.
  43. X
  44. X1. Copy config.dist to config.h
  45. X
  46. X2. Edit config.h to select the compile time options which best
  47. X   suit your likings.
  48. X
  49. X3. Edit Makefile to make sure everything is correct for your system.
  50. X
  51. X4. Type make.
  52. X
  53. X5. Install the pcmgr binary either in /etc or in /etc/daemons.
  54. X
  55. X6. Edit the /etc/rc file so that the wmgr and smgr are no longer
  56. X   started.  It is also recommended that you not run the phmgr
  57. X   program.  Make sure that a cron program is being started, either
  58. X   the standard cron that comes with the system or one of the
  59. X   replacement cron programs.  If you installed pcmgr in the
  60. X   /etc/daemons directory then no further changes are required.  If
  61. X   you installed pcmgr in the /etc/directory, add a line to the rc
  62. X   file to start the program.  No command line arguments are required
  63. X   and an ampersand at the end of the line is not required either.
  64. X
  65. X7. Double check the changes you have just made to /etc/rc.
  66. X
  67. X8. Triple check the changes.  This is very important because if you
  68. X   screw this up you could have problems rebooting your machine.
  69. X
  70. X9. Reboot the machine.
  71. X
  72. X10. Go back and read the README file again.
  73. X
  74. X
  75. XI will admit that step number 6 is a vague blob and it could probably
  76. Xbe done a lot nicer.  On the other hand, if you are not comfortable
  77. Xwith editing the /etc/rc file then you probably should have someone
  78. Xhelp you with this step anyway.
  79. END_OF_FILE
  80. if test 1456 -ne `wc -c <'INSTALL'`; then
  81.     echo shar: \"'INSTALL'\" unpacked with wrong size!
  82. fi
  83. # end of 'INSTALL'
  84. fi
  85. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  86.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  87. else
  88. echo shar: Extracting \"'MANIFEST'\" \(530 characters\)
  89. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  90. X   File Name        Archive #    Description
  91. X-----------------------------------------------------------
  92. X INSTALL                    1    
  93. X MANIFEST                   1    
  94. X Makefile                   1    
  95. X README                     1    
  96. X config.dist                1    
  97. X display.c                  1    
  98. X getid.c                    1    
  99. X hotkey.c                   2    
  100. X loadavgd.c                 2    
  101. X pcmgr.c                    1    
  102. X pcmgr.h                    1    
  103. X subr.c                     2    
  104. X sysinfo.c                  3    
  105. X windows.c                  2    
  106. END_OF_FILE
  107. if test 530 -ne `wc -c <'MANIFEST'`; then
  108.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  109. fi
  110. # end of 'MANIFEST'
  111. fi
  112. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  113.   echo shar: Will not clobber existing file \"'Makefile'\"
  114. else
  115. echo shar: Extracting \"'Makefile'\" \(1759 characters\)
  116. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  117. X##########################################################################
  118. X# Makefile for pcmgr program                                             #
  119. X# Copyright 1992 David H. Brierley, All rights reserved                  #
  120. X##########################################################################
  121. X
  122. X# Configuration Section
  123. X
  124. X# this programs requires an ANSI C compiler
  125. X# compile time options are controlled by editing the config.h file
  126. XCC    = gcc
  127. XOPTIMIZE= # -O
  128. XDEBUG    = # -g
  129. XCFLAGS    = -fpcc-struct-return -fstrength-reduce $(OPTIMIZE) $(DEBUG)
  130. X
  131. X# on my system, -lgnu contain the gnulib stuff, -ltam contains the 3.51m
  132. X# version of the tam routines, and -lutmp contain the 3.51m version of
  133. X# the getutent routines.  modify as appropriate for your system.
  134. XLIBS    = -lgnu -ltam -lutmp
  135. X
  136. X# link using ccc to get the shared library.  alternatives are using gcc
  137. X# with the -shlib option or using ld directly.
  138. XLD    = ccc
  139. XLDFLAGS    =
  140. X
  141. X# --- End of user configurable items ---
  142. X
  143. XPCMGR    = pcmgr.o display.o getid.o hotkey.o subr.o sysinfo.o windows.o
  144. X
  145. Xpcmgr:    $(PCMGR)
  146. X    $(LD) $(LDFLAGS) $(PCMGR) $(LIBS)
  147. X    mv a.out $@
  148. X
  149. Xloadavgd: loadavgd.o
  150. X    $(LD) $(LDFLAGS) loadavgd.o $(LIBS)
  151. X    mv a.out $@
  152. X
  153. X$(PCMGR): config.h pcmgr.h
  154. X
  155. X# pcmgr.h must be rebuilt if you change the arguments to any procedure or
  156. X# if you add or delete a procedure. this is normally only used if you are
  157. X# doing active development of the code.  this target has no dependencies
  158. X# and thus will never be built by default.  if it needs to be built, gcc
  159. X# should complain violently because the function prototypes will be wrong.
  160. Xpcmgr.h:
  161. X    mkptypes -A `echo $(PCMGR) | sed -e 's/\.o/.c/g'` > temp.h
  162. X    if cmp -s pcmgr.h temp.h; then rm temp.h; else mv temp.h pcmgr.h; fi
  163. X
  164. Xclean:
  165. X    rm -f $(PCMGR) pcmgr loadavgd.o loadavgd core
  166. END_OF_FILE
  167. if test 1759 -ne `wc -c <'Makefile'`; then
  168.     echo shar: \"'Makefile'\" unpacked with wrong size!
  169. fi
  170. # end of 'Makefile'
  171. fi
  172. if test -f 'README' -a "${1}" != "-c" ; then 
  173.   echo shar: Will not clobber existing file \"'README'\"
  174. else
  175. echo shar: Extracting \"'README'\" \(12740 characters\)
  176. sed "s/^X//" >'README' <<'END_OF_FILE'
  177. XREADME file for "pcmgr" program.
  178. X
  179. XWritten by David H. Brierley, with a few bits and pieces borrowed from others.
  180. XAppropriate credit is noted in the individual source files.
  181. X
  182. XCopyright 1992 David H. Brierley, All rights reserved.
  183. X
  184. X(copyright obviously does not apply to those source modules which were written
  185. Xby other people.)
  186. X
  187. X
  188. XThis is the "pcmgr" program.  It's purpose is to manage the windows and status
  189. Xlines on a PC7300/3B1 computer.  It replaces most of the functions of the "wmgr"
  190. Xand "smgr" programs.  The one function that I know of that it is not intended to
  191. Xreplace is the "cron" function.  For that you should either use the cron program
  192. Xthat is supplied with the machine or get one of the replacement cron programs.
  193. X(I personally use the cron replacement program that was written by Paul Vixie)
  194. X
  195. XThis program also incorporates the functionality of the "hotkey" program which
  196. Xwas written by me and released several years back, and the "sysinfo" program
  197. Xwhich was originally written by Lenny Tropiano.
  198. X
  199. XThis program utilizes the entire top status line and registers for control of
  200. Xthe various function keys.  As a result, it should not be run in conjunction
  201. Xwith the phone manager (phmgr) or any other program which attempts to write on
  202. Xthe top status line.
  203. X
  204. XThe following description of the program operation assumes that all of the
  205. Xdefault options were selected at compile time.  Read the config.dist file for
  206. Xinformation about customizing the appearance and operation of this program.
  207. X
  208. X
  209. X********** The displays:  **********
  210. X
  211. XThe top status line is split into three primary sections.  The center section
  212. Xcontains the current date and time.  The section to the left of this contains
  213. Xthe current window number and the title of that window.  For example, as I am
  214. Xediting this file the status line contains the following information:  "w2 Edit:
  215. XREADME".  To the right of the date will be a series of icons.  The first icon
  216. Xwill look like an envelope and will cause the mail program to be run when you
  217. Xclick on it with the mouse.  I recommend getting the "email" program for this
  218. Xpurpose.  The next icon will be a box that contains the word "login:".  Clicking
  219. Xon this icon will cause a new full-screen window with a login prompt to be
  220. Xcreated.  The "window" program, which was posted to the old unix-pc.sources
  221. Xgroup, is used to create this window.  If you need a copy of "window" let me
  222. Xknow and I will send it to you.  The next icon on the display will look like a
  223. Xsmall calendar (if you use your imagination), and clicking on it will cause the
  224. X"pcal" program to be run.  If there are any messages to be displayed (see
  225. Xbelow), next there will be a box with the word "Msgs" in it.  Clicking on this
  226. Xbox will cause your messages to be displayed.  Finally, to the far right of the
  227. Xscreen will be a box containing the letter F. If you have more than one
  228. Xpartition mounted, clicking on this icon will control which partition is
  229. Xdisplayed on the bottom status line.  This icon can also be configured to
  230. Xdisplay a list of user definable functions.
  231. X
  232. XThe next to the bottom line displays a list of what users are logged in, how
  233. Xmany mail messages each logged in user has, what the current "load average" is
  234. X(requires use of the "loadavgd" program, a copy of which is supplied with this
  235. Xprogram), and the length of time that the system has been up.
  236. X
  237. XThe very bottom line contains information about the currently selected file
  238. Xsystem, as well as information about currently available swap space and memory.
  239. XThe file system information includes the number of blocks and inodes for the
  240. Xfile system, either the amount used or the amount free.  These numbers are then
  241. Xfollowed by either the total number of blocks and inodes or a percentage.  Refer
  242. Xto config.h for information on how to select these options.
  243. X
  244. XThe next release of this program will probably contain options for a variety of
  245. Xdisplay formats on the bottom status lines.
  246. X
  247. X
  248. X********* Using the mouse **********
  249. X
  250. XThe pcmgr uses all three of the mouse buttons to perform different actions.
  251. XMouse button presses are only recognized when the mouse pointer is located in
  252. Xthe status line at the top of the screen.
  253. X
  254. XButton 1 (left button):  pressing B1 when the mouse pointer is positioned over
  255. Xone of the icons will cause the action indicated by that icon to be performed.
  256. XIf the mouse pointer is not located over one of the icons, the bell will be
  257. Xrung.
  258. X
  259. XButton 2 (middle button):  pressing B2 will toggle the visibility of the mouse
  260. Xpointer.  This only affects the mouse pointer visibility while the mouse pointer
  261. Xis positioned on the status line.  If you move the mouse pointer into one of the
  262. Xwindows then mouse pointer visibility is controlled by that window.  Mouse
  263. Xpointer visibility is turned on by default.  Making the mouse pointer
  264. Xinvisible seems to speed up various screen functions such as scrolling and
  265. Xredraw.  This can be very helpful when you are using the modem to dial into
  266. Xanother system.
  267. X
  268. XButton 3 (right button):  pressing B3 will cause a menu of user defined
  269. Xfunctions to be displayed.  User defined functions are described below under the
  270. Xheading "hotkey operations".  The displayed list of functions will also include
  271. Xentries for reading mail, creating a login window, and reading messages.
  272. X
  273. X
  274. X********** Mouse pointer bitmap **********
  275. X
  276. XWhen the mouse pointer is located in the status line, the shape will change from
  277. Xthe default arrow shape so a small rectangular box.  This is done for two
  278. Xreasons.  First, it makes the pointer bitmap fit completely within the status
  279. Xline.  Second, it makes it visibly apparrent as to whether or not the mouse
  280. Xpointer is at the very edge of the window or actually positioned on the status
  281. Xline.
  282. X
  283. X
  284. X********** Keyboard special key processing **********
  285. X
  286. XSince the pcmgr program is intended to replace the wmgr and smgr programs, it
  287. Xwas designed to process the various special keyboard commands that were
  288. Xpreviously processed by those two programs.  In particular, it supports the
  289. Xfollowing special keys by performing the action indicated:
  290. X
  291. XSuspd, Rsume - pressing either Suspd or Rsume will cause a list of currently
  292. Xavailable windows to be displayed, with the currently active window being
  293. Xhiglighted as the default choice.  You may then use the arrow keys to directly
  294. Xselect any window to become the new active window.
  295. X
  296. Xs-Suspd, s-Rsume - pressing either shift-Suspd or shift-Rsume will cause either
  297. Xthe next window in the list or the previous window in the list to become the new
  298. Xactive window.  s-Suspd selects the previous window and s-Rsume selects the next
  299. Xwindow.  The list of available windows is always maintained in window number
  300. Xorder.
  301. X
  302. XMsg, s-Msg - pressing either Msg or shift-Msg will cause any currently available
  303. Xmessages to be displayed.
  304. X
  305. Xs-Print - pressing shift-Print will invoke the "sprint" program to produce a
  306. Xscreen dump.  A couple of times when I was testing this the printed screen
  307. Xdump included the small "please wait" window that is created by sprint.  I'm
  308. Xnot sure why this happened and I was not able to reliably reproduce the
  309. Xerror in an effort to fix it.  It's possible that it is related to system
  310. Xloading.
  311. X
  312. Xs-F1 thru s-F8 - all shifted function keys perform the user defined function
  313. Xthat has been associated with them.  Refer to the section below labeled "hotkey
  314. Xoperations".
  315. X
  316. X
  317. X********** Messages **********
  318. X
  319. XThe pcmgr program reads and processes all records that are written to the
  320. X/dev/error device.  All records read are written out to the log file,
  321. X/usr/adm/errfile.  Records which conform to the format written by the eprintf()
  322. Xprocedure are parsed for possible display or other action.  Records which
  323. Xcontain a type field of S (system), P (popup), or D (display) are added to a
  324. Xqueue of messages to be displayed when you press the Msg button.  The action
  325. Xcode of the message is ingored with the exception of code L (logfile).  The L
  326. Xaction code simply records the message in the standard log file, multiple log
  327. Xfiles are not supported.
  328. X
  329. XRecords of type C (calendar) which also have an action code of E (exec) are
  330. Xadded to a list of calendar alarms.  When the specified time is reached the pcal
  331. Xprogram will be run, using the arguments specified in the text field of the
  332. Xrecord.
  333. X
  334. XUnlike the original smgr program, the pcmgr program is very paranoid about the
  335. Xcontents of the records read from /dev/error.  This is the reason that the
  336. Xaction code is ignored in the various messages.  The standard eprintf() format
  337. Xspecifies that if the action code is E (exec) then the text field contains a
  338. Xcommand to be executed.  Since the smgr program is not normally noted for being
  339. Xoverly security conscious, one would presume that this capability represents a
  340. Xsecurity hole large enough to drive several large trucks through.  The pcmgr
  341. Xprogram is so paranoid that the only program it will allow to the executed is
  342. X"/usr/bin/pcal" and even then it does not trust the command line arguments
  343. Xspecified in the record.
  344. X
  345. X
  346. X********** Program security **********
  347. X
  348. XSince I was just talking about security holes, I should mention what steps I
  349. Xhave taken in regard to security.  As I mentioned above, random programs may not
  350. Xbe executed simply by writing a properly formatted message to /dev/error.  The
  351. Xlogging feature of /dev/error is limited to only one file so that the worst a
  352. Xuser can do is use up all the disk space (but they can do that other ways just
  353. Xas easily).  When programs are to be executed due to clicking on one of the
  354. Xicons (mail or pcal), care is taken to determine the uid and gid of the
  355. Xcurrently active user and switch to that uid before doing the exec().  The
  356. Xcurrent directory is also changed to be the home directory of the currently
  357. Xactive user.  If there is no active user, i.e. no-one is logged in but you click
  358. Xon the mail icon, then no action is taken.  These precautions are also taken
  359. Xwhen using the "hotkey" feature.  All told, I have taken what I feel are
  360. Xreasonable measures to insure that this program will not compromise the security
  361. Xof your system.  I even made sure I never used the gets() routine.
  362. X
  363. X
  364. X********** Hotkey Operations **********
  365. X
  366. XThe shifted function keys are processed as special user-defined "hotkeys".
  367. XEach user of the machine is allowed to create a file which gives a list of
  368. Xkey numbers, what size window is to be created when the key is pressed, and
  369. Xwhat command is to be executed in that window.  The format of the file is
  370. Xlisted below.  The uid and gid will be set to that of the currently active
  371. Xuser, the current directory will be set to the users home directory, and the
  372. Xenvironment variables HOME and LOGNAME will be set to the appropriate
  373. Xvalues.
  374. X
  375. XThe key bindings for the "hotkey" operations are stored in a file called
  376. X".hotkey" in each users home directory.
  377. X
  378. XThere can be as many entries as desired in the binding file but there are
  379. Xonly eight function keys across the top of the keyboard.  Entries numbered
  380. Xone through eight will be available simply by pressing the shifted function
  381. Xkeys, all other entries will only be available via the function menu (mouse
  382. Xbutton B3).
  383. X
  384. X
  385. X********** Format of hotkey binding file **********
  386. X
  387. XEach line of the hotkey binding file has the following format:
  388. X
  389. Xnumber,rows,cols;name command options
  390. X
  391. XEach entry must consist of only one line, although the lines may be up to
  392. X256 characters long.  The elements of each line are defined as follows:
  393. X
  394. Xnumber    = key number, each entry must have a unique key number, number 1
  395. X    through 8 are bound to the shifted function keys.
  396. X
  397. Xrows,cols = the size of the window to be created, specifying a size of 24,80
  398. X    causes a borderless full screen window to be created.
  399. X
  400. Xname    = an optional name for this entry, if no name is specified the name
  401. X    will be set to the first word of the command, if the name is omitted
  402. X    the semi-colon should also be omitted, the name field is only used
  403. X    when displaying the menu of user-defined functions
  404. X
  405. XThe remainder of the line specify the command to be run and any options to
  406. Xbe passed to that command.  The command will be run by first trying to use
  407. Xthe execvp() routine and then by using "sh -c".  This allows you to specify
  408. Xcommands without using full pathnames, provided they can be located using
  409. Xthe default system search PATH as defined by "/etc/rc".
  410. X
  411. X
  412. X
  413. X********** **********
  414. X
  415. XWell, that's everything that I can think of that you should need to know to
  416. Xbe able to use the pcmgr program.  As is always the case with any program
  417. Xyou get from usenet, the definitive answers to all of your questions are
  418. Xincluded in the source code.  If you have questions that require looking at
  419. Xthe source code to answer, please email them to me so that I can include
  420. Xthem in the next release of these notes.
  421. X
  422. XDavid H. Brierley
  423. Xdave@galaxia.network23.com
  424. END_OF_FILE
  425. if test 12740 -ne `wc -c <'README'`; then
  426.     echo shar: \"'README'\" unpacked with wrong size!
  427. fi
  428. # end of 'README'
  429. fi
  430. if test -f 'config.dist' -a "${1}" != "-c" ; then 
  431.   echo shar: Will not clobber existing file \"'config.dist'\"
  432. else
  433. echo shar: Extracting \"'config.dist'\" \(6515 characters\)
  434. sed "s/^X//" >'config.dist' <<'END_OF_FILE'
  435. X/*
  436. X * pcmgr program configuration file.
  437. X *
  438. X * Read through this file carefully and decide if you need to make any changes
  439. X * to the items indicated.  There are several #define items that are either
  440. X * defined or undefined and are used to control the operation of the program.
  441. X * These are usually marked "define this if you want ...".  There are also
  442. X * several #define items that define data files.  You might want to change
  443. X * these to conform to any local standards you have developed.
  444. X *
  445. X * As a general rule, you should not change any of the #define items that
  446. X * have values associated with them, unless the comments explicitly tell you
  447. X * to change them.  Also (and hopefully this is obvious), do not change any of
  448. X * the structure definitions.
  449. X *
  450. X * This file should probably be split into two pieces, one containing things
  451. X * you can change and one containing things you cant change.  Maybe in the
  452. X * next release.
  453. X *
  454. X * Copyright 1992 David H. Brierley, All rights reserved.
  455. X * @(#) config.dist: version 2.1 7/14/92 21:12:16
  456. X */
  457. X
  458. X/*
  459. X * define SYNC_MINUTE if you want the updates to be synced on the minute, or
  460. X * undefine it to simply wait 60 seconds between updates
  461. X */
  462. X#define        SYNC_MINUTE
  463. X
  464. X/*
  465. X * Define the length of time (in seconds) before old calendar alarms are
  466. X * discarded.  Normally, calendar alarms are saved up until the user is
  467. X * logged in to receive them.  By setting this to a small number, alarms
  468. X * are discarded quickly.  Setting to a really large number will effectively
  469. X * keep them around forever (or until the user logs in to receive them).
  470. X * Recommended possible values: 1 day or 1 hour.
  471. X */
  472. X#define    DISCARD_TIME    ((24 * 60) * 60)    /* one day */
  473. X/*efine DISCARD_TIME    ((01 * 60) * 60)    /* one hour */
  474. X
  475. X/*
  476. X * Define the hotkey data structure.
  477. X */
  478. X#define H_NAME_MAX    32
  479. X#define H_CMD_MAX    256
  480. X
  481. Xstruct hotkey {
  482. X    struct hotkey  *h_next;
  483. X    int             h_key;
  484. X    int             h_height;
  485. X    int             h_width;
  486. X    char            h_name[H_NAME_MAX + 1];
  487. X    char            h_cmd[H_CMD_MAX];
  488. X};
  489. Xtypedef struct hotkey HotKey;
  490. X
  491. X/*
  492. X * Mouse location code meanings
  493. X */
  494. X#define        DO_NOTHING    0
  495. X#define        DO_LOGIN    10
  496. X#define        DO_EMAIL    11
  497. X#define        DO_CALNDR    12
  498. X#define        DO_MSGS        13
  499. X#define        DO_TOGGLE    20
  500. X#define        DO_MENU        30
  501. X
  502. X/*
  503. X * If you want the F button on the top line to display a menu of commands to
  504. X * be run (as defined by hotkey functions) then define DO_FBUTTON to be the
  505. X * same as DO_MENU.  On the other hand, if you want the F button to cycle
  506. X * through the list of mounted file systems then define it to something else.
  507. X * If the F button is defined as bringing up the function menu then the "Msg"
  508. X * key is used to sycle through the list of mounted file systems.  Normally
  509. X * the "Msg" key is used to display your messages.
  510. X */
  511. X#undef        DO_FBUTTON    DO_MENU    /* function menu */
  512. X#define        DO_FBUTTON    31    /* filesystem cycle */
  513. X
  514. X/*
  515. X * Define position and size of master window
  516. X */
  517. X#define        W_XPOS        0
  518. X#define        W_YPOS        0
  519. X#define        W_WIDTH        (9 * 80)
  520. X#define        W_HEIGHT    (12 * 1)
  521. X
  522. X/*
  523. X * Definitions of structures used to hold info about who is logged on.
  524. X */
  525. Xstruct U_Info {
  526. X    char            name[9];
  527. X    int             dev_no;
  528. X    int             uid;
  529. X    int             gid;
  530. X    int             access;
  531. X};
  532. Xtypedef struct U_Info U_Info;
  533. X
  534. Xstruct W_Info {
  535. X    int             access;
  536. X    int             uid;
  537. X};
  538. Xtypedef struct W_Info W_Info;
  539. X
  540. X/*
  541. X * Structure definition for message queue read from /dev/error
  542. X */
  543. Xstruct emsg {
  544. X    int                mtype;
  545. X    int             mact;
  546. X    int             alrm_date;
  547. X    int             alrm_time;
  548. X    char           *muser;
  549. X    char           *mtext;
  550. X    struct emsg    *mnext;
  551. X};
  552. X
  553. X/*
  554. X * Definitions related to processing the /dev/error device
  555. X */
  556. X
  557. X#define        DEV_ERROR    "/dev/error"
  558. X#define        ERR_LOGFILE    "/usr/adm/errfile"
  559. X
  560. X
  561. X/*
  562. X * the following define one less than the lowest window number and one more
  563. X * than the highest window number.
  564. X */
  565. X#define        MIN_WINDOW    0
  566. X#define        MAX_WINDOW    13
  567. X
  568. X/*
  569. X * Define the program to be run to create a new login window
  570. X */
  571. X#ifndef        WINDOW_PROG
  572. X#define        WINDOW_PROG    "/usr/local/bin/window"
  573. X#endif
  574. X
  575. X/*
  576. X * Define the various alarm levels.  If the indicated value is exceeded then
  577. X * that portion of the display will be highlighted.  Note that all values
  578. X * except MAX_LOAD_AVG represent values which the associated item is not
  579. X * allowed to drop below.  Note also that the block and inode levels are
  580. X * based on percentages of free space, irregardless of the value selected for
  581. X * SHOW_DISK_FREE in the section below.  Note also that the values for free
  582. X * disk space and free inodes are based on percentages regardless of whether
  583. X * or not you select the SHOW_DISK_TOTALS option in the section below.
  584. X */
  585. X#define    MAX_LOAD_AVG    1.0    /* maximum allowed load average */
  586. X#define MIN_BLK_PCT    7.5    /* minimum percent of free disk space */
  587. X#define MIN_INO_PCT    10.0    /* minimum percent of free inodes */
  588. X#define MIN_SWAP    500    /* minimum amount of free swap space */
  589. X#define MIN_FREE    500    /* minimum amount of free memory */
  590. X
  591. X/*
  592. X * The normal info displayed about the file system is the number of blocks
  593. X * used and the percent of blocks used.  To display the number of blocks free
  594. X * instead, define SHOW_DISK_FREE.  To also display the total number of
  595. X * blocks, define SHOW_DISK_TOTALS.  This option can be used with or without
  596. X * the SHOW_DISK_FREE option.  If the SHOW_DISK_TOTALS option is selected
  597. X * then the percentages will not be printed.
  598. X * 
  599. X * The display also includes information about the number of inodes and both of
  600. X * these options are also applied to that information.
  601. X */
  602. X#define    SHOW_DISK_FREE        /* define this to display free space */
  603. X#undef    SHOW_DISK_TOTALS    /* define this to display totals */
  604. X
  605. X/*
  606. X * If the PICKY_SLK_TEST option is defined then the slk lines will be
  607. X * subjected to farily extensive testing before they are over-written with
  608. X * the current status info.  The default test is that the second slk line
  609. X * is scanned for the string "blks" surrounded by blanks.  If both the
  610. X * PICKY_SLK_TEST option and the STANDARD_SLK_TEST option are disabled then
  611. X * no tests will be performed on the slk lines.
  612. X *
  613. X * It is recommended that you define STANDARD_SLK_TEST and leave PICKY_SLK_TEST
  614. X * undefined.  This gives you a reasonable amount of protection against having
  615. X * the slk lines overwritten when they are being used by another program but
  616. X * minimizes the amount of processing required.
  617. X */
  618. X#define    STANDARD_SLK_TEST    /* standard slk tests */
  619. X#undef    PICKY_SLK_TEST        /* picky tests */
  620. END_OF_FILE
  621. if test 6515 -ne `wc -c <'config.dist'`; then
  622.     echo shar: \"'config.dist'\" unpacked with wrong size!
  623. fi
  624. # end of 'config.dist'
  625. fi
  626. if test -f 'display.c' -a "${1}" != "-c" ; then 
  627.   echo shar: Will not clobber existing file \"'display.c'\"
  628. else
  629. echo shar: Extracting \"'display.c'\" \(9253 characters\)
  630. sed "s/^X//" >'display.c' <<'END_OF_FILE'
  631. X/*---------------------------------------------------------------------------
  632. X *
  633. X * Program: pcmgr
  634. X * Module:  display
  635. X *
  636. X * This module contains routines for displaying the status line across the
  637. X * top of the screen.
  638. X *
  639. X * Copyright 1992 David H. Brierley, All rights reserved.
  640. X *-------------------------------------------------------------------------*/
  641. X
  642. X#include <stdio.h>
  643. X#include <sys/types.h>
  644. X#include <sys/font.h>
  645. X#include <sys/window.h>
  646. X#include <time.h>
  647. X#include <signal.h>
  648. X#include <string.h>
  649. X#include <status.h>
  650. X#include <utmp.h>
  651. X#include <pwd.h>
  652. X#include <sys/stat.h>
  653. X#include <nlist.h>
  654. X#include <fcntl.h>
  655. X#include <ctype.h>
  656. X#include <termio.h>
  657. X#include <malloc.h>
  658. X#include <setjmp.h>
  659. X#include <sys/wd.h>
  660. X#include <track.h>
  661. X#include <tam.h>
  662. X#include <menu.h>
  663. X#include <kcodes.h>
  664. X#include <errno.h>
  665. X#include <sys/sysinfo.h>
  666. X#include <sys/var.h>
  667. X#include <sys/syslocal.h>
  668. X#include <sys/file.h>
  669. X#include <sys/text.h>
  670. X#include <sys/tune.h>
  671. X#include <sys/user.h>
  672. X#include <sys/vmmac.h>
  673. X#include <sys/sysmacros.h>
  674. X
  675. X#include "config.h"
  676. X#include "pcmgr.h"
  677. X
  678. Xstatic char    *Sccs_Id = "@(#) display.c: version 2.1 7/14/92 21:12:20";
  679. X
  680. Xchar           *day_names[] = {
  681. X    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  682. X};
  683. X
  684. Xchar           *month_names[] = {
  685. X    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  686. X    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  687. X};
  688. X
  689. X/*
  690. X * WARNING: if the size or location of the various icons changes,
  691. X * the parse_mouse routine must also be changed.  This includes the
  692. X * size and shape of the mouse pointer icon.
  693. X */
  694. X
  695. X/* array ARRAY contains a picture */
  696. X/*     48 pixels wide  */
  697. X/* and 12 pixels high. */
  698. X/* for wrastop calls use the following options: */
  699. X/* srcwidth = 6, width = 48, and height = 12.  */
  700. X
  701. Xstatic unsigned short loginpat[36] = {
  702. X    0xffff, 0xffff, 0x0003, 0x0001, 0x0000, 0x0002, 0x0011, 0x0008,
  703. X    0x0002, 0x0011, 0x0000, 0x0002, 0xe791, 0x13c9, 0x0002, 0x2491,
  704. X    0x1249, 0x0002, 0x2491, 0x0249, 0x0002, 0xe491, 0x1249, 0x0002,
  705. X    0x0791, 0x1249, 0x0002, 0xe001, 0x0001, 0x0002, 0x0001, 0x0000,
  706. X    0x0002, 0xffff, 0xffff, 0x0003
  707. X};
  708. X
  709. X/* array ARRAY contains a picture */
  710. X/*     48 pixels wide  */
  711. X/* and 12 pixels high. */
  712. X/* for wrastop calls use the following options: */
  713. X/* srcwidth = 6, width = 48, and height = 12.  */
  714. X
  715. Xstatic unsigned short envelope[36] = {
  716. X    0xffff, 0xffff, 0x0003, 0x0007, 0x8000, 0x0003, 0x0039, 0x7000,
  717. X    0x0002, 0x01c1, 0x0e00, 0x0002, 0x0e01, 0x01c0, 0x0002, 0x7001,
  718. X    0x0038, 0x0002, 0x8001, 0x0007, 0x0002, 0x0001, 0x0000, 0x0002,
  719. X    0x0001, 0x0000, 0x0002, 0x0001, 0x0000, 0x0002, 0x0001, 0x0000,
  720. X    0x0002, 0xffff, 0xffff, 0x0003
  721. X};
  722. X
  723. X/* array ARRAY contains a picture */
  724. X/*     48 pixels wide  */
  725. X/* and 12 pixels high. */
  726. X/* for wrastop calls use the following options: */
  727. X/* srcwidth = 6, width = 48, and height = 12.  */
  728. X
  729. Xstatic unsigned short calndr_pat[36] = {
  730. X    0xfffc,    0xffff,    0x0000,    0x0004,    0x8000,    0x0000,    0x0004,    0x8000,
  731. X    0x0000,    0xfffc,    0xffff,    0x0000,    0x4444,    0x8888,    0x0000,    0xfffc,
  732. X    0xffff,    0x0000,    0x4444,    0x8888,    0x0000,    0xfffc,    0xffff,    0x0000,
  733. X    0x4444,    0x8888,    0x0000,    0xfffc,    0xffff,    0x0000,    0x4444,    0x8888,
  734. X    0x0000,    0xfffc,    0xffff,    0x0000     
  735. X};
  736. X
  737. X/* array ARRAY contains a picture */
  738. X/*     48 pixels wide  */
  739. X/* and 12 pixels high. */
  740. X/* for wrastop calls use the following options: */
  741. X/* srcwidth = 6, width = 48, and height = 12.  */
  742. X
  743. Xstatic unsigned short msgs_pat[36] = {
  744. X    0xffff, 0xffff, 0x0003, 0x0001, 0x0000, 0x0002, 0x0001, 0x0000,
  745. X    0x0002, 0x0361, 0x0000, 0x0002, 0xf3e1, 0x0f3c, 0x0002, 0x12a1,
  746. X    0x0124, 0x0002, 0xf2a1, 0x0f24, 0x0002, 0x8221, 0x083c, 0x0002,
  747. X    0xf221, 0x0f20, 0x0002, 0x0001, 0x003c, 0x0002, 0x0001, 0x0000,
  748. X    0x0002, 0xffff, 0xffff, 0x0003
  749. X};
  750. X
  751. X/* no_msgs is an array of the same size as msgs_pat but with */
  752. X/* all of the cells set to 0.  it is used to blank out the */
  753. X/* display area */
  754. X
  755. Xstatic unsigned short no_msgs[36] = {
  756. X    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  757. X    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  758. X    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  759. X    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  760. X    0x0000, 0x0000, 0x0000, 0x0000
  761. X};
  762. X
  763. X/* array ARRAY contains a picture */
  764. X/*     32 pixels wide  */
  765. X/* and 12 pixels high. */
  766. X/* for wrastop calls use the following options: */
  767. X/* srcwidth = 4, width = 32, and height = 12.  */
  768. X
  769. Xstatic unsigned short fbutton[24] = {
  770. X    0xe000, 0x1fff, 0x2000, 0x7000, 0x2000, 0x70fc, 0x2000, 0x70fc,
  771. X    0x2000, 0x700c, 0x2000, 0x703c, 0x2000, 0x703c, 0x2000, 0x700c,
  772. X    0x2000, 0x700c, 0x2000, 0x7000, 0xe000, 0x7fff, 0xc000, 0x7fff
  773. X};
  774. X
  775. Xvoid
  776. Xinit_mouse (int visible, int flags)
  777. X{
  778. X    int             n;
  779. X    static struct umdata umdata;
  780. X    static struct icon mouse_icon;
  781. X
  782. X    umdata.um_flags = flags;
  783. X    umdata.um_x = 0;
  784. X    umdata.um_y = 0;
  785. X    umdata.um_w = WINWIDTH;
  786. X    umdata.um_h = WINHEIGHT;
  787. X    /* set up mouse icon */
  788. X
  789. X    /*
  790. X     * WARNING: if the size or location of the various icons changes, the
  791. X     * parse_mouse routine must also be changed.  This includes the size and
  792. X     * shape of the mouse pointer icon.
  793. X     */
  794. X    mouse_icon.ic_fc.fc_hs = 32;
  795. X    mouse_icon.ic_fc.fc_vs = 4;
  796. X    mouse_icon.ic_fc.fc_ha = -20;
  797. X    mouse_icon.ic_fc.fc_va = 0;
  798. X    mouse_icon.ic_fc.fc_hi = 0;
  799. X    mouse_icon.ic_fc.fc_vi = 0;
  800. X    for (n = 1; n < 64; n += 2) {
  801. X    mouse_icon.ic_raster[n] = (visible == 0) ? 0 : 0xff00;
  802. X    }
  803. X    umdata.um_icon = &mouse_icon;
  804. X    (void) ioctl (0, WIOCSETMOUSE, &umdata);
  805. X
  806. X}
  807. X
  808. X
  809. X/*ARGSUSED*/
  810. Xint
  811. Xdisplay (int code)
  812. X{
  813. X    int             wd;
  814. X    int             fd;
  815. X    static struct utdata utdata;
  816. X    char            label[WTXTLEN + 1];
  817. X    static char     buffer[90];
  818. X    char           *bptr;
  819. X    unsigned int    nbuf;
  820. X    time_t          now;
  821. X    unsigned int    then;
  822. X    struct tm      *tm;
  823. X    int             hour;
  824. X    static int      old_win = -1;
  825. X    static char     old_label[WTXTLEN + 1];
  826. X    static int      old_day = -1;
  827. X    extern int      errno;
  828. X    extern int      win_number;
  829. X    extern int      redraw_all;
  830. X
  831. X    (void) alarm (0);
  832. X    sync ();
  833. X
  834. X    /*
  835. X     * Check if there are any messages on /dev/error.  This is done before
  836. X     * updating the display so because a pending message could potentially
  837. X     * cause the msg icon to be displayed.
  838. X     */
  839. X    rd_dev_error ();
  840. X
  841. X    /*
  842. X     * WARNING: if the size or location of the various icons changes, the
  843. X     * parse_mouse routine must also be changed.  This includes the size and
  844. X     * shape of the mouse pointer icon.
  845. X     */
  846. X    if (redraw_all) {
  847. X    (void) wrastop (1, envelope, 6, 0, 0,
  848. X            0, 0, 470, 0, 48, 12,
  849. X            SRCSRC, DSTSRC, 0);
  850. X    (void) wrastop (1, loginpat, 6, 0, 0,
  851. X            0, 0, 510, 0, 48, 12,
  852. X            SRCSRC, DSTSRC, 0);
  853. X    (void) wrastop (1, calndr_pat, 6, 0, 0,
  854. X            0, 0, 550, 0, 48, 12,
  855. X            SRCSRC, DSTSRC, 0);
  856. X
  857. X    /*
  858. X     * The Msgs icon is only displayed if there are messages for the
  859. X     * current user.
  860. X     */
  861. X    if (msg_count ()) {
  862. X        (void) write (1, "\007", 1);    /* beep at the user */
  863. X        (void) wrastop (1, msgs_pat, 6, 0, 0,
  864. X                0, 0, 590, 0, 48, 12,
  865. X                SRCSRC, DSTSRC, 0);
  866. X    }
  867. X    else {
  868. X        (void) wrastop (1, no_msgs, 6, 0, 0,
  869. X                0, 0, 590, 0, 48, 12,
  870. X                SRCSRC, DSTSRC, 0);
  871. X    }
  872. X    (void) wrastop (1, fbutton, 4, 0, 0,
  873. X            0, 0, 686, 0, 32, 12,
  874. X            SRCSRC, DSTSRC, 0);
  875. X    }
  876. X
  877. X    /*
  878. X     * Check for calendar alarms
  879. X     */
  880. X    check_alarms ();
  881. X
  882. X    wd = ioctl (0, WIOCGCURR, NULL);
  883. X    if ((wd > 0) && (wd != win_number)) {
  884. X    (void) sprintf (buffer, "/dev/w%d", wd);
  885. X    label[0] = '\0';
  886. X    if ((fd = open (buffer, 0)) != -1) {
  887. X        utdata.ut_num = WTXTUSER;
  888. X        if (ioctl (fd, WIOCGETTEXT, &utdata) != -1) {
  889. X        (void) strncpy (label, utdata.ut_text, WTXTLEN);
  890. X        label[WTXTLEN] = '\0';
  891. X        }
  892. X        if (label[0] == '\0') {
  893. X        utdata.ut_num = WTXTLABEL;
  894. X        if (ioctl (fd, WIOCGETTEXT, &utdata) != -1) {
  895. X            (void) strncpy (label, utdata.ut_text, WTXTLEN);
  896. X            label[WTXTLEN] = '\0';
  897. X        }
  898. X        }
  899. X        if (label[0] == '\0') {
  900. X        (void) strcpy (label, "Unknown Contents");
  901. X        }
  902. X        (void) close (fd);
  903. X    }
  904. X    else {
  905. X        (void) sprintf (label, "%s, errno=%d", buffer, errno);
  906. X    }
  907. X    }
  908. X    else {
  909. X    (void) strcpy (label, "No window selected");
  910. X    }
  911. X
  912. X    now = time (0);
  913. X    tm = localtime (&now);
  914. X    hour = (tm -> tm_hour) % 12;
  915. X    if (hour == 0) {
  916. X    hour = 12;
  917. X    }
  918. X
  919. X    bptr = buffer;
  920. X    if (redraw_all || (wd != old_win) || strcmp (label, old_label)) {
  921. X    (void) sprintf (bptr,
  922. X            "%sw%d %-28.28s",
  923. X            "\033[;H",
  924. X            (wd > 0) ? wd : 0,
  925. X            label);
  926. X    old_win = wd;
  927. X    (void) strcpy (old_label, label);
  928. X    bptr += strlen (bptr);
  929. X    }
  930. X    if (redraw_all || (old_day != tm -> tm_wday)) {
  931. X    (void) sprintf (bptr,
  932. X            "%s%s %s %2d",
  933. X            "\033[;33H",
  934. X            day_names[tm -> tm_wday],
  935. X            month_names[tm -> tm_mon],
  936. X            tm -> tm_mday);
  937. X    old_day = tm -> tm_wday;
  938. X    bptr += strlen (bptr);
  939. X    }
  940. X    (void) sprintf (bptr,
  941. X            "%s%2d:%02d %s",
  942. X            "\033[;44H",
  943. X            hour,
  944. X            tm -> tm_min,
  945. X            (tm -> tm_hour >= 12) ? "pm" : "am");
  946. X    nbuf = strlen (buffer);
  947. X    (void) write (1, buffer, nbuf);
  948. X    redraw_all = 0;
  949. X    if (wd > 0) {
  950. X    info_process ();
  951. X    }
  952. X
  953. X#ifdef    SYNC_MINUTE
  954. X    now = time (0);
  955. X    then = 60 - (now % 60);
  956. X    if (then < 30) {
  957. X    then = 30;
  958. X    }
  959. X#else
  960. X    then = 60;
  961. X#endif
  962. X
  963. X    (void) alarm (then);
  964. X    (void) signal (SIGALRM, display);
  965. X    return (0);
  966. X
  967. X}
  968. END_OF_FILE
  969. if test 9253 -ne `wc -c <'display.c'`; then
  970.     echo shar: \"'display.c'\" unpacked with wrong size!
  971. fi
  972. # end of 'display.c'
  973. fi
  974. if test -f 'getid.c' -a "${1}" != "-c" ; then 
  975.   echo shar: Will not clobber existing file \"'getid.c'\"
  976. else
  977. echo shar: Extracting \"'getid.c'\" \(7240 characters\)
  978. sed "s/^X//" >'getid.c' <<'END_OF_FILE'
  979. X/*---------------------------------------------------------------------------
  980. X *
  981. X * Program: pcmgr
  982. X * Module:  getid.c
  983. X *
  984. X * This module contains routines for determining who the currently active
  985. X * user is.
  986. X *
  987. X * Copyright 1992 David H. Brierley, All rights reserved.
  988. X *-------------------------------------------------------------------------*/
  989. X
  990. X#include <stdio.h>
  991. X#include <sys/types.h>
  992. X#include <sys/font.h>
  993. X#include <sys/window.h>
  994. X#include <time.h>
  995. X#include <signal.h>
  996. X#include <string.h>
  997. X#include <status.h>
  998. X#include <utmp.h>
  999. X#include <pwd.h>
  1000. X#include <sys/stat.h>
  1001. X#include <nlist.h>
  1002. X#include <fcntl.h>
  1003. X#include <ctype.h>
  1004. X#include <termio.h>
  1005. X#include <malloc.h>
  1006. X#include <setjmp.h>
  1007. X#include <sys/wd.h>
  1008. X#include <track.h>
  1009. X#include <tam.h>
  1010. X#include <menu.h>
  1011. X#include <kcodes.h>
  1012. X#include <errno.h>
  1013. X#include <sys/sysinfo.h>
  1014. X#include <sys/var.h>
  1015. X#include <sys/syslocal.h>
  1016. X#include <sys/file.h>
  1017. X#include <sys/text.h>
  1018. X#include <sys/tune.h>
  1019. X#include <sys/user.h>
  1020. X#include <sys/vmmac.h>
  1021. X#include <sys/sysmacros.h>
  1022. X
  1023. X#include "config.h"
  1024. X#include "pcmgr.h"
  1025. X
  1026. Xstatic char    *Sccs_Id = "@(#) getid.c: version 2.1 7/14/92 21:12:25";
  1027. X
  1028. Xint
  1029. Xget_user_id (int *user_uid, int *user_gid)
  1030. X{
  1031. X    struct utmp     ut_record;
  1032. X    U_Info          users[32];
  1033. X    W_Info          wd_info[MAX_WINDOW + 1];
  1034. X    int             w_major_dev;
  1035. X    int             num_users;
  1036. X    int             which_user;
  1037. X    int             fd;
  1038. X    struct passwd  *pw;
  1039. X    struct passwd  *getpwnam ();
  1040. X    int             n;
  1041. X    int             rc;
  1042. X    int             wd;
  1043. X    char            wdev[32];
  1044. X    struct stat     sbuf;
  1045. X
  1046. X    if ((fd = open (UTMP_FILE, 0)) == -1) {
  1047. X    return (-1);
  1048. X    }
  1049. X
  1050. X    num_users = 0;
  1051. X    while (1) {
  1052. X    rc = read (fd, (char *) &ut_record, sizeof (ut_record));
  1053. X    if (rc != sizeof (ut_record)) {
  1054. X        break;
  1055. X    }
  1056. X    if (ut_record.ut_type == USER_PROCESS && ut_record.ut_line[0] == 'w') {
  1057. X        (void) strncpy (users[num_users].name, ut_record.ut_name, 8);
  1058. X        users[num_users].name[8] = '\0';
  1059. X        ut_record.ut_line[8] = '\0';
  1060. X        users[num_users].dev_no = atoi (ut_record.ut_line + 1);
  1061. X        pw = getpwnam (users[num_users].name);
  1062. X        if (pw != NULL) {
  1063. X        users[num_users].uid = pw -> pw_uid;
  1064. X        users[num_users].gid = pw -> pw_gid;
  1065. X        }
  1066. X        else {
  1067. X        users[num_users].uid = -1;
  1068. X        users[num_users].gid = -1;
  1069. X        }
  1070. X        users[num_users].access = ut_record.ut_time;
  1071. X#ifdef        TEST
  1072. X        printf ("add '%s', uid=%d, gid=%d, ut_time=%d, dev=%d\n",
  1073. X            users[num_users].name, users[num_users].uid,
  1074. X            users[num_users].gid, users[num_users].access,
  1075. X            users[num_users].dev_no);
  1076. X#endif
  1077. X        ++num_users;
  1078. X    }
  1079. X    }
  1080. X    (void) close (fd);
  1081. X
  1082. X    if (num_users == 0) {
  1083. X    return (-1);
  1084. X    }
  1085. X
  1086. X    if (num_users == 1) {
  1087. X    *user_uid = users[0].uid;
  1088. X    *user_gid = users[0].gid;
  1089. X    return (0);
  1090. X    }
  1091. X
  1092. X    for (wd = 0; wd <= MAX_WINDOW; ++wd) {
  1093. X    wd_info[wd].access = 0;
  1094. X    }
  1095. X
  1096. X    w_major_dev = -1;
  1097. X    for (wd = 1; wd <= MAX_WINDOW; ++wd) {
  1098. X    (void) sprintf (wdev, "/dev/w%d", wd);
  1099. X    if (stat (wdev, &sbuf) == -1) {
  1100. X        continue;
  1101. X    }
  1102. X    wd_info[wd].access = sbuf.st_atime;
  1103. X    wd_info[wd].uid = -1;
  1104. X    w_major_dev = major (sbuf.st_rdev);
  1105. X#ifdef  TEST
  1106. X    printf ("w%d, st_atime = %d, st_dev=%04x, st_rdev=%04x\n",
  1107. X        wd, sbuf.st_atime, sbuf.st_dev, sbuf.st_rdev);
  1108. X#endif
  1109. X    }
  1110. X
  1111. X    if (w_major_dev == -1) {
  1112. X    return (-1);
  1113. X    }
  1114. X
  1115. X#ifdef TEST
  1116. X    printf ("calling find_dev_uid, major_dev = %d\n", w_major_dev);
  1117. X#endif
  1118. X    if (find_dev_uid (wd_info, w_major_dev) == -1) {
  1119. X    return (-1);
  1120. X    }
  1121. X
  1122. X    for (wd = 1; wd <= MAX_WINDOW; ++wd) {
  1123. X#ifdef    TEST
  1124. X    printf ("wd=%d, uid=%d, access=%d\n",
  1125. X        wd, wd_info[wd].uid, wd_info[wd].access);
  1126. X#endif
  1127. X    for (n = 0; n < num_users; ++n) {
  1128. X        if (users[n].uid != wd_info[wd].uid) {
  1129. X        continue;
  1130. X        }
  1131. X        if (wd_info[wd].access > users[n].access) {
  1132. X        users[n].access = wd_info[wd].access;
  1133. X        }
  1134. X    }
  1135. X    }
  1136. X
  1137. X    for (n = 0; n < num_users; ++n) {
  1138. X    wd = users[n].dev_no;
  1139. X    if (wd_info[wd].access > users[n].access) {
  1140. X        users[n].access = wd_info[wd].access;
  1141. X    }
  1142. X    }
  1143. X
  1144. X    which_user = 0;
  1145. X    for (n = 1; n < num_users; ++n) {
  1146. X    if (users[n].access > users[which_user].access) {
  1147. X        which_user = n;
  1148. X    }
  1149. X    }
  1150. X
  1151. X    *user_uid = users[which_user].uid;
  1152. X    *user_gid = users[which_user].gid;
  1153. X
  1154. X    return (0);
  1155. X
  1156. X}
  1157. X
  1158. X/*
  1159. X * the find_dev_uid routine is absed in part on the sadc program written by
  1160. X * Mark H. Colburn (mark@jhereg.mn.org).
  1161. X */
  1162. X
  1163. Xstruct nlist    sysadr[] = {
  1164. X    {"proc", 0, 0, 0, 0, 0},
  1165. X    {"", 0, 0, 0, 0, 0}
  1166. X};
  1167. X
  1168. X#define procadr        (sysadr[0].n_value)
  1169. X
  1170. Xint             fd_kmem;    /* file handle for /dev/kmem */
  1171. Xint             fd_mem;        /* file handle for /dev/mem */
  1172. Xstruct proc     proc_list[NPROCMAX];    /* the proc table */
  1173. X
  1174. Xint
  1175. Xfind_dev_uid (W_Info wd_info[], int wd_major)
  1176. X{
  1177. X    int             nproc;
  1178. X    int             wmajor;
  1179. X    int             wminor;
  1180. X    struct user     u_area;
  1181. X    struct proc    *p;
  1182. X
  1183. X    if (fdu_init () == -1) {
  1184. X    return (-1);
  1185. X    }
  1186. X
  1187. X    nproc = read_proc_table ();
  1188. X    for (p = proc_list; nproc; --nproc, ++p) {
  1189. X    if (read_user (p, &u_area)) {
  1190. X        wmajor = major (u_area.u_ttyd);
  1191. X        wminor = minor (u_area.u_ttyd);
  1192. X#ifdef        TEST
  1193. X        printf ("proc: u_ttyd=%04x, major=%d, minor=%d, uid=%d, ruid=%d\n",
  1194. X        u_area.u_ttyd, wmajor, wminor, u_area.u_uid, u_area.u_ruid);
  1195. X#endif
  1196. X        if (wmajor != wd_major) {
  1197. X        continue;
  1198. X        }
  1199. X        wd_info[wminor].uid = u_area.u_ruid;
  1200. X    }
  1201. X    }
  1202. X    (void) close (fd_kmem);
  1203. X    (void) close (fd_mem);
  1204. X    return (0);
  1205. X
  1206. X}
  1207. X
  1208. X
  1209. X/*
  1210. X * fdu_init - handle miscellaneous initializations
  1211. X */
  1212. X
  1213. Xint
  1214. Xfdu_init (void)
  1215. X{
  1216. X    /* open the kernel memory */
  1217. X    if ((fd_kmem = open ("/dev/kmem", O_RDONLY)) == -1)
  1218. X    return (-1);
  1219. X
  1220. X    if ((fd_mem = open ("/dev/mem", O_RDONLY)) == -1)
  1221. X    return (-1);
  1222. X
  1223. X    /* get addresses of various kernel structures from /unix */
  1224. X    if (nlist ("/unix", sysadr) == -1)
  1225. X    return (-1);
  1226. X
  1227. X    kmemread (procadr, (char *) &procadr, sizeof (procadr));
  1228. X    return (0);
  1229. X
  1230. X}
  1231. X
  1232. X
  1233. X/*
  1234. X * read_proc_table
  1235. X */
  1236. X
  1237. Xint
  1238. Xread_proc_table (void)
  1239. X{
  1240. X    long            vaddr;    /* address of kernel var structure */
  1241. X    unsigned int    sz_proc;
  1242. X    struct var      v_area;    /* kernel var structure */
  1243. X
  1244. X    /*
  1245. X     * read all of the information that we need for statistics out of the
  1246. X     * kernel space.  For some of these items, it means that we will have to
  1247. X     * read the data twice, since they are only pointers to the real items.
  1248. X     */
  1249. X
  1250. X    vaddr = (long) syslocal (SYSL_KADDR, SLA_V);
  1251. X    kmemread (vaddr, (char *) &v_area, (long) sizeof (v_area));
  1252. X
  1253. X    /* compute the current table sizes */
  1254. X    sz_proc = ((long) v_area.ve_proc - procadr);
  1255. X    kmemread (procadr, (char *) proc_list, sz_proc);
  1256. X
  1257. X    return (sz_proc / sizeof (struct proc));
  1258. X
  1259. X}
  1260. X
  1261. Xvoid
  1262. Xkmemread (long kmadr, char *dptr, unsigned int nbytes)
  1263. X{
  1264. X    (void) lseek (fd_kmem, kmadr, 0);
  1265. X    (void) read (fd_kmem, dptr, nbytes);
  1266. X}
  1267. X
  1268. Xvoid
  1269. Xmemread (long kmadr, char *dptr, unsigned int nbytes)
  1270. X{
  1271. X    (void) lseek (fd_mem, kmadr, 0);
  1272. X    (void) read (fd_mem, dptr, nbytes);
  1273. X}
  1274. X
  1275. Xint
  1276. Xread_user (struct proc * p, struct user * u)
  1277. X{
  1278. X    long            upage;
  1279. X
  1280. X    if (!p -> p_stat ||
  1281. X    p -> p_stat == SIDL ||
  1282. X    p -> p_stat == SZOMB)
  1283. X    return 0;
  1284. X
  1285. X    if (!(p -> p_flag & SLOAD)) {
  1286. X    return 0;
  1287. X    }
  1288. X
  1289. X    upage = (long) ctob (p -> p_addr[0]);
  1290. X
  1291. X    /* copy in the user structure */
  1292. X    memread (upage + U_OFFSET, (char *) u, sizeof (struct user));
  1293. X
  1294. X    return (1);
  1295. X
  1296. X}
  1297. END_OF_FILE
  1298. if test 7240 -ne `wc -c <'getid.c'`; then
  1299.     echo shar: \"'getid.c'\" unpacked with wrong size!
  1300. fi
  1301. # end of 'getid.c'
  1302. fi
  1303. if test -f 'pcmgr.c' -a "${1}" != "-c" ; then 
  1304.   echo shar: Will not clobber existing file \"'pcmgr.c'\"
  1305. else
  1306. echo shar: Extracting \"'pcmgr.c'\" \(9026 characters\)
  1307. sed "s/^X//" >'pcmgr.c' <<'END_OF_FILE'
  1308. X/*---------------------------------------------------------------------------
  1309. X *
  1310. X * Program: pcmgr
  1311. X * Module:  pcmgr.c
  1312. X *
  1313. X * This module contains the main program and a few routines related to
  1314. X * mouse and keyboard input processing.
  1315. X *
  1316. X * Copyright 1992 David H. Brierley, All rights reserved.
  1317. X *-------------------------------------------------------------------------*/
  1318. X
  1319. X#include <stdio.h>
  1320. X#include <sys/types.h>
  1321. X#include <sys/font.h>
  1322. X#include <sys/window.h>
  1323. X#include <time.h>
  1324. X#include <signal.h>
  1325. X#include <string.h>
  1326. X#include <status.h>
  1327. X#include <utmp.h>
  1328. X#include <pwd.h>
  1329. X#include <sys/stat.h>
  1330. X#include <nlist.h>
  1331. X#include <fcntl.h>
  1332. X#include <ctype.h>
  1333. X#include <termio.h>
  1334. X#include <malloc.h>
  1335. X#include <setjmp.h>
  1336. X#include <sys/wd.h>
  1337. X#include <track.h>
  1338. X#include <tam.h>
  1339. X#include <menu.h>
  1340. X#include <kcodes.h>
  1341. X#include <errno.h>
  1342. X#include <sys/sysinfo.h>
  1343. X#include <sys/var.h>
  1344. X#include <sys/syslocal.h>
  1345. X#include <sys/file.h>
  1346. X#include <sys/text.h>
  1347. X#include <sys/tune.h>
  1348. X#include <sys/user.h>
  1349. X#include <sys/vmmac.h>
  1350. X#include <sys/sysmacros.h>
  1351. X
  1352. X#include "config.h"
  1353. X#include "pcmgr.h"
  1354. X
  1355. Xstatic char    *Sccs_Id = "@(#) pcmgr.c: version 2.1 7/14/92 21:12:41";
  1356. X
  1357. X#ifdef    DEBUG
  1358. X#include <syslog.h>
  1359. X#endif
  1360. X
  1361. X/*
  1362. X * Global variables.
  1363. X */
  1364. Xint             win_number = -1; /* window number of status bar */
  1365. Xint             mouse_visible;    /* is the mouse pointer visible */
  1366. Xint             redraw_all = 1; /* complete redraw of status line */
  1367. X
  1368. Xint
  1369. Xmain (int argc, char *argv[])
  1370. X{
  1371. X    int             key;
  1372. X    char            buffer[32];
  1373. X    char            w_name[32];
  1374. X    int             nbytes;
  1375. X    int             n;
  1376. X    int             wd;
  1377. X    int             fd;
  1378. X    int             oldwd;
  1379. X
  1380. X    if (fork () != 0) {
  1381. X    exit (0);
  1382. X    }
  1383. X    (void) setpgrp ();
  1384. X#ifdef    DEBUG
  1385. X    (void) openlog ("pcmgr", LOG_PID | LOG_TIME, 0);
  1386. X#endif
  1387. X
  1388. X    wd = mk_window ();
  1389. X
  1390. X    for (n = 0; n < _NFILE; ++n) {
  1391. X    if (n != wd) {
  1392. X        (void) close (n);
  1393. X    }
  1394. X    }
  1395. X
  1396. X    while (wd != 0) {
  1397. X    (void) close (0);
  1398. X    n = fcntl (wd, F_DUPFD, 0);
  1399. X    if (n != -1) {
  1400. X        (void) close (wd);
  1401. X        wd = n;
  1402. X    }
  1403. X    }
  1404. X    (void) dup (0);
  1405. X    (void) dup (0);
  1406. X    winit ();
  1407. X    (void) wcreate (0, 0, 1, 80, NBORDER);
  1408. X
  1409. X    oldwd = ioctl (0, WIOCGPREV, NULL);
  1410. X    if ((oldwd != -1) && (oldwd != win_number)) {
  1411. X    (void) sprintf (w_name, "/dev/w%d", oldwd);
  1412. X    if ((fd = open (w_name, 0)) != -1) {
  1413. X        (void) ioctl (fd, WIOCSELECT, NULL);
  1414. X        (void) close (fd);
  1415. X    }
  1416. X    }
  1417. X
  1418. X    mouse_visible = 1;
  1419. X    init_mouse (mouse_visible, MSDOWN | MSIN);
  1420. X    init_sysinfo ();
  1421. X    display (SIGALRM);
  1422. X    init_kmap ();
  1423. X
  1424. X    (void) signal (SIGHUP, SIG_IGN);
  1425. X    (void) signal (SIGINT, SIG_IGN);
  1426. X    (void) signal (SIGTERM, SIG_IGN);
  1427. X    (void) signal (SIGWIND, do_sigwind);
  1428. X    (void) signal (SIGCLD, SIG_IGN);
  1429. X
  1430. X    while (1) {
  1431. X    nbytes = read (0, buffer, 32);
  1432. X    if (nbytes == -1) {
  1433. X        continue;
  1434. X    }
  1435. X    /*
  1436. X     * Figure out what key the user pressed.
  1437. X     */
  1438. X    key = chk_kmap (buffer, nbytes);
  1439. X#ifdef    DEBUG
  1440. X    (void) syslog (LOG_DEBUG, "key press: key = %d", key);
  1441. X#endif
  1442. X    switch (key) {
  1443. X    /* one of the mouse buttons was pressed */
  1444. X    case Mouse:
  1445. X        if ((wd = ioctl (0, WIOCGPREV, NULL)) != -1 && wd != win_number) {
  1446. X        (void) sprintf (w_name, "/dev/w%d", wd);
  1447. X        if ((fd = open (w_name, 0)) != -1) {
  1448. X            (void) ioctl (fd, WIOCSELECT, NULL);
  1449. X            (void) close (fd);
  1450. X        }
  1451. X        }
  1452. X        /*
  1453. X         * Figure out which mouse button the user pressed and what
  1454. X         * action is to be performed.
  1455. X         */
  1456. X        switch (parse_mouse (buffer)) {
  1457. X        case DO_NOTHING:
  1458. X        (void) write (1, "\007", 1);
  1459. X        redraw_all = 1;
  1460. X        break;
  1461. X        case DO_LOGIN:
  1462. X        make_login ();
  1463. X        break;
  1464. X        case DO_EMAIL:
  1465. X        run_email ();
  1466. X        break;
  1467. X        case DO_CALNDR:
  1468. X        run_calndr (NULL);
  1469. X        break;
  1470. X        case DO_MSGS:
  1471. X        show_msgs ();
  1472. X        break;
  1473. X        case DO_TOGGLE:
  1474. X        mouse_visible = 1 - mouse_visible;
  1475. X        break;
  1476. X        case DO_FBUTTON:
  1477. X#if        (DO_FBUTTON == DO_MENU)
  1478. X        function_menu ();
  1479. X        break;
  1480. X#else
  1481. X        cycle_fs ();
  1482. X        break;
  1483. X#endif
  1484. X        case DO_MENU:
  1485. X        function_menu ();
  1486. X        break;
  1487. X        }
  1488. X        init_mouse (mouse_visible, MSDOWN | MSIN);
  1489. X        break;
  1490. X    /*
  1491. X     * One of the functions keys was pressed.  Call the hotkey routine.
  1492. X     */
  1493. X    case s_F1:
  1494. X    case s_F2:
  1495. X    case s_F3:
  1496. X    case s_F4:
  1497. X    case s_F5:
  1498. X    case s_F6:
  1499. X    case s_F7:
  1500. X    case s_F8:
  1501. X        /*
  1502. X         * map keypress into 1 thru 8
  1503. X         */
  1504. X        do_hotkey ((key - s_F1) + 1);
  1505. X        break;
  1506. X    /*
  1507. X     * Suspd and Rsume bring up the list of windows
  1508. X     */
  1509. X    case Suspd:
  1510. X    case Rsume:
  1511. X        window_menu ();
  1512. X        break;
  1513. X    /*
  1514. X     * shift Suspd and Rsume cycle through the window list
  1515. X     */
  1516. X    case s_Suspd:
  1517. X        cycle_window (-1);
  1518. X        break;
  1519. X    case s_Rsume:
  1520. X        cycle_window (1);
  1521. X        break;
  1522. X    /*
  1523. X     * Msg button pressed.  Depending on the configuration options
  1524. X     * selected this either displays the users messages or cycles
  1525. X     * through the list of mounted filesystems.
  1526. X     */
  1527. X    case Msg:
  1528. X#if        (DO_FBUTTON == DO_MENU)
  1529. X        cycle_fs ();
  1530. X        break;
  1531. X#else
  1532. X        show_msgs ();
  1533. X        break;
  1534. X#endif
  1535. X    /*
  1536. X     * shift-Print. Do a screen dump.
  1537. X     */
  1538. X    case s_Print:
  1539. X        do_sprint ();
  1540. X        break;
  1541. X    }
  1542. X    display (SIGALRM);
  1543. X    }
  1544. X
  1545. X    /* the above loop should never terminate. */
  1546. X    return(1);
  1547. X
  1548. X}
  1549. X
  1550. Xstruct kmap {
  1551. X    int             kcode;
  1552. X    int             kvlen;
  1553. X    char            kvalue[8];
  1554. X};
  1555. X
  1556. Xstatic struct kmap kmap[] = {
  1557. X    {Mouse, 0, ""},
  1558. X    {s_F1, 0, ""},
  1559. X    {s_F2, 0, ""},
  1560. X    {s_F3, 0, ""},
  1561. X    {s_F4, 0, ""},
  1562. X    {s_F5, 0, ""},
  1563. X    {s_F6, 0, ""},
  1564. X    {s_F7, 0, ""},
  1565. X    {s_F8, 0, ""},
  1566. X    {Suspd, 0, ""},
  1567. X    {s_Suspd, 0, ""},
  1568. X    {Rsume, 0, ""},
  1569. X    {s_Rsume, 0, ""},
  1570. X    {s_Print, 0, ""},
  1571. X    {Msg, 0, ""},
  1572. X    {s_Msg, 0, ""},
  1573. X    {0, 0, ""}
  1574. X};
  1575. X
  1576. Xvoid
  1577. Xinit_kmap (void)
  1578. X{
  1579. X    int             n;
  1580. X    char           *x;
  1581. X
  1582. X    for (n = 0; kmap[n].kcode != 0; ++n) {
  1583. X    x = kcodemap (kmap[n].kcode);
  1584. X    if (x == NULL) {
  1585. X#ifdef        DEBUG
  1586. X        (void) syslog (LOG_DEBUG, "kcodemap(%d) == NULL", kmap[n].kcode);
  1587. X#endif
  1588. X    }
  1589. X    else {
  1590. X        (void) strcpy (kmap[n].kvalue, kcodemap (kmap[n].kcode));
  1591. X    }
  1592. X    kmap[n].kvlen = strlen (kmap[n].kvalue);
  1593. X#ifdef    DEBUG
  1594. X    (void) syslog (LOG_DEBUG, "kmap: code=%d, len=%d, value='%s'",
  1595. X               kmap[n].kcode, kmap[n].kvlen, kmap[n].kvalue);
  1596. X#endif
  1597. X    }
  1598. X
  1599. X}
  1600. X
  1601. Xint
  1602. Xchk_kmap (char *buf, int count)
  1603. X{
  1604. X    int             n;
  1605. X
  1606. X    for (n = 0; kmap[n].kcode != 0; ++n) {
  1607. X    if (count < kmap[n].kvlen) {
  1608. X        continue;
  1609. X    }
  1610. X    if (strncmp (buf, kmap[n].kvalue, kmap[n].kvlen) == 0) {
  1611. X        return (kmap[n].kcode);
  1612. X    }
  1613. X    }
  1614. X
  1615. X    /* kludge for Msg key */
  1616. X    if ((count == 1) && (buf[0] == '\032')) {
  1617. X    return (Msg);
  1618. X    }
  1619. X
  1620. X#ifdef    DEBUG
  1621. X    (void) syslog (LOG_DEBUG, "unknown keypress: '%s', count=%d", buf, count);
  1622. X#endif
  1623. X    return (-1);
  1624. X
  1625. X}
  1626. X
  1627. Xint
  1628. Xparse_mouse (char *buf)
  1629. X{
  1630. X    static int      xpos;
  1631. X    static int      ypos;
  1632. X    static char     button;
  1633. X    static char     reason;
  1634. X
  1635. X    if (sscanf (buf, "%*c[?%d;%d;%c;%c", &xpos, &ypos, &button, &reason) != 4) {
  1636. X    return (DO_NOTHING);
  1637. X    }
  1638. X
  1639. X    button -= '0';        /* convert char to number */
  1640. X
  1641. X    /*
  1642. X     * Left button pressed?
  1643. X     */
  1644. X    if (button & 4) {
  1645. X    /*
  1646. X     * Examine the mouse x-position and determine if the use has clicked on
  1647. X     * one of the special labels at the right of the window.
  1648. X     */
  1649. X#ifdef    DEBUG
  1650. X    (void) syslog (LOG_DEBUG, "parse_mouse: xpos = %d", xpos);
  1651. X#endif
  1652. X    if ((xpos > 466) && (xpos < 492)) {
  1653. X        return (DO_EMAIL);
  1654. X    }
  1655. X    if ((xpos > 506) && (xpos < 532)) {
  1656. X        return (DO_LOGIN);
  1657. X    }
  1658. X    if ((xpos > 546) && (xpos < 572)) {
  1659. X        return (DO_CALNDR);
  1660. X    }
  1661. X    if ((xpos > 586) && (xpos < 612)) {
  1662. X        return (DO_MSGS);
  1663. X    }
  1664. X    if ((xpos > 694) && (xpos < 706)) {
  1665. X        return (DO_FBUTTON);
  1666. X    }
  1667. X    return (DO_NOTHING);
  1668. X    }
  1669. X
  1670. X    /*
  1671. X     * Middle button pressed?
  1672. X     */
  1673. X    if (button & 2) {
  1674. X    return (DO_TOGGLE);
  1675. X    }
  1676. X
  1677. X    /*
  1678. X     * Right button pressed?
  1679. X     */
  1680. X    if (button & 1) {
  1681. X    return (DO_MENU);
  1682. X    }
  1683. X
  1684. X    return (-1);
  1685. X
  1686. X}
  1687. X
  1688. Xint
  1689. Xmk_window (void)
  1690. X{
  1691. X    int             wd;
  1692. X    int             fd;
  1693. X    int             xnum;
  1694. X    struct uwdata   uwdata;
  1695. X    struct utdata   utdata;
  1696. X    struct termio   tty;
  1697. X    struct stat     sbuf;
  1698. X
  1699. X    win_number = -1;
  1700. X    wd = -1;
  1701. X    while (1) {
  1702. X    fd = open ("/dev/window", 2);
  1703. X    if (fd == -1) {
  1704. X        if (win_number == -1) {
  1705. X        exit (1);
  1706. X        }
  1707. X        break;
  1708. X    }
  1709. X    if (fstat (fd, &sbuf) != -1) {
  1710. X        xnum = minor (sbuf.st_rdev);
  1711. X        if (xnum > win_number) {
  1712. X        win_number = xnum;
  1713. X        wd = fd;
  1714. X        }
  1715. X    }
  1716. X    }
  1717. X
  1718. X    if (ioctl (wd, WIOCGETD, &uwdata) != -1) {
  1719. X    uwdata.uw_x = W_XPOS;
  1720. X    uwdata.uw_y = W_YPOS;
  1721. X    uwdata.uw_width = W_WIDTH;
  1722. X    uwdata.uw_height = W_HEIGHT;
  1723. X    uwdata.uw_uflags = NBORDER;
  1724. X    (void) ioctl (wd, WIOCSETD, &uwdata);
  1725. X    }
  1726. X
  1727. X    utdata.ut_num = WTXTUSER;
  1728. X    (void) strcpy (utdata.ut_text, "Status Manager");
  1729. X    (void) ioctl (wd, WIOCSETTEXT, &utdata);
  1730. X
  1731. X    (void) ioctl (wd, WIOCPGRP, NULL);
  1732. X    (void) ioctl (wd, WIOCSYS, SYSWMGR);
  1733. X    (void) ioctl (wd, WIOCSYS, SYSPMGR);
  1734. X    (void) ioctl (wd, WIOCSYS, SYSSMGR);
  1735. X
  1736. X    if (ioctl (wd, TCGETA, &tty) != -1) {
  1737. X    tty.c_lflag = 0;
  1738. X    tty.c_cc[VMIN] = 1;
  1739. X    tty.c_cc[VTIME] = 0;
  1740. X    (void) ioctl (wd, TCSETA, &tty);
  1741. X    }
  1742. X
  1743. X    return (wd);
  1744. X
  1745. X}
  1746. X
  1747. Xint
  1748. Xdo_sigwind (int code)
  1749. X{
  1750. X
  1751. X    if (ioctl (0, WIOCGCURR, NULL) == win_number) {
  1752. X    init_mouse (mouse_visible, MSDOWN | MSIN);
  1753. X    }
  1754. X
  1755. X    (void) signal (code, do_sigwind);
  1756. X    return (0);
  1757. X
  1758. X}
  1759. END_OF_FILE
  1760. if test 9026 -ne `wc -c <'pcmgr.c'`; then
  1761.     echo shar: \"'pcmgr.c'\" unpacked with wrong size!
  1762. fi
  1763. # end of 'pcmgr.c'
  1764. fi
  1765. if test -f 'pcmgr.h' -a "${1}" != "-c" ; then 
  1766.   echo shar: Will not clobber existing file \"'pcmgr.h'\"
  1767. else
  1768. echo shar: Extracting \"'pcmgr.h'\" \(1754 characters\)
  1769. sed "s/^X//" >'pcmgr.h' <<'END_OF_FILE'
  1770. X
  1771. X/* pcmgr.c */
  1772. Xint main(int argc, char *argv[]);
  1773. Xvoid init_kmap(void);
  1774. Xint chk_kmap(char *buf, int count);
  1775. Xint parse_mouse(char *buf);
  1776. Xint mk_window(void);
  1777. Xint do_sigwind(int code);
  1778. X
  1779. X/* display.c */
  1780. Xvoid init_mouse(int visible, int flags);
  1781. Xint display(int code);
  1782. X
  1783. X/* getid.c */
  1784. Xint get_user_id(int *user_uid, int *user_gid);
  1785. Xint find_dev_uid(W_Info wd_info[], int wd_major);
  1786. Xint fdu_init(void);
  1787. Xint read_proc_table(void);
  1788. Xvoid kmemread(long kmadr, char *dptr, unsigned int nbytes);
  1789. Xvoid memread(long kmadr, char *dptr, unsigned int nbytes);
  1790. Xint read_user(struct proc *p, struct user *u);
  1791. X
  1792. X/* hotkey.c */
  1793. Xvoid do_hotkey(int code);
  1794. XHotKey *read_keyfile(char *filename);
  1795. Xvoid free_list(HotKey *head);
  1796. XHotKey *insert(HotKey *head, int key, int hgt, int width, char *cmd, char *cmd_name);
  1797. Xvoid function_menu(void);
  1798. X
  1799. X/* subr.c */
  1800. Xvoid make_login(void);
  1801. Xvoid cycle_window(int dir);
  1802. Xvoid rd_dev_error(void);
  1803. Xvoid trap_alarm(int sig);
  1804. Xvoid parse_ebuffer(char *buf);
  1805. Xvoid parse_cal_trigger(char *buf, int *adate, int *atime);
  1806. Xvoid write_to_log(long pid, char *buf);
  1807. Xvoid insert_msg(int type, int action, int adate, int atime, char *user, char *text);
  1808. Xint msg_count(void);
  1809. Xvoid show_msgs(void);
  1810. Xvoid check_alarms(void);
  1811. Xvoid setenv(char *name, char *value);
  1812. X
  1813. X/* sysinfo.c */
  1814. Xvoid init_sysinfo(void);
  1815. Xvoid info_process(void);
  1816. Xvoid open_current_window(void);
  1817. Xvoid filestatus(void);
  1818. Xvoid cycle_fs(void);
  1819. Xvoid read_mtab(void);
  1820. Xvoid uptime(char *buf);
  1821. Xvoid mailcheck(char *buf);
  1822. Xvoid loadaverage(char *lbuf);
  1823. Xlong memory(void);
  1824. Xint slktest(void);
  1825. Xvoid count_users(char *buf);
  1826. Xlong page(void);
  1827. Xvoid highlight(char *start, char *end);
  1828. X
  1829. X/* windows.c */
  1830. Xvoid window_menu(void);
  1831. Xchar *msave(char *str);
  1832. Xvoid run_email(void);
  1833. Xvoid run_calndr(char *buf);
  1834. Xvoid do_sprint(void);
  1835. END_OF_FILE
  1836. if test 1754 -ne `wc -c <'pcmgr.h'`; then
  1837.     echo shar: \"'pcmgr.h'\" unpacked with wrong size!
  1838. fi
  1839. # end of 'pcmgr.h'
  1840. fi
  1841. echo shar: End of archive 1 \(of 3\).
  1842. cp /dev/null ark1isdone
  1843. MISSING=""
  1844. for I in 1 2 3 ; do
  1845.     if test ! -f ark${I}isdone ; then
  1846.     MISSING="${MISSING} ${I}"
  1847.     fi
  1848. done
  1849. if test "${MISSING}" = "" ; then
  1850.     echo You have unpacked all 3 archives.
  1851.     rm -f ark[1-9]isdone
  1852. else
  1853.     echo You still need to unpack the following archives:
  1854.     echo "        " ${MISSING}
  1855. fi
  1856. ##  End of shell archive.
  1857. exit 0
  1858. -- 
  1859. David H. Brierley
  1860. Home: dave@galaxia.network23.com; Work: dhb@quahog.ssd.ray.com
  1861. Send comp.sources.3b1 submissions to comp-sources-3b1@galaxia.network23.com
  1862. %% Can I be excused, my brain is full. **
  1863.