home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / maint / part02 < prev    next >
Encoding:
Text File  |  1992-05-13  |  75.0 KB  |  2,327 lines

  1. Newsgroups: comp.sources.unix
  2. From: peirce@gw.wmich.edu (Leonard J. Peirce)
  3. Subject: v26i050: maint - full-screen file and directory maintenance tool, Part02/07
  4. Sender: unix-sources-moderator@pa.dec.com
  5. Approved: vixie@pa.dec.com
  6.  
  7. Submitted-By: peirce@gw.wmich.edu (Leonard J. Peirce)
  8. Posting-Number: Volume 26, Issue 50
  9. Archive-Name: maint/part02
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 2 (of 7)."
  18. # Contents:  info.c maint.h.dist options.c pool.c slot.c
  19. # Wrapped by vixie@cognition.pa.dec.com on Thu May 14 23:05:42 1992
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'info.c' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'info.c'\"
  23. else
  24. echo shar: Extracting \"'info.c'\" \(13653 characters\)
  25. sed "s/^X//" >'info.c' <<'END_OF_FILE'
  26. X/******************************************************************************
  27. X*******************************************************************************
  28. X
  29. X   Site:    Western Michigan University Academic Computer Center
  30. X
  31. X   System:    Directory/File System Maintenance
  32. X  
  33. X   Program:    maint
  34. X
  35. X   Version=01    Level=00    01/24/92    Leonard J. Peirce
  36. X
  37. X   Purpose:    Give full information about a file, including size, pro-
  38. X        tection mode, inode, and file commands, among other info.
  39. X
  40. X   Arguments:    See individual routine(s).
  41. X
  42. X   External variables:    None
  43. X
  44. X   Maint external functions:
  45. X
  46. X    Defined:    info
  47. X
  48. X    Called:        add_filetype, get_group, get_owner, prot_val_to_str,
  49. X            put_line, readlink
  50. X
  51. X   Files accessed:    File passed to info routine
  52. X
  53. X   Return codes:    See individual routines
  54. X
  55. X   Compiling instructions:    See Makefile
  56. X
  57. X   Linking instructions:    See Makefile
  58. X
  59. X   Other information:    (C) Copyright 1992, Leonard J. Peirce
  60. X
  61. X********************************************************************************
  62. X*******************************************************************************/
  63. X
  64. X/******************************************************************************/
  65. X/*                                                                            */
  66. X/*                        # I N C L U D E   F I L E S                         */
  67. X/*                                                                            */
  68. X/******************************************************************************/
  69. X
  70. X#if !defined(SYSV) || defined(sun)
  71. X#include <sys/types.h>
  72. X#endif
  73. X#ifdef ultrix
  74. X#include <cursesX.h>
  75. X#else
  76. X#include <curses.h>
  77. X#endif
  78. X#include <stdio.h>
  79. X#include <string.h>
  80. X#include <errno.h>
  81. X#include <time.h>
  82. X#include "maint.h"
  83. X#include <sys/stat.h>
  84. X
  85. X/******************************************************************************/
  86. X/*                                                                            */
  87. X/*                             # D E F I N E S                                */
  88. X/*                                                                            */
  89. X/******************************************************************************/
  90. X
  91. X/******************************************************************************/
  92. X/*                                                                            */
  93. X/*          S T R U C T U R E S ,   U N I O N S ,   T Y P E D E F S           */
  94. X/*                                                                            */
  95. X/******************************************************************************/
  96. X
  97. X/******************************************************************************/
  98. X/*                                                                            */
  99. X/*   E X T E R N A L   D E F I N I T I O N S   &   D E C L A R A T I O N S    */
  100. X/*                                                                            */
  101. X/******************************************************************************/
  102. X
  103. extern     char      *prot_val_to_str(),
  104. X          *get_owner(),
  105. X          *get_group();
  106. X
  107. extern     int      readlink();
  108. X
  109. extern     u_short  add_filetype();
  110. X
  111. extern     short      put_line();
  112. X
  113. X     short      info();
  114. X
  115. X/******************************************************************************/
  116. X/*                                                                            */
  117. X/*     S T A T I C   D E F I N I T I O N S   &   D E C L A R A T I O N S      */
  118. X/*                                                                            */
  119. X/******************************************************************************/
  120. X
  121. X/*******************************************************************************
  122. X********************************************************************************
  123. X
  124. X  Function:    info
  125. X
  126. X  Purpose:    Display all the information about the file that the user could
  127. X        possibly want.  Basically, all of the information on the file
  128. X        is displayed, along with any of the commands that might be
  129. X        associated with the file.
  130. X
  131. X  Global variables:
  132. X
  133. X    Name            Examine/Modify/Use/Read/Write
  134. X    ----            -----------------------------
  135. X    none
  136. X
  137. X  Return Codes:
  138. X
  139. X    Code            Reason
  140. X    ----            ------
  141. X      0            completed successfully
  142. X    CANT_DISPLAY        can't get file attributes to display
  143. X
  144. X********************************************************************************
  145. X*******************************************************************************/
  146. X
  147. short info(ent,args)
  148. X                    /*******   FORMAL  PARAMETERS   *******/
  149. register ENT_DEF  *ent;            /* file entry pointer              */
  150. X     ARG_DEF  *args;        /* run-time arguments              */
  151. X
  152. X{    /*** info ***/
  153. X                    /********   LOCAL  VARIABLES   ********/
  154. register COM_DEF  *comm_ptr;        /* pointer to file commands for file  */
  155. X     WINDOW      *window;        /* window to use              */
  156. X     long      temp;            /* temporary time value              */
  157. struct     stat      statbuf;        /* for getting file information          */
  158. X     int      row = 0,        /* what row is being written to          */
  159. X          length,        /* length of string from readlink()   */
  160. X          status,        /* return code status holder          */
  161. X          max_row,        /* max. usable row for window          */
  162. X          i, j ;        /* simple counters               */
  163. X     char      buf[MAXNAMLEN*2],    /* formatting buffer              */
  164. X          buf2[MAXNAMLEN+10],    /* for getting symbolic link info     */
  165. X          time1[TIME_STR_MAX+2], /* time string formatting buffer     */
  166. X          time2[TIME_STR_MAX+2], /* time string formatting buffer     */
  167. X          time3[TIME_STR_MAX+2]; /* time string formatting buffer     */
  168. u_short        prot ;        /* protection word value          */
  169. static     char      indent_str[] = {"    "},
  170. X          copy_str[] = {"Copy to: "},
  171. X          rename_str[] = {"Rename to: "},
  172. X          delete_str[] = {"Delete"},
  173. X          protect_str[] = {"Protection: "},
  174. X          text_str[] = {"Text descriptor: "},
  175. X          owner_str[] = {"Owner: "},
  176. X          group_str[] = {"Group: "},
  177. X          link_str[] = {"Symbolic link to: "};
  178. static char      *who_perm[ 3 ] = {
  179. X                    "Owner",
  180. X                    "Group",
  181. X                    "Others"
  182. X                    } ;
  183. static char      *dir_permissions[] = {
  184. X    "   %s can%s read (list) the directory",
  185. X    "   %s can%s create, delete and rename files in the directory",
  186. X    "   %s can%s pass through the directory to other files or dirs",
  187. X    } ;
  188. static char      *file_permissions[] = {
  189. X    "   %s can%s read the file",
  190. X    "   %s can%s change the file",
  191. X    "   %s can%s run the program or shell script in the file",
  192. X    } ;
  193. char          **perm_details = file_permissions ;
  194. X
  195. X    
  196. X
  197. X   /* first create a window to use */
  198. X
  199. X   window = newwin(LINES - SPEC_WINDOW_ROWS,COLS,SPEC_WINDOW_ROWS,0);
  200. X   werase(window);
  201. X   keypad(window,TRUE);
  202. X   max_row = LINES - (SPEC_WINDOW_ROWS + 1);
  203. X
  204. X   /* get the info for the file */
  205. X
  206. X#if !defined(SYSV) || defined(sun)
  207. X   status = lstat(ent->filename,&statbuf);
  208. X#else
  209. X   status = stat(ent->filename,&statbuf);
  210. X#endif
  211. X
  212. X   if(status != 0)
  213. X      return(FAILURE);
  214. X
  215. X   /* now write the stuff to the screen */
  216. X
  217. X   strtcpy(buf,ent->filename);        /* make control chars printable first */
  218. X   put_buf(window,buf,&row,max_row,0,A_BOLD,FALSE,' ',FALSE);
  219. X   put_buf(window,"",&row,max_row,0,A_BOLD,FALSE,' ',FALSE);
  220. X
  221. X#if !defined(SYSV) || defined(sun)
  222. X   if(ent->type == LINK)
  223. X   {
  224. X      /* get what it's linked to */
  225. X
  226. X      length = readlink(ent->filename,buf2,MAXNAMLEN+10);
  227. X
  228. X      if(length > 0)
  229. X      {
  230. X     buf2[length] = '\0';        /* make it a string              */
  231. X     cat(3,buf,link_str,buf2);
  232. X         put_buf(window,buf,&row,max_row,sizeof(link_str),A_NORMAL,FALSE,' ',
  233. X         FALSE);
  234. X      }
  235. X   }
  236. X#endif
  237. X
  238. X   prot = add_filetype(ent->type,ent->prot);
  239. X   sprintf(buf,"Protection: %s    Owner: %s        Group: %s",
  240. X       prot_val_to_str(prot), get_owner(ent->uid),get_group(ent->gid));
  241. X
  242. X   put_buf(window,buf,&row,max_row,0,A_NORMAL,FALSE,' ',FALSE);
  243. X
  244. X   /* first determine what type of file it is */
  245. X
  246. X   switch(prot & S_IFMT)
  247. X   {
  248. X      case(S_IFREG):
  249. X     put_buf(window,"This is a standard file.",&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  250. X#if !defined(SYSV) || defined(sun)
  251. X         sprintf(buf,"Size in bytes: %d    Size in blocks: %d",statbuf.st_size,
  252. X       statbuf.st_blocks);
  253. X#else
  254. X         sprintf(buf,"Size in bytes: %d",statbuf.st_size);
  255. X#endif
  256. X     put_buf(window,buf,&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  257. X     break;
  258. X      case(S_IFDIR):
  259. X     put_buf(window,"This file is a directory.",&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  260. X     perm_details = dir_permissions ;
  261. X#if !defined(SYSV)
  262. X         if(prot & S_ISGID)
  263. X       put_buf(window,"  Files created in this directory will be of the same group as the directory.",&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  264. X     else
  265. X       put_buf(window,"  Files created in this directory will be of the same group as your default.",&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  266. X#endif
  267. X     break;
  268. X      case(S_IFCHR):
  269. X     put_buf(window,"This file represents a character device.",&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  270. X         sprintf(buf,"  The major device number is %d, minor number %d.",statbuf.st_size,
  271. X       statbuf.st_blocks);
  272. X     put_buf(window,buf,&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  273. X     break;
  274. X      case(S_IFBLK):
  275. X     put_buf(window,"This file represents a block device.",&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  276. X         sprintf(buf,"  The major device number is %d, minor number %d.",statbuf.st_size,
  277. X       statbuf.st_blocks);
  278. X     put_buf(window,buf,&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  279. X     break;
  280. X      case(S_IFIFO):
  281. X     put_buf(window,"This file is a named pipe.",&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  282. X         sprintf(buf,"  There are %d unread bytes in the pipe",statbuf.st_size);
  283. X     put_buf(window,buf,&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  284. X     break;
  285. X#if defined(S_IFLNK)
  286. X      case(S_IFLNK):
  287. X     put_buf(window,"This file is a symbolic link.",&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  288. X     break;
  289. X#endif
  290. X      default:
  291. X     put_buf(window,"This file is an unknown type.",&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  292. X     break;
  293. X   }
  294. X
  295. X   /* create and print the detailed permission string */
  296. X
  297. X   put_buf(window,"Details on permissions:",&row,max_row,0,A_NORMAL,FALSE,' ',FALSE);
  298. X   for(i = j = 0 ; i < 3 ; i++, j+=3 )
  299. X   {
  300. X      sprintf( buf, perm_details[ 0 ], who_perm[ i ],
  301. X     (prot & (S_IREAD >> j)) ? "" : "not" ) ;
  302. X      put_buf(window,buf,&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  303. X      sprintf( buf, perm_details[ 1 ], who_perm[ i ],
  304. X     (prot & (S_IWRITE >> j)) ? "" : "not" ) ;
  305. X      put_buf(window,buf,&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  306. X      sprintf( buf, perm_details[ 2 ], who_perm[ i ],
  307. X     (prot & (S_IEXEC >> j)) ? "" : "not" ) ;
  308. X      put_buf(window,buf,&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  309. X   }
  310. X
  311. X   if(prot & S_ISUID)
  312. X      put_buf(window,"The setuid bit is set.",&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  313. X
  314. X   if(prot & S_ISGID)
  315. X      put_buf(window,"The sgid bit is set.",&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  316. X
  317. X   if(prot & S_ISVTX)
  318. X      put_buf(window,"The sticky bit is set.",&row,max_row,0,A_NORMAL,FALSE,' ',FALSE) ;
  319. X
  320. X   sprintf(buf,"Inode #: %d        Number of links: %d",statbuf.st_ino,
  321. X       statbuf.st_nlink);
  322. X
  323. X   put_buf(window,buf,&row,max_row,0,A_NORMAL,FALSE,' ',FALSE);
  324. X
  325. X   temp = (long) statbuf.st_atime;
  326. X   strcpy(time1,ctime(&temp));
  327. X   temp = (long) statbuf.st_mtime;
  328. X   strcpy(time2,ctime(&temp));
  329. X   temp = (long) statbuf.st_ctime;
  330. X   strcpy(time3,ctime(&temp));
  331. X
  332. X   time1[TIME_STR_MAX] = '\0';        /* lop off the \n's              */
  333. X   time2[TIME_STR_MAX] = '\0';
  334. X   time3[TIME_STR_MAX] = '\0';
  335. X
  336. X   cat(3,buf,"Last access:        ",time1);
  337. X   put_buf(window,buf,&row,max_row,0,A_NORMAL,FALSE,' ',FALSE);
  338. X
  339. X   cat(3,buf,"Last modification:    ",time2);
  340. X   put_buf(window,buf,&row,max_row,0,A_NORMAL,FALSE,' ',FALSE);
  341. X
  342. X   cat(3,buf,"Last status change:    ",time3);
  343. X   put_buf(window,buf,&row,max_row,0,A_NORMAL,FALSE,' ',FALSE);
  344. X
  345. X   if(args->text)
  346. X   {
  347. X      if(ent->text == NULL)
  348. X     strcpy(buf,"Text descriptor:    None");
  349. X      else
  350. X     cat(3,buf,"Text descriptor:    ",ent->text);
  351. X
  352. X      put_buf(window,buf,&row,max_row,0,A_NORMAL,FALSE,' ',FALSE);
  353. X   }
  354. X   
  355. X   if(ent->command)
  356. X   {
  357. X      put_buf(window,"",&row,max_row,0,A_NORMAL,FALSE,' ',FALSE);
  358. X      put_buf(window,"File commands:",&row,max_row,0,A_BOLD,FALSE,' ',FALSE);
  359. X
  360. X      comm_ptr = ent->command;
  361. X
  362. X      if(comm_ptr->comm_copy)
  363. X      {
  364. X     cat(4,buf,indent_str,copy_str,comm_ptr->copy_name);
  365. X     put_buf(window,buf,&row,max_row,sizeof(indent_str) + sizeof(copy_str),
  366. X         A_NORMAL,FALSE,' ',FALSE);
  367. X      }
  368. X
  369. X      if(comm_ptr->comm_ren)
  370. X      {
  371. X     cat(4,buf,indent_str,rename_str,comm_ptr->ren_name);
  372. X     put_buf(window,buf,&row,max_row,sizeof(indent_str) +
  373. X         sizeof(rename_str),A_NORMAL,FALSE,' ',FALSE);
  374. X      }
  375. X
  376. X      if(comm_ptr->comm_prot)
  377. X      {
  378. X     cat(4,buf,indent_str,protect_str,
  379. X         prot_val_to_str(add_filetype(ent->type,comm_ptr->prot)));
  380. X     put_buf(window,buf,&row,max_row,sizeof(indent_str) +
  381. X         sizeof(protect_str),A_NORMAL,FALSE,' ',FALSE);
  382. X      }
  383. X
  384. X      if(comm_ptr->comm_text)
  385. X      {
  386. X     cat(4,buf,indent_str,text_str,comm_ptr->text);
  387. X     put_buf(window,buf,&row,max_row,sizeof(indent_str) + sizeof(text_str),
  388. X         A_NORMAL,FALSE,' ',FALSE);
  389. X      }
  390. X
  391. X      if(comm_ptr->comm_own)
  392. X      {
  393. X     cat(4,buf,indent_str,owner_str,get_owner(comm_ptr->owner));
  394. X     put_buf(window,buf,&row,max_row,sizeof(indent_str) + sizeof(owner_str),
  395. X         A_NORMAL,FALSE,' ',FALSE);
  396. X      }
  397. X
  398. X      if(comm_ptr->comm_grp)
  399. X      {
  400. X     cat(4,buf,indent_str,group_str,get_group(comm_ptr->group));
  401. X     put_buf(window,buf,&row,max_row,sizeof(indent_str) + sizeof(group_str),
  402. X         A_NORMAL,FALSE,' ',FALSE);
  403. X      }
  404. X
  405. X      if(comm_ptr->comm_del)
  406. X      {
  407. X     cat(3,buf,indent_str,delete_str);
  408. X     put_buf(window,buf,&row,max_row,sizeof(indent_str) +
  409. X         sizeof(delete_str),A_NORMAL,FALSE,' ',FALSE);
  410. X      }
  411. X   }
  412. X   else
  413. X      put_buf(window,"File commands:        None",&row,max_row,0,A_NORMAL,
  414. X           FALSE,' ',FALSE);
  415. X
  416. X
  417. X   put_buf(window," ",&row,max_row,0,A_REVERSE,TRUE,' ',TRUE);
  418. X   delwin(window);            /* get rid of the window          */
  419. X   return(SUCCESS);
  420. X
  421. X}    /*** info ***/
  422. END_OF_FILE
  423. if test 13653 -ne `wc -c <'info.c'`; then
  424.     echo shar: \"'info.c'\" unpacked with wrong size!
  425. fi
  426. # end of 'info.c'
  427. fi
  428. if test -f 'maint.h.dist' -a "${1}" != "-c" ; then 
  429.   echo shar: Will not clobber existing file \"'maint.h.dist'\"
  430. else
  431. echo shar: Extracting \"'maint.h.dist'\" \(15883 characters\)
  432. sed "s/^X//" >'maint.h.dist' <<'END_OF_FILE'
  433. X#ifndef MAINT_H
  434. X/******************************************************************************
  435. X*******************************************************************************
  436. X
  437. X   Installation:  Western Michigan University Academic Computer Center
  438. X
  439. X   System:    Directory/File System Maintenance
  440. X  
  441. X   Program:    maint
  442. X
  443. X   Header name:    maint.h
  444. X
  445. X   Version=01    Level=00    01/24/92    Leonard J. Peirce
  446. X
  447. X   Purpose:  Header file for the MAINT program.  This header file should
  448. X         only be used by MAINT as it would be of no use to any other
  449. X         program.
  450. X
  451. X   Other information:    (C) Copyright 1992, Leonard J. Peirce
  452. X
  453. X********************************************************************************
  454. X*******************************************************************************/
  455. X
  456. X#define MAINT_H 1            /* to prevent multiple inclusion      */
  457. X
  458. X/******************************************************************************/
  459. X/*                                                                            */
  460. X/*                        # I N C L U D E   F I L E S                         */
  461. X/*                                                                            */
  462. X/******************************************************************************/
  463. X
  464. X#include <sys/types.h>
  465. X#include <dirent.h>
  466. X
  467. X/******************************************************************************/
  468. X/*                                                                            */
  469. X/*                             # D E F I N E S                                */
  470. X/*                                                                            */
  471. X/******************************************************************************/
  472. X
  473. X/* HELPFILE contains on-line help for maint and should be defined in the
  474. X * Makefile so that maints knows where it's supposed to be and so that it
  475. X * it gets installed in the right spot; if you don't want to define it in
  476. X * the Makefile you'll need to make sure that the path to the help file is
  477. X * correct in both spots
  478. X */
  479. X
  480. X#ifndef HELPFILE
  481. X#define HELPFILE "/usr/local/lib/maint.help"
  482. X#endif
  483. X
  484. X#define MAX_SCREEN_ROWS 65        /* max. # of rows for screens          */
  485. X#define MAX_SCREEN_COLS 132        /* max. # of columns for screens      */
  486. X#define DEFAULT_PAGER "less"        /* less is better than cat.....:-)    */
  487. X#define DEFAULT_EDITOR "vi"        /* sigh.....                  */
  488. X#define DEFAULT_SHELL "csh"
  489. X
  490. X/* the following stuff you probably won't want to touch */
  491. X
  492. X#define TRUE (1)
  493. X#define FALSE (0)
  494. X#define NULLPTR (char *) 0
  495. X
  496. X#define LEFT 0
  497. X#define RIGHT 1
  498. X
  499. X#define SPEC_WINDOW_ROWS 2        /* # of rows in directory spec window */
  500. X#define SPEC_WINDOW_START_ROW 0        /* starting row # of dir spec window  */
  501. X#define STAT_WINDOW_ROWS 2        /* # of rows in statistics window     */
  502. X#define STAT_WINDOW_START_ROW 0
  503. X
  504. X#define SUCCESS 1
  505. X#define FAILURE 0
  506. X
  507. X#define NO_REBUILD 0            /* return values from config()          */
  508. X#define REBUILD_WITH_FILEMARKS 1
  509. X#define REBUILD_SCREEN 2
  510. X#define REBUILD_DIRECTORY 4
  511. X#define REBUILD_WITH_SORT 8
  512. X
  513. X#define CANT_OPEN -1            /* can't open file to display it      */
  514. X#define CANT_DISPLAY -2            /* can't display file on screen          */
  515. X#define EMPTY_FILE -3            /* selected file is empty          */
  516. X#define BAD_FILE -4            /* file format invalid              */
  517. X#define DONT_CREATE -5            /* do not create file              */
  518. X#define NO_FILE -6            /* file does not exist              */
  519. X#define NEW_FILE -7            /* new file had to be created          */
  520. X#define BAD_SCREEN_NO -8        /* bad screen number read in          */
  521. X#define CANT_ALLOCATE -9        /* can't allocate necessary memory    */
  522. X#define CANT_OPEN_DEST -10        /* can't open destination file          */
  523. X#define CANT_STAT -11            /* can't stat a file              */
  524. X#define CANT_WRITE -12            /* can't write to a file          */
  525. X#define CANT_CHMOD -13            /* chmod() failed on a file          */
  526. X#define BAD_GROUP -14            /* invalid group specified          */
  527. X#define BAD_OWNER -15            /* invalid owner specified          */
  528. X#define DISPLAY_TEXT 1            /* text descriptors to be displayed   */
  529. X#define SLOT_OVF 2            /* text descriptor overflows slot     */
  530. X
  531. X                    /**    return codes for proc_dir()   **/
  532. X#define RECALL_PROC 1            /* force proc_dir() to be recalled    */
  533. X#define EMPTY_DIR 2            /* selected directory is empty          */
  534. X
  535. X#define NORMAL 1
  536. X#define HIGHLITE 2
  537. X
  538. X#define PROT_MAX 10            /* max. length of protection string   */
  539. X#define DATE_MAX 12            /* max. length of date/time string    */
  540. X#define DNAME_MAX 14            /* max. length of displayed filename  */
  541. X#define FILEMARK_MAX 1            /* max. length of filetype mark          */
  542. X#define DISP_MAX DNAME_MAX+FILEMARK_MAX /* max. length of filename & mark     */
  543. X#define SIZE_MAX 8            /* max. length of filesize string     */
  544. X#define OWNER_MAX 8            /* max. length of owner string          */
  545. X#define GROUP_MAX 8            /* max. length of group string          */
  546. X#define FIELD_GAP 2            /* space between fields in a slot     */
  547. X#define SLOT_GAP 3            /* space between slots on a screen    */
  548. X#define FULL_MAX PROT_MAX + DATE_MAX + DISP_MAX + OWNER_MAX + \
  549. SIZE_MAX + GROUP_MAX + (FIELD_GAP * 5)
  550. X#define MESS_MAX 255            /* max. length of broadcast message   */
  551. X#define STR_MAX 255            /* max. length of help input line     */
  552. X#define TYPE_MAX 3            /* max. length of displayed filetype  */
  553. X#define SPEC_MAX 255            /* max. length of filename          */
  554. X#define FULL_SPEC_MAX 255        /* max. length of full file spec      */
  555. X#define RESP_MAX 80            /* max. length of response from tty   */
  556. X#define COMMAND_MAX 4            /* max. number of commands per file   */
  557. X#define TEXT_MAX 40            /* max. length of text descriptor     */
  558. X#define DIR_TEXT_MAX 70            /* max. length of directory text desc */
  559. X#define DATE_TIME_MAX 23        /* max. length of a date/time string  */
  560. X#define BUF_MAX 16384            /* buffer size for block mode copying */
  561. X#define PAGE_NO_MAX 4            /* max. digits in screen number          */
  562. X#define DIR_NAME_MAX MAXNAMLEN        /* this is system-dependent          */
  563. X#define PROMPT_MAX 80            /* max.length of a prompt string      */
  564. X#define ID_STR_MAX 16            /* max. length of uid/gid string      */
  565. X#define TIME_STR_MAX 24            /* time string from ctime(3)          */
  566. X#define PROT_INP_MAX 9            /* max. length of protect str read in */
  567. X                    /* from the screen              */
  568. X
  569. X/* maximum number of file rows; this is used to allocate the static array
  570. X * for holding file scree nodes
  571. X */
  572. X
  573. X#define MAX_NODE_ROW (MAX_SCREEN_ROWS - (SPEC_WINDOW_ROWS + \
  574. X STAT_WINDOW_ROWS + 1))
  575. X
  576. X#define MAX_NODE_COL ((MAX_SCREEN_COLS + (DISP_MAX + \
  577. SLOT_GAP - 1))/(DISP_MAX + SLOT_GAP))
  578. X
  579. X#define MIN_SLOT_WIDTH 16        /* minimum slot width              */
  580. X#define MIN_DISP_LEN 5            /* display >= 5 chars for inputting   */
  581. X#define FLAG_CHAR '+'            /* long filename flag character          */
  582. X#define TAG_CHAR '>'            /* tag for making marks on files      */
  583. X#define OPT_STRING_MAX 40        /* option id string              */
  584. X
  585. X#define GROUP_SAVE 150            /* number of gids to save          */
  586. X#define OWNER_SAVE 150            /* number of uids to save          */
  587. X
  588. X#define IN_REC_SIZE 512            /* size of input record buffer          */
  589. X#define TEXT_REC_MAX 112        /* max. length of text descriptor rec */
  590. X#define FUDGE_FACTOR 35            /* multiplied by number of elements   */
  591. X                    /* needed to get the size of the      */
  592. X                    /* memory pool to allocate          */
  593. X
  594. X/* these must coincide with the fields in the arg_strings structure that
  595. X * is defined in main.c
  596. X */
  597. X
  598. X#define SIZE_OPT 0
  599. X#define PROT_OPT 1
  600. X#define DATE_OPT 2
  601. X#define GROUP_OPT 3
  602. X#define OWNER_OPT 4
  603. X#define CONFIRM_OPT 5
  604. X#define AUTO_FEED_OPT 6
  605. X#define TEXT_OPT 7
  606. X#define DOT_FILES_OPT 8
  607. X#define FILEMARKS_OPT 9
  608. X#define SORT_OPT 10
  609. X#define NUM_OPT_STRINGS 11
  610. X
  611. X#define TEXT_FILE ".maint.tdf"        /* name of text descriptor file          */
  612. X
  613. X#define DELETE 'd'            /* file command definitions          */
  614. X#define RENAME 'r'
  615. X#define COPY 'c'
  616. X#define PROTECT 'p'
  617. X#define TEXT 't'
  618. X#define GROUP 'g'
  619. X#define OWNER 'o'
  620. X                    /* -S option flag values          */
  621. X#define FILENAME 1            /* sort by filename              */
  622. X#define TYPE 2                /* sort by file type              */
  623. X#define SIZE 3                /* sort by file size              */
  624. X#define DATE 4                /* sort by date                  */
  625. X#define NUM_SORT_OPT 4            /* number of highest sort option      */
  626. X
  627. X#define REGULAR '-'
  628. X#define DIRECTORY 'd'
  629. X#define CHARACTER 'c'
  630. X#define BLOCK 'b'
  631. X#define FIFO 'p'
  632. X#define SOCKET 's'
  633. X#define LINK 'l'
  634. X
  635. X#define CONTROL_B 0x2
  636. X#define CONTROL_D 0x4
  637. X#define CONTROL_F 0x6
  638. X#define CONTROL_G 0x7
  639. X#define CONTROL_H 0x8
  640. X#define CONTROL_I 0x9
  641. X#define CONTROL_K 0xB
  642. X#define CONTROL_L 0xC
  643. X#define CONTROL_P 0x10
  644. X#define CONTROL_R 0x12
  645. X#define CONTROL_W 0x17
  646. X#define CONTROL_Z 0x1a
  647. X#define LINEFEED 0xA
  648. X#define CARRIAGE_RETURN 0xD
  649. X#define BACKSPACE 0x8
  650. X#define ESCAPE 0x1b
  651. X
  652. X#define kbytes(size) (((size) + 1023) / 1024)
  653. X#define info_mess(message) write_mess(message,A_BOLD,0)
  654. X#define xmess(message,prefix_len) write_mess(message,A_REVERSE,prefix_len)
  655. X
  656. X#if defined(SYSV) && !defined(sun)
  657. X
  658. X/* stuff that needs to be defined for System V */
  659. X
  660. X#define vfork fork            /* no vfork()                  */
  661. X#define dbtob(db) ((unsigned)(db) << BSHIFT)
  662. X#define R_OK 04                /* for access()                  */
  663. X
  664. X#endif
  665. X
  666. X/******************************************************************************/
  667. X/*                                                                            */
  668. X/*          S T R U C T U R E S ,   U N I O N S ,   T Y P E D E F S           */
  669. X/*                                                                            */
  670. X/******************************************************************************/
  671. X
  672. X#if defined(SYSV) && !defined(sun)
  673. X
  674. typedef unsigned long int u_long;    /* I like underscores....          */
  675. typedef unsigned int u_int;
  676. typedef unsigned short int u_short;
  677. typedef unsigned char u_char;
  678. typedef int gid_t,uid_t;
  679. X
  680. X#endif
  681. X
  682. X#ifdef SUNOS3
  683. X
  684. X/* weird...SunOS 3.X doesn't have typedefs for uid_t and gid_t in sys/types.h;
  685. X * however, SunOS 4.0 does and it doesn't match the pw_uid and pw_gid fields
  686. X * in the passwd struct in pwd.h -- they are ints and the typedefs for uid_t
  687. X * and gid_t in sys/types.h are u_short.....sigh.....
  688. X */
  689. X
  690. typedef     int      uid_t, gid_t;        
  691. X
  692. X#endif
  693. X
  694. typedef     struct      NODE_TYP {        /* screen position node              */
  695. X     short      left_row,           /* row-coordinate for node array      */
  696. X          left_col,        /* column-coordinate for node array   */
  697. X          right_row,        /* row-coordinate for node array      */
  698. X          right_col,        /* column-coordinate for node array   */
  699. X          down_row,        /* row-coordinate for node array      */
  700. X          down_col,        /* column-coordinate for node array   */
  701. X          up_row,        /* row-coordinate for node array      */
  702. X          up_col,        /* column-coordinate for node array   */
  703. X          row,            /* cursor row coordinate for node     */
  704. X          column;        /* cursor column coordinate for node  */
  705. X} NODE_DEF;
  706. X
  707. typedef     struct      ARG_TYP {        /* run-time argument flags          */
  708. X     short      sort,            /* wants files sorted              */
  709. X          size,            /* wants size field included          */
  710. X          prot,            /* wants protection field included    */
  711. X          date,            /* wants date field included          */
  712. X          def,            /* wants just default info          */
  713. X          group,        /* wants group field              */
  714. X          owner,        /* wants owner field              */
  715. X          wide,            /* wants 132-column mode          */
  716. X          confirm,        /* wants to be asked before Xecuting  */
  717. X          auto_feed,        /* wants autofeed on Delete/Unmark    */
  718. X          text_startup,        /* set if -t on command line          */
  719. X          text,            /* wants text descriptors included    */
  720. X          dot_files,        /* wants files starting with .          */
  721. X          filemarks;        /* / for dirs, * for executables, etc */
  722. X} ARG_DEF;
  723. X
  724. typedef     struct      ARG_STR_TYP {        /* strings for configuring on the fly */
  725. X     char      string[OPT_STRING_MAX+1];
  726. X     short      *ptr;            /* pointer into arg structure          */
  727. X} ARG_STR;
  728. X
  729. typedef     struct      COM_TYP {        /* file command definition type          */
  730. X     char      *copy_name,        /* new filename for copying          */
  731. X          *ren_name,        /* new filename for renaming          */
  732. X          *text;        /* text descriptor string          */
  733. X     gid_t      group;        /* new group value              */
  734. X     uid_t      owner;        /* new owner for file              */
  735. X     u_short  prot;            /* protection value              */
  736. X     short      copy_len,        /* max. length of copy filename str.  */
  737. X          ren_len,        /* max. length of rename filename str */
  738. X          text_len;        /* max. length of text string          */
  739. X     char      comm_text,        /* text descriptor for file          */
  740. X          comm_del,        /* file is to be deleted          */
  741. X          comm_prot,        /* new protection for file          */
  742. X          comm_copy,        /* file is to be copied              */
  743. X          comm_ren,        /* file is to be renamed          */
  744. X          comm_grp,        /* change group of file              */
  745. X          comm_own;        /* change owner of file              */
  746. X     char      dummy[3];        /* pad-out; might not be necessary    */
  747. X} COM_DEF;
  748. X
  749. typedef     struct      ENT_TYP {        /* file entry definition type          */
  750. X     COM_DEF  *command;        /* commands for file              */
  751. X       char      *filename,        /* real filename              */
  752. X          *text;        /* text descriptor              */
  753. X     size_t      size;            /* in blocks                  */
  754. X     time_t      time;            /* whatever type of time desired..... */
  755. X     uid_t      uid;            /* owner id of file              */
  756. X     gid_t      gid;            /* group id of file              */
  757. X     u_short  prot,            /* integer protection value          */
  758. X          name_len,        /* length of scr_name minus padding   */
  759. X          disp_len;        /* displayed length of full filename  */
  760. X     u_char      type,            /* file type                  */
  761. X          mark_flag;        /* set if file is Marked          */
  762. X     char      scr_name[DISP_MAX+1];    /* displayed filename and filemark    */
  763. X} ENT_DEF;
  764. X
  765. typedef     struct      POOL_TYP {        /* memory pool node structure          */
  766. X     char      *ptr,            /* pointer to next byte in pool          */
  767. X          *first;        /* pointer to beginning of pool          */
  768. struct     POOL_TYP *next_pool;        /* pointer to next memory pool          */
  769. X     size_t      remaining,        /* # of remaining bytes in pool          */
  770. X          length;        /* original length of pool          */
  771. X} POOL_DEF;
  772. X
  773. typedef     struct      OPT_TYPE {        /* displayed options definition          */
  774. X     char      *keystr,        /* keystroke for command          */
  775. X            *remaining,        /* rest of chars in command          */
  776. X          key_len,        /* length of keystroke for command    */
  777. X          rem_len,        /* length of rest of chars in command */
  778. X          spaces;        /* number of spaces after command def */
  779. X} OPT_DEF;
  780. X
  781. typedef     struct      {            /* saved uid/gid entry              */
  782. X     uid_t      id;            /* uid/gid saved              */
  783. X     char      str[ID_STR_MAX+1];    /* associated string              */
  784. X} ID_ENT;
  785. X
  786. typedef     struct      {            /* summary info of directory entries  */
  787. X     ENT_DEF  *ptr;            /* pointer to directory info          */
  788. X     short      num_file;        /* number of files in directory          */
  789. X} DIR_SUMM;
  790. X
  791. typedef     struct      DIR_TYPE {        /* directory info link structure      */
  792. X     ENT_DEF  *dirptr;        /* pointer to directory information   */
  793. X     char      *dir_name;        /* name of directory              */
  794. struct     DIR_TYPE *prev,        /* pointer to previous directory node */
  795. X          *next;        /* pointer to next directory node     */
  796. X     POOL_DEF *first_pool,        /* first memory pool for directory    */
  797. X          *curr_pool;        /* current memory pool for directory  */
  798. X     size_t      pool_length;        /* length for allocating new pools    */
  799. X     time_t      stat_time;        /* when directory was last modified   */
  800. X     u_short  count;        /* number of times directory entered  */
  801. X     short      num_file;        /* number of files in directory          */
  802. X} DIR_PTR;
  803. X
  804. X/******************************************************************************/
  805. X/*                                                                            */
  806. X/*   E X T E R N A L   D E F I N I T I O N S   &   D E C L A R A T I O N S    */
  807. X/*                                                                            */
  808. X/******************************************************************************/
  809. X
  810. X
  811. X/******************************************************************************/
  812. X/*                                                                            */
  813. X/*     S T A T I C   D E F I N I T I O N S   &   D E C L A R A T I O N S      */
  814. X/*                                                                            */
  815. X/******************************************************************************/
  816. X
  817. X#endif
  818. END_OF_FILE
  819. if test 15883 -ne `wc -c <'maint.h.dist'`; then
  820.     echo shar: \"'maint.h.dist'\" unpacked with wrong size!
  821. fi
  822. # end of 'maint.h.dist'
  823. fi
  824. if test -f 'options.c' -a "${1}" != "-c" ; then 
  825.   echo shar: Will not clobber existing file \"'options.c'\"
  826. else
  827. echo shar: Extracting \"'options.c'\" \(12468 characters\)
  828. sed "s/^X//" >'options.c' <<'END_OF_FILE'
  829. X/******************************************************************************
  830. X*******************************************************************************
  831. X
  832. X   Site:    Western Michigan University Academic Computer Center
  833. X
  834. X   System:    Directory/File System Maintenance
  835. X  
  836. X   Program:    maint
  837. X
  838. X   Version=01    Level=00    01/24/92    Leonard J. Peirce
  839. X
  840. X   Purpose:    Allow the user to change the configuration options on the fly.
  841. X
  842. X   Arguments:    See individual routine(s).
  843. X
  844. X   External variables:    None
  845. X
  846. X   Maint external functions:
  847. X
  848. X    Defined:    config_options
  849. X
  850. X    Called:
  851. X
  852. X   Files accessed:    None
  853. X
  854. X   Return codes:    See individual routine(s).
  855. X
  856. X   Compiling instructions:    See Makefile
  857. X
  858. X   Linking instructions:    See Makefile
  859. X
  860. X   Other information:    (C) Copyright 1992, Leonard J. Peirce
  861. X
  862. X********************************************************************************
  863. X*******************************************************************************/
  864. X
  865. X/******************************************************************************/
  866. X/*                                                                            */
  867. X/*                        # I N C L U D E   F I L E S                         */
  868. X/*                                                                            */
  869. X/******************************************************************************/
  870. X
  871. X#ifdef ultrix
  872. X#include <cursesX.h>
  873. X#else
  874. X#include <curses.h>
  875. X#endif
  876. X#include "maint.h"
  877. X
  878. X/******************************************************************************/
  879. X/*                                                                            */
  880. X/*                             # D E F I N E S                                */
  881. X/*                                                                            */
  882. X/******************************************************************************/
  883. X
  884. X/******************************************************************************/
  885. X/*                                                                            */
  886. X/*          S T R U C T U R E S ,   U N I O N S ,   T Y P E D E F S           */
  887. X/*                                                                            */
  888. X/******************************************************************************/
  889. X
  890. X/******************************************************************************/
  891. X/*                                                                            */
  892. X/*   E X T E R N A L   D E F I N I T I O N S   &   D E C L A R A T I O N S    */
  893. X/*                                                                            */
  894. X/******************************************************************************/
  895. X
  896. extern     ARG_STR  arg_strings[];
  897. X
  898. X     int      config_options();
  899. X
  900. X/******************************************************************************/
  901. X/*                                                                            */
  902. X/*     S T A T I C   D E F I N I T I O N S   &   D E C L A R A T I O N S      */
  903. X/*                                                                            */
  904. X/******************************************************************************/
  905. X
  906. X/*******************************************************************************
  907. X********************************************************************************
  908. X
  909. X  Function:    config_options
  910. X
  911. X  Purpose:    Let the user view/change configuration options.
  912. X
  913. X  Global variables:
  914. X
  915. X    Name            Examine/Modify/Use/Read/Write
  916. X    ----            -----------------------------
  917. X    none
  918. X
  919. X  Return Codes:
  920. X
  921. X    Code            Reason
  922. X    ----            ------
  923. X    REBUILD_DIRECTORY    entire directory must be reinitialized
  924. X    REBUILD_SCREEN        only screen layout was affected
  925. X    REBUILD_WITH_FILEMARKS    include filemarks for files
  926. X    REBUILD_WITH_SORT    sort files when rebuild is performed
  927. X    NO_REBUILD        don't have to rebuild anything
  928. X
  929. X********************************************************************************
  930. X*******************************************************************************/
  931. X
  932. int config_options(args)
  933. X                    /*******   FORMAL  PARAMETERS   *******/
  934. register ARG_DEF *args;            /* run-time arguments              */
  935. X
  936. X{    /*** config_options ***/
  937. X                    /********   LOCAL  VARIABLES   ********/
  938. register short      term_code;        /* keystroke read in              */
  939. X     WINDOW      *window;        /* for displaying/reading options     */
  940. X     int      rows,            /* rows in option window          */
  941. X          columns,        /* columns in option window          */
  942. X          curr_row,        /* current screen row              */
  943. X          curr_col,        /* current screen column          */
  944. X          retval;        /* return code                  */
  945. X     short      i;            /* loop and array index              */
  946. X     ARG_DEF  tmp_args;        /* for saving current arguments          */
  947. X     char      buf[MAX_SCREEN_COLS+1];
  948. static     char      *opt_banner[] = {
  949. X"                               Configuration menu",
  950. X"      Use Arrow Keys to select, space to toggle option, control-D to finish"};
  951. X
  952. X
  953. X   /* save current run-time arguments to see if anything has actually
  954. X    * changed when the user is done
  955. X    */
  956. X
  957. X   memcpy(&tmp_args,args,sizeof(tmp_args));
  958. X
  959. X   /* set up the screen */
  960. X
  961. X   rows = LINES - SPEC_WINDOW_ROWS;
  962. X   columns = COLS;
  963. X   window = newwin(rows,columns,2,0);
  964. X   werase(window);
  965. X   keypad(window,TRUE);
  966. X   curr_row = 0;
  967. X
  968. X   /* write the configuration options and their current values */
  969. X
  970. X   while(curr_row < NUM_OPT_STRINGS)
  971. X   {
  972. X      /* create the line first */
  973. X
  974. X      if(curr_row == SORT_OPT)
  975. X      {
  976. X     strcpy(buf,arg_strings[SORT_OPT].string);
  977. X
  978. X     switch(args->sort)
  979. X     {
  980. X        case(DATE):
  981. X
  982. X           strcat(buf,"date    ");
  983. X           break;
  984. X
  985. X        case(SIZE):
  986. X
  987. X           strcat(buf,"size    ");
  988. X           break;
  989. X
  990. X        case(FILENAME):
  991. X
  992. X           strcat(buf,"filename");
  993. X           break;
  994. X
  995. X        default:
  996. X
  997. X           strcat(buf,"none    ");
  998. X           break;
  999. X     }
  1000. X      }
  1001. X      else
  1002. X      {
  1003. X     strcpy(buf,arg_strings[curr_row].string);
  1004. X     strcat(buf,*(arg_strings[curr_row].ptr) ? "yes" : "no ");
  1005. X      }
  1006. X
  1007. X      mvwaddstr(window,curr_row++,1,buf);
  1008. X   }
  1009. X
  1010. X   /* print the instructions for changing the options */
  1011. X
  1012. X   i = rows - (sizeof(opt_banner) / sizeof(char *));
  1013. X
  1014. X   while(curr_row < i)
  1015. X   {
  1016. X      wmove(window,curr_row,0);
  1017. X      waddch(window,'X');
  1018. X      wmove(window,curr_row,0);
  1019. X      wclrtoeol(window);
  1020. X      curr_row++;
  1021. X   }
  1022. X
  1023. X   /* write the instructions to the screen */
  1024. X
  1025. X   i = 0;
  1026. X   wattron(window,A_BOLD);
  1027. X
  1028. X   while(i < (sizeof(opt_banner) / sizeof(char *)))
  1029. X      mvwaddstr(window,curr_row++,0,opt_banner[i++]);
  1030. X
  1031. X   curr_row = 0;
  1032. X   curr_col = 0;
  1033. X   wmove(window,curr_row,curr_col);
  1034. X   wrefresh(window);
  1035. X
  1036. X   /* now ask for input until the user presses ESCAPE to exit */
  1037. X
  1038. X   term_code = wgetch(window);
  1039. X
  1040. X   while(term_code != CONTROL_D)
  1041. X   {
  1042. X      switch(term_code)
  1043. X      {
  1044. X     case('G'):
  1045. X     case('g'):
  1046. X        term_code = ' ';
  1047. X        curr_row = GROUP_OPT;
  1048. X        break;
  1049. X
  1050. X     case('O'):
  1051. X     case('o'):
  1052. X        term_code = ' ';
  1053. X        curr_row = OWNER_OPT;
  1054. X        break;
  1055. X
  1056. X     case('s'):
  1057. X        term_code = ' ';
  1058. X        curr_row = SIZE_OPT;
  1059. X        break;
  1060. X
  1061. X     case('P'):
  1062. X     case('p'):
  1063. X        term_code = ' ';
  1064. X        curr_row = PROT_OPT;
  1065. X        break;
  1066. X
  1067. X     case('D'):
  1068. X     case('d'):
  1069. X        term_code = ' ';
  1070. X        curr_row = DATE_OPT;
  1071. X        break;
  1072. X
  1073. X     case('T'):
  1074. X     case('t'):
  1075. X        term_code = ' ';
  1076. X        curr_row = TEXT_OPT;
  1077. X        break;
  1078. X
  1079. X     case('C'):
  1080. X     case('c'):
  1081. X        term_code = ' ';
  1082. X        curr_row = CONFIRM_OPT;
  1083. X        break;
  1084. X
  1085. X     case('A'):
  1086. X        term_code = ' ';
  1087. X        curr_row = AUTO_FEED_OPT;
  1088. X        break;
  1089. X
  1090. X     case('a'):
  1091. X        term_code = ' ';
  1092. X        curr_row = DOT_FILES_OPT;
  1093. X        break;
  1094. X
  1095. X     case('f'):
  1096. X        term_code = ' ';
  1097. X        curr_row = FILEMARKS_OPT;
  1098. X        break;
  1099. X
  1100. X     case('S'):
  1101. X        term_code = ' ';
  1102. X        curr_row = SORT_OPT;
  1103. X        break;
  1104. X
  1105. X     default:
  1106. X        break;
  1107. X      }
  1108. X
  1109. X      switch(term_code)
  1110. X      {
  1111. X     case('j'):
  1112. X     case('J'):
  1113. X     case(CARRIAGE_RETURN):
  1114. X     case(KEY_DOWN):
  1115. X     case(LINEFEED):
  1116. X
  1117. X        if(curr_row < (NUM_OPT_STRINGS - 1))
  1118. X           wmove(window,++curr_row,curr_col);
  1119. X        else
  1120. X        {
  1121. X           curr_row = 0;
  1122. X           wmove(window,curr_row,curr_col);
  1123. X        }
  1124. X
  1125. X        break;
  1126. X
  1127. X     case('^'):
  1128. X     case('K'):
  1129. X     case('k'):
  1130. X     case(KEY_UP):
  1131. X
  1132. X        if(curr_row > 0)
  1133. X           wmove(window,--curr_row,curr_col);
  1134. X        else
  1135. X        {
  1136. X           curr_row = NUM_OPT_STRINGS - 1;
  1137. X           wmove(window,curr_row,curr_col);
  1138. X        }
  1139. X
  1140. X        break;
  1141. X
  1142. X     case(' '):
  1143. X
  1144. X        /* see where the user was when they toggled */
  1145. X
  1146. X        switch(curr_row)
  1147. X        {
  1148. X           case(SIZE_OPT):
  1149. X
  1150. X          args->size = !args->size;
  1151. X          strcpy(buf,arg_strings[SIZE_OPT].string);
  1152. X          strcat(buf,*(arg_strings[SIZE_OPT].ptr) ? "yes" : "no ");
  1153. X          mvwaddstr(window,curr_row,1,buf);
  1154. X          wmove(window,curr_row,0);
  1155. X          break;
  1156. X
  1157. X           case(PROT_OPT):
  1158. X
  1159. X          args->prot = !args->prot;
  1160. X          strcpy(buf,arg_strings[PROT_OPT].string);
  1161. X          strcat(buf,*(arg_strings[PROT_OPT].ptr) ? "yes" : "no ");
  1162. X          mvwaddstr(window,curr_row,1,buf);
  1163. X          wmove(window,curr_row,0);
  1164. X          break;
  1165. X
  1166. X           case(DATE_OPT):
  1167. X
  1168. X          args->date = !args->date;
  1169. X          strcpy(buf,arg_strings[DATE_OPT].string);
  1170. X          strcat(buf,*(arg_strings[DATE_OPT].ptr) ? "yes" : "no ");
  1171. X          mvwaddstr(window,curr_row,1,buf);
  1172. X          wmove(window,curr_row,0);
  1173. X          break;
  1174. X
  1175. X           case(GROUP_OPT):
  1176. X
  1177. X          args->group = !args->group;
  1178. X          strcpy(buf,arg_strings[GROUP_OPT].string);
  1179. X          strcat(buf,*(arg_strings[GROUP_OPT].ptr) ? "yes" : "no ");
  1180. X          mvwaddstr(window,curr_row,1,buf);
  1181. X          wmove(window,curr_row,0);
  1182. X          break;
  1183. X
  1184. X           case(OWNER_OPT):
  1185. X
  1186. X          args->owner = !args->owner;
  1187. X          strcpy(buf,arg_strings[OWNER_OPT].string);
  1188. X          strcat(buf,*(arg_strings[OWNER_OPT].ptr) ? "yes" : "no ");
  1189. X          mvwaddstr(window,curr_row,1,buf);
  1190. X          wmove(window,curr_row,0);
  1191. X          break;
  1192. X
  1193. X           case(CONFIRM_OPT):
  1194. X
  1195. X          args->confirm = !args->confirm;
  1196. X          strcpy(buf,arg_strings[CONFIRM_OPT].string);
  1197. X          strcat(buf,*(arg_strings[CONFIRM_OPT].ptr) ? "yes" : "no ");
  1198. X          mvwaddstr(window,curr_row,1,buf);
  1199. X          wmove(window,curr_row,0);
  1200. X          break;
  1201. X
  1202. X           case(AUTO_FEED_OPT):
  1203. X
  1204. X          args->auto_feed = !args->auto_feed;
  1205. X          strcpy(buf,arg_strings[AUTO_FEED_OPT].string);
  1206. X          strcat(buf,*(arg_strings[AUTO_FEED_OPT].ptr) ? "yes" : "no ");
  1207. X          mvwaddstr(window,curr_row,1,buf);
  1208. X          wmove(window,curr_row,0);
  1209. X          break;
  1210. X
  1211. X           case(TEXT_OPT):
  1212. X
  1213. X          args->text = !args->text;
  1214. X
  1215. X          /* set the text_startup flag so that the width of the
  1216. X           * of the text descriptors won't be taken into account
  1217. X           * when updating def_slot_wid in set_args()
  1218. X           */
  1219. X
  1220. X          args->text_startup = !args->text_startup;
  1221. X          strcpy(buf,arg_strings[TEXT_OPT].string);
  1222. X          strcat(buf,*(arg_strings[TEXT_OPT].ptr) ? "yes" : "no ");
  1223. X          mvwaddstr(window,curr_row,1,buf);
  1224. X          wmove(window,curr_row,0);
  1225. X          break;
  1226. X
  1227. X           case(DOT_FILES_OPT):
  1228. X
  1229. X          args->dot_files = !args->dot_files;
  1230. X          strcpy(buf,arg_strings[DOT_FILES_OPT].string);
  1231. X          strcat(buf,*(arg_strings[DOT_FILES_OPT].ptr) ? "yes" : "no ");
  1232. X          mvwaddstr(window,curr_row,1,buf);
  1233. X          wmove(window,curr_row,0);
  1234. X          break;
  1235. X
  1236. X           case(FILEMARKS_OPT):
  1237. X
  1238. X          args->filemarks = !args->filemarks;
  1239. X          strcpy(buf,arg_strings[FILEMARKS_OPT].string);
  1240. X          strcat(buf,*(arg_strings[FILEMARKS_OPT].ptr) ? "yes" : "no ");
  1241. X          mvwaddstr(window,curr_row,1,buf);
  1242. X          wmove(window,curr_row,0);
  1243. X          break;
  1244. X
  1245. X           case(SORT_OPT):
  1246. X
  1247. X          args->sort = (args->sort + 1) % (NUM_SORT_OPT + 1);
  1248. X          strcpy(buf,arg_strings[SORT_OPT].string);
  1249. X
  1250. X          switch(args->sort)
  1251. X          {
  1252. X             case(DATE):
  1253. X
  1254. X            strcat(buf,"date    ");
  1255. X            break;
  1256. X
  1257. X             case(TYPE):
  1258. X
  1259. X            strcat(buf,"type    ");
  1260. X            break;
  1261. X
  1262. X             case(SIZE):
  1263. X
  1264. X            strcat(buf,"size    ");
  1265. X            break;
  1266. X
  1267. X             case(FILENAME):
  1268. X
  1269. X            strcat(buf,"filename");
  1270. X            break;
  1271. X
  1272. X             default:
  1273. X
  1274. X            strcat(buf,"none    ");
  1275. X            break;
  1276. X          }
  1277. X
  1278. X          mvwaddstr(window,curr_row,1,buf);
  1279. X          wmove(window,curr_row,0);
  1280. X          break;
  1281. X
  1282. X           default:            /* shouldn't happen              */
  1283. X
  1284. X          break;
  1285. X        }
  1286. X
  1287. X        break;
  1288. X
  1289. X     default:
  1290. X
  1291. X        beep();
  1292. X        break;
  1293. X      }
  1294. X
  1295. X      wrefresh(window);
  1296. X      term_code = wgetch(window);
  1297. X   }
  1298. X
  1299. X   werase(window);            /* kill everything              */
  1300. X   wrefresh(window);
  1301. X   delwin(window);
  1302. X
  1303. X   retval = NO_REBUILD;
  1304. X
  1305. X   if(memcmp(&tmp_args,args,sizeof(tmp_args)) != 0)
  1306. X   {
  1307. X      /* something really happened */
  1308. X
  1309. X      if(args->dot_files != tmp_args.dot_files)
  1310. X     retval |= REBUILD_DIRECTORY;
  1311. X
  1312. X      if(args->size != tmp_args.size ||
  1313. X     args->prot != tmp_args.prot ||
  1314. X     args->date != tmp_args.date ||
  1315. X     args->owner != tmp_args.owner ||
  1316. X     args->group != tmp_args.group ||
  1317. X     args->filemarks != tmp_args.filemarks ||
  1318. X     args->sort != tmp_args.sort ||
  1319. X     args->text != tmp_args.text)
  1320. X     retval |= REBUILD_SCREEN;
  1321. X
  1322. X      if(args->filemarks != tmp_args.filemarks)
  1323. X     retval |= REBUILD_WITH_FILEMARKS;
  1324. X
  1325. X      if(args->sort && !tmp_args.filemarks)
  1326. X     retval |= REBUILD_WITH_SORT;
  1327. X   }
  1328. X
  1329. X   return(retval);
  1330. X
  1331. X}    /*** config_options ***/
  1332. END_OF_FILE
  1333. if test 12468 -ne `wc -c <'options.c'`; then
  1334.     echo shar: \"'options.c'\" unpacked with wrong size!
  1335. fi
  1336. # end of 'options.c'
  1337. fi
  1338. if test -f 'pool.c' -a "${1}" != "-c" ; then 
  1339.   echo shar: Will not clobber existing file \"'pool.c'\"
  1340. else
  1341. echo shar: Extracting \"'pool.c'\" \(13024 characters\)
  1342. sed "s/^X//" >'pool.c' <<'END_OF_FILE'
  1343. X/******************************************************************************
  1344. X*******************************************************************************
  1345. X
  1346. X   Site:    Western Michigan University Academic Computer Center
  1347. X
  1348. X   System:    Directory/File System Maintenance
  1349. X  
  1350. X   Program:    maint
  1351. X
  1352. X   Version=01    Level=00    01/24/92    Leonard J. Peirce
  1353. X
  1354. X   Purpose:    Routines for handling memory pools.
  1355. X
  1356. X   Arguments:    See individual routines.
  1357. X
  1358. X   External variables:    See individual routines.
  1359. X
  1360. X   External functions:
  1361. X
  1362. X    Defined:    free_pool, get_pool_mem, init_pool, new_pool, put_pool,
  1363. X            reset_pool
  1364. X
  1365. X    Called:        None
  1366. X
  1367. X   Files accessed:    None
  1368. X
  1369. X   Return codes:    See individual routines
  1370. X
  1371. X   Compiling instructions:    See Makefile
  1372. X
  1373. X   Linking instructions:    See Makefile
  1374. X
  1375. X   Other information:    Copyright (C) 1992, Leonard J. Peirce
  1376. X
  1377. X********************************************************************************
  1378. X*******************************************************************************/
  1379. X
  1380. X/******************************************************************************/
  1381. X/*                                                                            */
  1382. X/*                        # I N C L U D E   F I L E S                         */
  1383. X/*                                                                            */
  1384. X/******************************************************************************/
  1385. X
  1386. X#include <stdio.h>
  1387. X#include <malloc.h>
  1388. X#include "maint.h"
  1389. X#include <string.h>
  1390. X
  1391. X/******************************************************************************/
  1392. X/*                                                                            */
  1393. X/*                             # D E F I N E S                                */
  1394. X/*                                                                            */
  1395. X/******************************************************************************/
  1396. X
  1397. X/******************************************************************************/
  1398. X/*                                                                            */
  1399. X/*          S T R U C T U R E S ,   U N I O N S ,   T Y P E D E F S           */
  1400. X/*                                                                            */
  1401. X/******************************************************************************/
  1402. X
  1403. X/******************************************************************************/
  1404. X/*                                                                            */
  1405. X/*   E X T E R N A L   D E F I N I T I O N S   &   D E C L A R A T I O N S    */
  1406. X/*                                                                            */
  1407. X/******************************************************************************/
  1408. X
  1409. X     char      *get_pool_mem();
  1410. X
  1411. X     POOL_DEF *new_pool();
  1412. X
  1413. X     void      init_pool(),
  1414. X          put_pool(),
  1415. X          free_pool(),
  1416. X          reset_pool();
  1417. X
  1418. X/******************************************************************************/
  1419. X/*                                                                            */
  1420. X/*     S T A T I C   D E F I N I T I O N S   &   D E C L A R A T I O N S      */
  1421. X/*                                                                            */
  1422. X/******************************************************************************/
  1423. X
  1424. X/*******************************************************************************
  1425. X********************************************************************************
  1426. X
  1427. X  Function:    init_pool
  1428. X
  1429. X  Purpose:    Allocate the first memory pool for the current directory,
  1430. X        initializing the pool structure node and initialize all of
  1431. X        the other structures to point to null pools.  The remaining
  1432. X        pool node structures are linked together in a linked list.
  1433. X
  1434. X  Global variables:
  1435. X
  1436. X    Name            Examine/Modify/Use/Read/Write
  1437. X    ----            -----------------------------
  1438. X    none
  1439. X
  1440. X  Return Codes:
  1441. X                 
  1442. X    Code            Reason
  1443. X    ----            ------
  1444. X    none
  1445. X
  1446. X  Termination Codes:
  1447. X
  1448. X    Code            Reason
  1449. X    ----            ------
  1450. X    CANT_ALLOC        cannot allocate memory
  1451. X
  1452. X********************************************************************************
  1453. X*******************************************************************************/
  1454. X
  1455. void init_pool(pool,pool_length)
  1456. X                    /*******   FORMAL  PARAMETERS   *******/
  1457. X     POOL_DEF **pool;        /* array of pool node structures      */
  1458. X     size_t      pool_length;        /* length of pool to allocate          */
  1459. X
  1460. X{    /*** init_pool ***/
  1461. X                    /********   LOCAL  VARIABLES   ********/
  1462. register POOL_DEF *tptr;        /* temporary pool node structure ptr  */
  1463. X
  1464. X
  1465. X   /* allocate memory for the pool node structure first */
  1466. X
  1467. X   tptr = (POOL_DEF *) malloc(sizeof(POOL_DEF));
  1468. X
  1469. X   if(tptr == NULL)
  1470. X   {
  1471. X      puts("*ERROR*  Cannot allocate memory in init_pool #1");
  1472. X      exit(CANT_ALLOCATE);
  1473. X   }
  1474. X
  1475. X   /* allocate memory for the first pool and initialize all of the other
  1476. X    * accounting stuff associated with it
  1477. X    */
  1478. X
  1479. X   tptr->first = (char *) malloc((u_int) pool_length);
  1480. X
  1481. X   if(tptr == NULL)
  1482. X   {
  1483. X      puts("*ERROR*  Cannot allocate memory in init_pool #2");
  1484. X      exit(CANT_ALLOCATE);
  1485. X   }
  1486. X
  1487. X   /* set up the other stuff for the first memory pool */
  1488. X
  1489. X   tptr->ptr = tptr->first;        /* set pointer to available memory    */
  1490. X   tptr->remaining = pool_length;    /* all bytes in pool available          */
  1491. X   tptr->next_pool = NULL;        /* terminate the linked list....      */
  1492. X   tptr->length = pool_length;        /* save original length of pool          */
  1493. X   *pool = tptr;            /* start everything....              */
  1494. X
  1495. X   return;
  1496. X
  1497. X}    /*** init_pool ***/
  1498. X
  1499. X/*******************************************************************************
  1500. X********************************************************************************
  1501. X
  1502. X  Function:    reset_pool
  1503. X
  1504. X  Purpose:    Reset the pool pointers so that the memory allocated for them
  1505. X        can be used again without reallocating the memory.
  1506. X
  1507. X  Global variables:
  1508. X
  1509. X    Name            Examine/Modify/Use/Read/Write
  1510. X    ----            -----------------------------
  1511. X    none
  1512. X
  1513. X  Return Codes:
  1514. X
  1515. X    Code            Reason
  1516. X    ----            ------
  1517. X    none
  1518. X
  1519. X********************************************************************************
  1520. X*******************************************************************************/
  1521. X
  1522. void reset_pool(pool)
  1523. X                    /*******   FORMAL  PARAMETERS   *******/
  1524. register POOL_DEF *pool;        /* memory pool node structures          */
  1525. X
  1526. X{    /*** reset_pool ***/                 
  1527. X
  1528. X   while(pool != NULL)
  1529. X   {
  1530. X      pool->ptr = pool->first;        /* reset available byte pointer          */
  1531. X      pool->remaining = pool->length;    /* reset number of bytes available    */
  1532. X      pool = pool->next_pool;        /* go to next pool node structure     */
  1533. X   }
  1534. X
  1535. X   return;
  1536. X
  1537. X}    /*** reset_pool ***/
  1538. X
  1539. X/*******************************************************************************
  1540. X********************************************************************************
  1541. X
  1542. X  Function:    new_pool
  1543. X
  1544. X  Purpose:    allocate memory for a pool node structure and the actual
  1545. X        memory for the pool; also link the pool to the pool list.
  1546. X
  1547. X  Global variables:
  1548. X
  1549. X    Name            Examine/Modify/Use/Read/Write
  1550. X    ----            -----------------------------
  1551. X    none
  1552. X
  1553. X  Return Codes:
  1554. X
  1555. X    Code            Reason
  1556. X    ----            ------
  1557. X    none
  1558. X
  1559. X********************************************************************************
  1560. X*******************************************************************************/
  1561. X
  1562. POOL_DEF *new_pool(pool,pool_length)
  1563. X                    /*******   FORMAL  PARAMETERS   *******/
  1564. register POOL_DEF *pool;        /* pointer to current memory pool     */
  1565. X     size_t      pool_length;        /* length of pool to allocate          */
  1566. X
  1567. X{    /*** new_pool ***/
  1568. X                    /********   LOCAL  VARIABLES   ********/
  1569. X     POOL_DEF *tptr;        /* temporary pool pointer          */
  1570. X
  1571. X
  1572. X   /* first see if there is a pool already out there; if there is,
  1573. X    * just return so that we don't have to reuse the memory
  1574. X    */
  1575. X
  1576. X   if(pool->next_pool != NULL)        /* is there a pool out there?          */
  1577. X      return(pool->next_pool);        /* yes, just return a pointer to it   */
  1578. X
  1579. X   /* at this point we have conceded that a new memory pool is needed; allocate
  1580. X    * the structure to hold the new pool's accounting information
  1581. X    */
  1582. X
  1583. X   init_pool(&tptr,pool_length);
  1584. X
  1585. X   pool->next_pool = tptr;        /* link to current pool              */
  1586. X   pool = pool->next_pool;        /* move to new pool structure          */
  1587. X
  1588. X   return(tptr);            /* return pointer to new pool struct. */
  1589. X
  1590. X}    /*** new_pool ***/
  1591. X
  1592. X/*******************************************************************************
  1593. X********************************************************************************
  1594. X
  1595. X  Function:    put_pool
  1596. X
  1597. X  Purpose:    Copy a string to a memory pool.  If the current pool does not
  1598. X        have enough memory to accomodate the string, allocate a new
  1599. X        pool first and then copy the string to the new pool.
  1600. X
  1601. X  Global variables:
  1602. X
  1603. X    Name            Examine/Modify/Use/Read/Write
  1604. X    ----            -----------------------------
  1605. X    none
  1606. X
  1607. X  Return Codes:
  1608. X
  1609. X    Code            Reason
  1610. X    ----            ------
  1611. X    none
  1612. X
  1613. X********************************************************************************
  1614. X*******************************************************************************/
  1615. X
  1616. void put_pool(dest,pool,str,length,pool_length)
  1617. X                    /*******   FORMAL  PARAMETERS   *******/
  1618. X     char      **dest;        /* where to store pointer to str      */
  1619. X     POOL_DEF **pool;        /* current memory pool structure      */
  1620. X     char      *str;            /* string to be stored in memory pool */
  1621. X     size_t      length;        /* length of string to be stored      */
  1622. X     size_t      pool_length;        /* length of pool if we need another  */
  1623. X                
  1624. X{    /*** put_pool ***/
  1625. X                    /********   LOCAL  VARIABLES   ********/
  1626. register POOL_DEF *tptr;        /* temporary pool structure pointer   */
  1627. X
  1628. X
  1629. X   if((*pool)->remaining < (length + 1)) /* has the pool run dry....?          */
  1630. X   {
  1631. X      *pool = new_pool(*pool,pool_length); /* yes, get another pool          */
  1632. X   }
  1633. X
  1634. X   tptr = *pool;            /* set up temporary pool struct. ptr. */
  1635. X   strcpy(tptr->ptr,str);        /* copy the string to the pool          */
  1636. X   *dest = tptr->ptr;            /* set the pointer to the string      */
  1637. X   tptr->ptr = tptr->ptr + length + 1;    /* update available memory pointer    */
  1638. X   tptr->remaining = tptr->remaining - (length + 1);
  1639. X
  1640. X   return;
  1641. X
  1642. X}    /*** put_pool ***/
  1643. X
  1644. X/*******************************************************************************
  1645. X********************************************************************************
  1646. X
  1647. X  Function:    get_pool_mem
  1648. X
  1649. X  Purpose:    Return a pointer to a memory slot that will satisfy the request.
  1650. X
  1651. X  Global variables:
  1652. X
  1653. X    Name            Examine/Modify/Use/Read/Write
  1654. X    ----            -----------------------------
  1655. X    none
  1656. X
  1657. X  Return Codes:
  1658. X
  1659. X    Code            Reason
  1660. X    ----            ------
  1661. X    retptr            pointer to memory slot
  1662. X
  1663. X********************************************************************************
  1664. X*******************************************************************************/
  1665. X
  1666. char *get_pool_mem(pool,pool_length,length)
  1667. X                    /*******   FORMAL  PARAMETERS   *******/
  1668. register POOL_DEF **pool;        /* current memory pool              */
  1669. X     size_t      pool_length,        /* length of pool to request          */
  1670. X          length;        /* length of memory slot needed          */
  1671. X
  1672. X{    /*** get_pool_mem ***/
  1673. X                    /********   LOCAL  VARIABLES   ********/
  1674. register char      *retptr;        /* pointer to return              */
  1675. register POOL_DEF *tptr;        /* used to speed things up a bit....  */
  1676. X
  1677. X
  1678. X   /* is there enough room in the current memory pool?  If not, allocate
  1679. X    * another one and get the memory from there
  1680. X    */
  1681. X
  1682. X   if((*pool)->remaining < (length + 1))
  1683. X      *pool = new_pool(*pool,pool_length);
  1684. X
  1685. X   tptr = *pool;            /* make a pointer              */
  1686. X
  1687. X   /* we have the memory, whether it is in a new pool or the one we had on
  1688. X    * entry; update the pool structure to reflect the memory that we need
  1689. X    * to take from it
  1690. X    */
  1691. X
  1692. X   retptr = tptr->ptr;            /* save pointer to memory slot          */
  1693. X   tptr->ptr = tptr->ptr + length + 1L;
  1694. X   tptr->remaining = tptr->remaining - (length + 1);
  1695. X   
  1696. X   return(retptr);            /* return pointer to slot          */
  1697. X
  1698. X}    /*** get_pool_mem ***/
  1699. X
  1700. X/*******************************************************************************
  1701. X********************************************************************************
  1702. X
  1703. X  Function:    free_pool
  1704. X
  1705. X  Purpose:    Free the memory of all of the memory pools for a directory,
  1706. X        including the node structures for all of the nodes.  This
  1707. X        routine will be called when exiting a directory.
  1708. X
  1709. X  Global variables:
  1710. X
  1711. X    Name            Examine/Modify/Use/Read/Write
  1712. X    ----            -----------------------------
  1713. X    none
  1714. X
  1715. X  Return Codes:
  1716. X
  1717. X    Code             Reason
  1718. X    ----            ------
  1719. X    none
  1720. X
  1721. X********************************************************************************
  1722. X*******************************************************************************/
  1723. X
  1724. void free_pool(pool)
  1725. X                    /*******   FORMAL  PARAMETERS   *******/
  1726. register POOL_DEF *pool;        /* first pool in pool node list          */
  1727. X
  1728. X{    /*** free_pool ***/
  1729. X                    /********   LOCAL  VARIABLES   ********/
  1730. register POOL_DEF *tpool;        /* temporary pool node pointer          */
  1731. X
  1732. X
  1733. X
  1734. X   while(pool != NULL)
  1735. X   {
  1736. X      /* free the memory for the pool first */
  1737. X
  1738. X      tpool = pool->next_pool;        /* save pointer to next pool node     */
  1739. X      free(pool->first);        /* free the memory              */
  1740. X      free((char *) pool);        /* free memory for pool node struct.  */
  1741. X      pool = tpool;            /* move to next pool in list          */
  1742. X   }
  1743. X
  1744. X   return;
  1745. X
  1746. X}    /*** free_pool ***/
  1747. END_OF_FILE
  1748. if test 13024 -ne `wc -c <'pool.c'`; then
  1749.     echo shar: \"'pool.c'\" unpacked with wrong size!
  1750. fi
  1751. # end of 'pool.c'
  1752. fi
  1753. if test -f 'slot.c' -a "${1}" != "-c" ; then 
  1754.   echo shar: Will not clobber existing file \"'slot.c'\"
  1755. else
  1756. echo shar: Extracting \"'slot.c'\" \(16586 characters\)
  1757. sed "s/^X//" >'slot.c' <<'END_OF_FILE'
  1758. X/******************************************************************************
  1759. X*******************************************************************************
  1760. X
  1761. X   Site:    Western Michigan University Academic Computer Center
  1762. X
  1763. X   System:    Directory/File System Maintenance
  1764. X  
  1765. X   Program:    maint
  1766. X
  1767. X   Version=01    Level=00    01/24/92    Leonard J. Peirce
  1768. X
  1769. X   Purpose:    Routines for creating file slots and gathering info for
  1770. X        Expanding.
  1771. X
  1772. X   Arguments:    See individual routines.
  1773. X
  1774. X   External variables:    None
  1775. X
  1776. X   WMU external functions:
  1777. X
  1778. X          Defined:    get_group, get_owner, make_slot
  1779. X
  1780. X          Called:    add_filetype, mystrcpy, mystrmcpy, padcpy,
  1781. X            prot_val_to_str, set_date
  1782. X
  1783. X   Files accessed:    See individual routines.
  1784. X
  1785. X   Return codes:    See individual routines.
  1786. X
  1787. X   Compiling instructions:    See Makefile.
  1788. X
  1789. X   Linking instructions:    See Makefile.
  1790. X
  1791. X   Other information:    (C) Copyright 1992, Leonard J. Peirce
  1792. X
  1793. X********************************************************************************
  1794. X*******************************************************************************/
  1795. X
  1796. X/******************************************************************************/
  1797. X/*                                                                            */
  1798. X/*                        # I N C L U D E   F I L E S                         */
  1799. X/*                                                                            */
  1800. X/******************************************************************************/
  1801. X
  1802. X#ifdef ultrix
  1803. X#include <cursesX.h>
  1804. X#else
  1805. X#include <curses.h>
  1806. X#endif
  1807. X#include <stdio.h>
  1808. X#include <string.h>
  1809. X#include <ctype.h>
  1810. X#include <pwd.h>
  1811. X#include <grp.h>
  1812. X#include "maint.h"
  1813. X
  1814. X/******************************************************************************/
  1815. X/*                                                                            */
  1816. X/*                             # D E F I N E S                                */
  1817. X/*                                                                            */
  1818. X/******************************************************************************/
  1819. X
  1820. X/******************************************************************************/
  1821. X/*                                                                            */
  1822. X/*          S T R U C T U R E S ,   U N I O N S ,   T Y P E D E F S           */
  1823. X/*                                                                            */
  1824. X/******************************************************************************/
  1825. X
  1826. X/******************************************************************************/
  1827. X/*                                                                            */
  1828. X/*   E X T E R N A L   D E F I N I T I O N S   &   D E C L A R A T I O N S    */
  1829. X/*                                                                            */
  1830. X/******************************************************************************/
  1831. X
  1832. extern     char      *mystrcpy(),
  1833. X          *mystrmcpy(),
  1834. X          *prot_val_to_str(),
  1835. X          *padcpy(),
  1836. X          *set_date();
  1837. X
  1838. X#if defined(SYSV) || defined(sun)
  1839. extern     void      setpwent(),
  1840. X          setgrent();
  1841. X#else
  1842. extern     int      setpwent(),
  1843. X          setgrent();
  1844. X#endif
  1845. X
  1846. extern     u_short  add_filetype();
  1847. X
  1848. X     char      *get_owner(),
  1849. X          *get_group();
  1850. X
  1851. X     int      make_slot();
  1852. X
  1853. X/******************************************************************************/
  1854. X/*                                                                            */
  1855. X/*     S T A T I C   D E F I N I T I O N S   &   D E C L A R A T I O N S      */
  1856. X/*                                                                            */
  1857. X/******************************************************************************/
  1858. X
  1859. X/*******************************************************************************
  1860. X********************************************************************************
  1861. X
  1862. X  Function:    make_slot
  1863. X
  1864. X  Purpose:    Make a slot to be displayed on the screen for a file depending
  1865. X        on the (possible) commands associated with the file.  In
  1866. X        some cases, some funny stuff will be done with the screen
  1867. X        slot to connotate that the file has some commands associated
  1868. X        with it.
  1869. X
  1870. X  Global variables:
  1871. X
  1872. X    Name            Examine/Modify/Use/Read/Write
  1873. X    ----            -----------------------------
  1874. X    none
  1875. X
  1876. X  Return Codes:
  1877. X
  1878. X    Code            Reason
  1879. X    ----            ------
  1880. X    A_NORMAL        file slot is normal
  1881. X    A_BOLD            file has commands; highlite it
  1882. X
  1883. X********************************************************************************
  1884. X*******************************************************************************/
  1885. X
  1886. int make_slot(buf,ent,args,slot_width,text_flag)
  1887. X                     /*******   FORMAL  PARAMETERS   *******/
  1888. X     char      *buf;            /* where to put the screen slot          */
  1889. register ENT_DEF  *ent;            /* file entry pointer              */
  1890. register ARG_DEF  *args;        /* run-time arguments              */
  1891. X     short      slot_width,        /* width of a screen slot          */
  1892. X          text_flag;        /* whether we display text descrips   */
  1893. X
  1894. X{    /*** make_slot ***/
  1895. X                    /********   LOCAL  VARIABLES   ********/
  1896. register char      *tptr;        /* temporary pointer              */
  1897. X     char      *text_ptr = NULL;    /* pointer to text descriptor          */
  1898. X     COM_DEF  *ptr;            /* pointer to possible command struct */
  1899. static     u_short  pass;            /* set if we've been here before      */
  1900. static     char      gap_buf[FIELD_GAP+1],    /* inter-field gap buffer          */
  1901. X          gap_buf2[SLOT_GAP+1], /* inter-slot gap buffer          */
  1902. X          text_buf[TEXT_MAX+1],    /* for formatting text descriptors    */
  1903. X          size_buf[SIZE_MAX+1],    /* for formatting size of file          */
  1904. X          blnk_text[TEXT_MAX+1], /* blank text descriptor          */
  1905. X          del_str1[] = {"<del>"},
  1906. X          del_str2[] = {"<delete>"};
  1907. X
  1908. X
  1909. X   if(!pass)
  1910. X   {
  1911. X      for(pass = 0; pass < FIELD_GAP; pass++)
  1912. X     gap_buf[pass] = ' ';
  1913. X      for(pass = 0; pass < SLOT_GAP; pass++)
  1914. X     gap_buf2[pass] = ' ';
  1915. X      for(pass = 0; pass < TEXT_MAX; pass++)
  1916. X     blnk_text[pass] = ' ';
  1917. X      pass = 1;
  1918. X   }
  1919. X
  1920. X   /* now see if there are commands associated with the file; we do things
  1921. X    * a little differently if there are
  1922. X    */
  1923. X
  1924. X   ptr = ent->command;
  1925. X
  1926. X   if(ptr != NULL)
  1927. X   {
  1928. X      if(ptr->comm_del)            /* is the file going to be deleted?   */
  1929. X      {
  1930. X     /* yes, now see if there is enough room to put in the "<delete>"
  1931. X      * string
  1932. X      */
  1933. X
  1934. X     if(slot_width <= (DISP_MAX + sizeof(del_str2)))
  1935. X     {
  1936. X        /* the slot is only big enough to use <del> to signify that the
  1937. X         * file is marked for deletion
  1938. X         */
  1939. X
  1940. X        strcpy(buf,ent->scr_name);
  1941. X        strcpy(&buf[DISP_MAX - sizeof(del_str1) + 1],del_str1);
  1942. X
  1943. X        if(ent->disp_len > (DISP_MAX - sizeof(del_str1) + 1))
  1944. X        {
  1945. X           buf[slot_width] = FLAG_CHAR;
  1946. X           buf[slot_width + 1] = '\0';
  1947. X        }
  1948. X     }
  1949. X     else
  1950. X     {
  1951. X        /* use the regular "<delete>" string to show that the user
  1952. X         * marked the file to be deleted
  1953. X         */
  1954. X
  1955. X        sprintf(buf,"%s%s                                         \
  1956. X                                    ",ent->scr_name,del_str2);
  1957. X
  1958. X        if(ent->disp_len > DISP_MAX)
  1959. X            buf[DISP_MAX + sizeof(del_str2) - 1] = FLAG_CHAR;
  1960. X
  1961. X        *(buf + slot_width + SLOT_GAP) = '\0';
  1962. X     }
  1963. X
  1964. X     return((int) A_BOLD);        /* just return from here          */
  1965. X      }
  1966. X
  1967. X      /* no, the file is not going to be deleted, but it might have some other
  1968. X       * command associated with it; check them to be sure
  1969. X       */
  1970. X
  1971. X      /* which text descriptor pointer should we use? */
  1972. X
  1973. X      if(text_flag == DISPLAY_TEXT)    /* should we display text descriptor? */
  1974. X      {
  1975. X     /* yes, text descriptors are to be displayed on the screen; now
  1976. X      * determine which, if any, text descriptor to use for the
  1977. X      * current file
  1978. X      */
  1979. X
  1980. X     if(ptr->comm_text)        /* use new text descriptor?          */
  1981. X     {
  1982. X        /* use the new text descriptor for the slot */
  1983. X
  1984. X        padcpy(text_buf,ptr->text,TEXT_MAX);
  1985. X        text_ptr = text_buf;    /* set the pointer to the text desc.  */
  1986. X     }
  1987. X     else if(ent->text != NULL)    /* or should we use the original?     */
  1988. X     {
  1989. X        /* use the original text descriptor for the file */
  1990. X
  1991. X        padcpy(text_buf,ent->text,TEXT_MAX);
  1992. X        text_ptr = text_buf;    /* set the pointer to the text desc.  */
  1993. X     }
  1994. X     else                /* or should we use a blank desc?     */
  1995. X     {
  1996. X        /* this file has no text descriptor; use a blank one to make
  1997. X         * sure that we completely write over any text descriptor that
  1998. X         * might been written in the current slot before this
  1999. X         */
  2000. X
  2001. X        text_ptr = blnk_text;    /* use a blank text descriptor          */
  2002. X     }
  2003. X      }
  2004. X   }
  2005. X
  2006. X   /* now create the slot */
  2007. X
  2008. X   if(text_flag == DISPLAY_TEXT && !text_ptr)
  2009. X   {
  2010. X      /* yes, we want text descriptors, they don't overflow the slots,
  2011. X       * and this file doesn't have a new one specified for it
  2012. X       */
  2013. X
  2014. X      if(ent->text != NULL)        /* is there a text descriptor?          */
  2015. X      {
  2016. X     /* there IS a text descriptor for this file; pad the text descriptor
  2017. X      * on the right with spaces so that if there was a descriptor on the
  2018. X      * screen in this slot (perhaps from a previous page) it will be
  2019. X      * completely overwritten by the current one
  2020. X      */
  2021. X
  2022. X     padcpy(text_buf,ent->text,TEXT_MAX);
  2023. X     text_ptr = text_buf;        /* set the pointer to the text desc.  */
  2024. X      }
  2025. X      else
  2026. X     text_ptr = blnk_text;        /* use a blank text descriptor          */
  2027. X   }
  2028. X
  2029. X   /* collect all of the information necessary to make the slot */
  2030. X
  2031. X   tptr = buf;
  2032. X   tptr = mystrcpy(buf,ent->scr_name);
  2033. X
  2034. X   /* write a gap buf just in case a file still has a FLAG_CHAR there
  2035. X    * from before; this can happen when the displayed filename will just fit
  2036. X    * on the screen, the user selects Delete, and then Unmarks it;
  2037. X    * we don't move tptr because if there is anything else that will
  2038. X    * go into this slot, it will just overwrite the extra gap_buf
  2039. X    */
  2040. X
  2041. X   mystrcpy(tptr,gap_buf);
  2042. X
  2043. X   if(args->owner)
  2044. X   {
  2045. X      tptr = mystrcpy(tptr,gap_buf);
  2046. X      tptr = mystrmcpy(tptr,get_owner(ent->uid),OWNER_MAX);
  2047. X   }
  2048. X
  2049. X   if(args->group)
  2050. X   {
  2051. X      tptr = mystrcpy(tptr,gap_buf);
  2052. X      tptr = mystrmcpy(tptr,get_group(ent->gid),GROUP_MAX);
  2053. X   }
  2054. X
  2055. X   if(args->size)            /* should the size be included?          */
  2056. X   { 
  2057. X      tptr = mystrcpy(tptr,gap_buf);
  2058. X      sprintf(size_buf,"%8d",ent->size);
  2059. X      tptr = mystrcpy(tptr,size_buf);
  2060. X   }
  2061. X
  2062. X   if(args->date)
  2063. X   {
  2064. X      tptr = mystrcpy(tptr,gap_buf);
  2065. X      tptr = mystrcpy(tptr,set_date(ent->time));
  2066. X   }
  2067. X
  2068. X   if(args->prot)
  2069. X   {
  2070. X      tptr = mystrcpy(tptr,gap_buf);
  2071. X      tptr = mystrcpy(tptr,prot_val_to_str(ent->prot));
  2072. X   }
  2073. X
  2074. X   if(text_flag == DISPLAY_TEXT)    /* do we display the text descrips?   */
  2075. X   {
  2076. X      /* yes, they don't overflow the file slots; now see if there is one
  2077. X       * for the current file
  2078. X       */
  2079. X
  2080. X      tptr = mystrcpy(tptr,gap_buf);
  2081. X
  2082. X      if(text_ptr != NULL)        /* use new text descriptor?          */
  2083. X     tptr = mystrcpy(tptr,text_ptr);
  2084. X      else
  2085. X     tptr = mystrcpy(tptr,blnk_text);
  2086. X   }
  2087. X
  2088. X   if(ent->name_len > DNAME_MAX)    /* flag it if it's too long          */
  2089. X   {
  2090. X      if(buf[DISP_MAX] == '\0')
  2091. X      {
  2092. X     buf[DISP_MAX] = FLAG_CHAR;
  2093. X     buf[DISP_MAX+1] = '\0';
  2094. X      }
  2095. X      else
  2096. X     buf[DISP_MAX] = FLAG_CHAR;
  2097. X
  2098. X      tptr++;
  2099. X   }
  2100. X
  2101. X   tptr = mystrcpy(tptr,gap_buf2);
  2102. X
  2103. X   return(ent->command ? (int) A_BOLD : (int) A_NORMAL);
  2104. X
  2105. X}    /*** make_slot ***/
  2106. X
  2107. X/*******************************************************************************
  2108. X********************************************************************************
  2109. X
  2110. X  Function:    get_group    
  2111. X
  2112. X  Purpose:    Return the string associated with a group id.  Gids that are
  2113. X        successfully translated are saved to speed up future trans-
  2114. X        lations.
  2115. X
  2116. X  Global variables:
  2117. X
  2118. X    Name            Examine/Modify/Use/Read/Write
  2119. X    ----            -----------------------------
  2120. X    none
  2121. X
  2122. X  Return Codes:
  2123. X
  2124. X    Code            Reason
  2125. X    ----            ------
  2126. X    retptr            pointer to group string, padded out to
  2127. X                ID_STR_MAX with spaces
  2128. X
  2129. X********************************************************************************
  2130. X*******************************************************************************/
  2131. X
  2132. char *get_group(gid)
  2133. X                    /*******   FORMAL  PARAMETERS   *******/
  2134. X     gid_t      gid;            /* group id value              */
  2135. X
  2136. X{    /*** get_group ***/
  2137. X                    /********   LOCAL  VARIABLES   ********/
  2138. struct     group      *gptr;        /* for using getgrent              */
  2139. X     char      *retptr;        /* group string to return          */
  2140. X     u_short  i;            /* loop and array index              */
  2141. static     u_short  count;        /* number of group ids saved          */
  2142. static     ID_ENT      groups[GROUP_SAVE];    /* list of groups already retrieved   */
  2143. static     char      buf[ID_STR_MAX+1];    /* used for formatting              */
  2144. X
  2145. X
  2146. X   /* first search the groups that are already saved */
  2147. X
  2148. X   i = 0;
  2149. X   while((i < count) && gid != groups[i].id)
  2150. X      ++i;
  2151. X
  2152. X   if(i >= count)            /* did we find the gid?              */
  2153. X   {
  2154. X      gptr = getgrgid((int) gid);    /* nope, go get it....              */
  2155. X
  2156. X      if(gptr != NULL)            /* did we find it?              */
  2157. X      {
  2158. X     /* we found it; now save it if we have room */
  2159. X
  2160. X     if(count < GROUP_SAVE)        /* do we have room?              */
  2161. X     {
  2162. X        groups[count].id = gid;    /* yes, save the gid and string...    */
  2163. X        padcpy(groups[count].str,gptr->gr_name,ID_STR_MAX);
  2164. X        retptr = groups[count].str;
  2165. X        count++;            /* count it since we saved it          */
  2166. X     }
  2167. X     else
  2168. X     {
  2169. X        /* no room to save it; put it in buf, padded with spaces on the
  2170. X         * right
  2171. X         */
  2172. X
  2173. X        padcpy(buf,gptr->gr_name,ID_STR_MAX);
  2174. X        retptr = buf;
  2175. X     }
  2176. X      }
  2177. X      else
  2178. X      {
  2179. X     /* we didn't find it; convert the gid to a string and use that */        
  2180. X     sprintf(buf,"%-8d",gid);
  2181. X
  2182. X     /* we might as well save it just in case we get another file
  2183. X      * that has the same gid
  2184. X      */
  2185. X
  2186. X     if(count < GROUP_SAVE)        /* do we have room?              */
  2187. X     {
  2188. X        groups[count].id = gid;    /* yes, save the gid and string...    */
  2189. X        padcpy(groups[count].str,buf,ID_STR_MAX);
  2190. X        retptr = groups[count].str;    /* set return pointer              */
  2191. X        count++;
  2192. X     }
  2193. X     else
  2194. X        retptr = buf;        /* no room to save it              */
  2195. X      }
  2196. X
  2197. X      setgrent();            /* to rewind the file, basically..... */
  2198. X   }
  2199. X   else
  2200. X      retptr = groups[i].str;        /* we found it....              */
  2201. X
  2202. X   return(retptr);
  2203. X
  2204. X}    /*** get_group ***/
  2205. X
  2206. X/*******************************************************************************
  2207. X********************************************************************************
  2208. X
  2209. X  Function:    get_owner    
  2210. X
  2211. X  Purpose:    Return the string corresponding to the owner of a file
  2212. X        based on the uid that is passed.  Uids that are successfully
  2213. X        translated are saved to speed up future translations.
  2214. X
  2215. X  Global variables:
  2216. X
  2217. X    Name            Examine/Modify/Use/Read/Write
  2218. X    ----            -----------------------------
  2219. X    none
  2220. X
  2221. X  Return Codes:
  2222. X
  2223. X    Code            Reason
  2224. X    ----            ------
  2225. X    retptr            pointer to owner string, padded out to
  2226. X                ID_STR_MAX with spaces
  2227. X
  2228. X********************************************************************************
  2229. X*******************************************************************************/
  2230. X
  2231. char *get_owner(uid)
  2232. X                    /*******   FORMAL  PARAMETERS   *******/
  2233. X     uid_t      uid;            /* user id value              */
  2234. X
  2235. X{    /*** get_owner ***/
  2236. X                    /********   LOCAL  VARIABLES   ********/
  2237. struct     passwd      *uptr;        /* for using getpwuid              */
  2238. X     char      *retptr;        /* owner string to return          */
  2239. X     u_short  i;            /* loop and array index              */
  2240. static     u_short  count;        /* number of user ids saved          */
  2241. static     ID_ENT      owners[OWNER_SAVE];    /* list of user ids already retrieved */
  2242. static     char      buf[ID_STR_MAX+1];    /* used for formatting              */
  2243. X
  2244. X
  2245. X   /* first search the uids that are already saved */
  2246. X
  2247. X   i = 0;
  2248. X   while((i < count) && uid != owners[i].id)
  2249. X      ++i;
  2250. X
  2251. X   if(i >= count)            /* did we find the uid?              */
  2252. X   {
  2253. X      uptr = getpwuid((int) uid);    /* nope, go get it....              */
  2254. X
  2255. X      if(uptr != NULL)            /* did we find it?              */
  2256. X      {
  2257. X     /* we found it; now save it if we have room */
  2258. X
  2259. X     if(count < OWNER_SAVE)        /* do we have room?              */
  2260. X     {
  2261. X        owners[count].id = uid;    /* yes, save the uid and string...    */
  2262. X        padcpy(owners[count].str,uptr->pw_name,ID_STR_MAX);
  2263. X        retptr = owners[count].str;
  2264. X        count++;            /* count it since we saved it          */
  2265. X     }
  2266. X     else
  2267. X     {
  2268. X        /* no room to save it; put it in buf, padded with spaces on the
  2269. X         * right
  2270. X         */
  2271. X
  2272. X        padcpy(buf,uptr->pw_name,ID_STR_MAX);
  2273. X        retptr = buf;
  2274. X     }
  2275. X      }
  2276. X      else
  2277. X      {
  2278. X     /* we didn't find it; convert the gid to a string and use that */        
  2279. X     sprintf(buf,"%-8d",uid);
  2280. X
  2281. X     /* we might as well save it just in case we get another file
  2282. X      * that has the same uid
  2283. X      */
  2284. X
  2285. X     if(count < OWNER_SAVE)        /* do we have room?              */
  2286. X     {
  2287. X        owners[count].id = uid;    /* yes, save the gid and string...    */
  2288. X        padcpy(owners[count].str,buf,ID_STR_MAX);
  2289. X        retptr = owners[count].str;
  2290. X        count++;            /* count it since we saved it          */
  2291. X     }
  2292. X     else
  2293. X        retptr = buf;
  2294. X      }
  2295. X
  2296. X      setpwent();            /* to rewind the file, basically..... */
  2297. X   }
  2298. X   else
  2299. X      retptr = owners[i].str;        /* we found it....              */
  2300. X
  2301. X   return(retptr);
  2302. X
  2303. X}    /*** get_owner ***/
  2304. END_OF_FILE
  2305. if test 16586 -ne `wc -c <'slot.c'`; then
  2306.     echo shar: \"'slot.c'\" unpacked with wrong size!
  2307. fi
  2308. # end of 'slot.c'
  2309. fi
  2310. echo shar: End of archive 2 \(of 7\).
  2311. cp /dev/null ark2isdone
  2312. MISSING=""
  2313. for I in 1 2 3 4 5 6 7 ; do
  2314.     if test ! -f ark${I}isdone ; then
  2315.     MISSING="${MISSING} ${I}"
  2316.     fi
  2317. done
  2318. if test "${MISSING}" = "" ; then
  2319.     echo You have unpacked all 7 archives.
  2320.     rm -f ark[1-9]isdone
  2321. else
  2322.     echo You still need to unpack the following archives:
  2323.     echo "        " ${MISSING}
  2324. fi
  2325. ##  End of shell archive.
  2326. exit 0
  2327.