home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-05-13 | 80.4 KB | 2,636 lines |
- Newsgroups: comp.sources.unix
- From: peirce@gw.wmich.edu (Leonard J. Peirce)
- Subject: v26i055: maint - full-screen file and directory maintenance tool, Part07/07
- Sender: unix-sources-moderator@pa.dec.com
- Approved: vixie@pa.dec.com
-
- Submitted-By: peirce@gw.wmich.edu (Leonard J. Peirce)
- Posting-Number: Volume 26, Issue 55
- Archive-Name: maint/part07
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 7 (of 7)."
- # Contents: main.c
- # Wrapped by vixie@cognition.pa.dec.com on Thu May 14 23:05:44 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'main.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'main.c'\"
- else
- echo shar: Extracting \"'main.c'\" \(78195 characters\)
- sed "s/^X//" >'main.c' <<'END_OF_FILE'
- X/******************************************************************************
- X*******************************************************************************
- X
- X Site: Western Michigan University Academic Computer Center
- X
- X System: Directory/File System Maintenance
- X
- X Program: maint
- X
- X Version=01 Level=00 01/24/92 Leonard J. Peirce
- X
- X Purpose: This program provides the user with a full-screen method for
- X maintaining directories and file systems. The directory
- X will be presented to the user in a series of screens, each
- X of which will contain information about individual files.
- X The user may move through a directory structure, marking files
- X for deletion, changing protection modes, renaming files,
- X creating text descriptors, copying files, editing files, and
- X viewing files. Other options are available to allow the user
- X to fork a subprocess to return to shell and search for a
- X file.
- X
- X See the manual page maint.1 for more details.
- X
- X Arguments:
- X
- X -a auto-advance the cursor on
- X Delete or Unmark
- X -c ask for confirmation before executing
- X -d include date field for files
- X -f full info; implies -ogds
- X -g include group name for files
- X -o include owner field for files
- X -p include protection field for files
- X -s include size (in bytes) for files
- X -t start up in text mode
- X -S <sort-opt> sort files by <sort-opt>; legal
- X values are: size, date, protection,
- X filename; default is filename
- X
- X External variables: See individual routine(s)
- X
- X Maint external functions:
- X
- X Defined: None
- X
- X Called: cat, check_marks, clean_up, clear_mess, config_options,
- X create_text, edit, erase_tag, file_locate,
- X file_ptr_locate, file_select, follow_link, free_comm,
- X free_pool, get_args, get_bnum, get_dir, get_dir_mem,
- X get_filemarks, get_num_file, get_scr_num, give_help,
- X highlite, info, init_pool, initialize, make_screen,
- X make_slot, mark_cancel, mark_copy_ren, mark_delete,
- X mark_group, mark_owner, mark_protect, mark_rename,
- X mark_repeat, mark_text, prompt_getstr, put_pagnum,
- X put_slot, put_spec, put_stat, put_text, read_text_des,
- X screen_reset, set_args, set_nodes, set_screen,
- X sort_files, strindex, strmcpy, strdel, tag_file, xecute
- X
- X Files accessed: only those in the directory and possibly .maint.tdf
- X in other directories
- X
- X Return codes: 0 Successful completion
- X
- X Compiling instructions: See Makefile.
- X
- X Linking instructions: See Makefile.
- X
- X Other information: (C) Copyright 1992, Leonard J. Peirce
- X
- X Data structures:
- X
- X Several different data structures are used internally to Maint to store
- X all kinds of information, ranging from the filenames and related information
- X to text descriptors and new filenames.
- X
- X Directory information for the files in a directory is allocated dynamically
- X upon entry to the proc_dir() function. An automatic pointer, dirptr, is
- X used to point to the memory that holds the information about the files.
- X This pointer MUST remain automatic because each directory needs it own
- X copy. After the number of files in the directory is determined, the
- X amount of memory needed to hold the information about each file in the
- X directory can be calculated. It is calculated by taking the number of
- X files in the directory, adding one, and multiplying it by the length of
- X the structure definition ENT_DEF. This is the number of bytes needed.
- X The memory is allocated by calling malloc() and the pointer to the
- X memory is stored in dirptr.
- X
- X When a Finish command is issued or the commands in a directory are executed,
- X the memory is deallocated, the number of files is computed, the size of
- X the memory necessary is calculated, and the memory is allocated once again.
- X
- X A) Memory Pools
- X
- X MAINT uses its own memory pool allocation scheme. These memory pools are
- X used to store only CHARACTER data and thus there is no need to worry about
- X byte alignment for integer values and such. Items that are stored in the
- X memory pools include: 1) the full filename of a file, and 2) the text
- X descriptor of the file in case the user selects Text mode.
- X
- X The pools are allocated on a demand basis and are linked together into a
- X linked list. The size of each memory pool in the list can vary, depending
- X on the state of the information that will be included for each directory.
- X The global variable ent_factor is initially set to FUDGE_FACTOR, which is
- X a guess at the number of bytes that each file entry is going to need to
- X store its information. Then the run-time arguments are taken into account,
- X with ent_factor being updated for each that argument that will require
- X something stored in the memory pools. See the routine set_factors() for
- X the values that ent_factor is increased by.
- X
- X When it is time to redo the information for a directory, the memory in the
- X memory pools is reclaimed rather than released and reallocated. The pointer
- X to the next available byte in the structure is set to point to the beginning
- X of the memory pool and the remaining length is reset to the original length
- X of the pool. This may waste a little memory but it saves a few calls that
- X would be needed to free and reallocate the memory.
- X
- X B) Command structures
- X
- X Command structures are used to hold the information necessary to carry out
- X commands for a specific file. When the first command for a file is speci-
- X fied by the user, a new command structure is allocated and linked to the
- X file entry for the file, the pointer to the command structure being stored
- X in the command field of the ENT_DEF structure.
- X
- X All of the information in the command structure that requires string values
- X (such as ren_name, copy_name, and text) are stored in memory allocated by
- X malloc() and NOT in a memory pool. This is to cut down on wasting of
- X memory for file commands that are cancelled.
- X
- X When commands for a file are cancelled, all the memory for any of the char-
- X acter strings are freed (via free()) and the command structure itself
- X is freed.
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- X/******************************************************************************/
- X/* */
- X/* # I N C L U D E F I L E S */
- X/* */
- X/******************************************************************************/
- X
- X#ifdef ultrix
- X#include <cursesX.h>
- X#include <unistd.h>
- X#else
- X#include <curses.h>
- X#include <sys/file.h>
- X#endif
- X#include <sys/param.h>
- X#include <sys/stat.h>
- X#include <stdio.h> /* who knows? (NULL maybe?) */
- X#include <time.h> /* for getting current year value */
- X#include <string.h> /* string functions */
- X#include <malloc.h> /* so free is declared right */
- X#include "maint.h" /* our very own header file */
- X
- X/******************************************************************************/
- X/* */
- X/* # D E F I N E S */
- X/* */
- X/******************************************************************************/
- X
- X#define MAX_DIR 15 /* max. # of subdirectories to save */
- X
- X/******************************************************************************/
- X/* */
- 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 */
- X/* */
- X/******************************************************************************/
- X
- X/******************************************************************************/
- X/* */
- 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 */
- X/* */
- X/******************************************************************************/
- X
- extern char *getenv();
- X
- extern u_int sleep();
- X
- extern int strindex(),
- X access();
- X
- extern long get_bnum();
- X
- extern int mark_text(),
- X mark_delete(),
- X mark_copy_ren(),
- X mark_protect(),
- X mark_rename(),
- X mark_repeat(),
- X mark_owner(),
- X mark_group(),
- X check_marks(),
- X put_slot(),
- X file_select(),
- X edit(),
- X make_slot(),
- X read_text_des(),
- X file_locate(),
- X file_ptr_locate(),
- X follow_link(),
- X config_options(),
- X create_text();
- X
- extern short info(),
- X get_num_file(),
- X get_scr_num();
- X
- extern void mark_cancel(),
- X free_comm(),
- X set_screen(),
- X set_args(),
- X set_nodes(),
- X get_args(),
- X get_dir_mem(),
- X get_dir(),
- X make_screen(),
- X init_pool(),
- X free_pool(),
- X initialize(),
- X put_stat(),
- X put_spec(),
- X put_pagnum(),
- X prompt_getstr(),
- X screen_reset(),
- X clear_mess(),
- X highlite(),
- X tag_file(),
- X erase_tag(),
- X clean_up(),
- X put_text(),
- X xecute(),
- X get_text(),
- X get_filemarks(),
- X give_help();
- X
- X#if defined(SYSV) && !defined(sun)
- X
- extern char *getcwd();
- extern u_short geteuid();
- X
- X#else
- X
- extern char *getwd();
- X
- X#endif
- X
- X ENT_DEF *baseptr; /* pointer to directory entries */
- X
- X WINDOW *spec_win, /* directory spec/page # window */
- X *main_win, /* main display window */
- X *stat_win; /* stats/options window */
- X
- X int *global_row, /* so others functions can use it */
- X *global_col, /* ditto.... */
- X curr_year, /* current year value */
- X main_rows; /* rows in main window */
- X
- X u_short node_row_max, /* max. # of rows in nodes array */
- X node_col_max, /* max. # of columns in nodes array */
- X cont_flag; /* set if continuing after suspend */
- X
- X ARG_DEF args; /* run-time argument flags */
- X
- X NODE_DEF nodes[MAX_NODE_ROW+1][MAX_NODE_COL+1];
- X
- X ARG_STR arg_strings[] = {
- X{"Include file size? (-s) ",&args.size},
- X{"Include file protection? (-p) ",&args.prot},
- X{"Include date? (-d) ",&args.date},
- X{"Include group? (-g) ",&args.group},
- X{"Include owner? (-o) ",&args.owner},
- X{"Confirm before Xecuting marks? (-c) ",&args.confirm},
- X{"Auto-feed on Delete/Unmark? (-A) ",&args.auto_feed},
- X{"Include text descriptors? (-t) ",&args.text},
- X{"Include dot-files? (-a) ",&args.dot_files},
- X{"Include file marks? (-F) ",&args.filemarks},
- X{"Sort field? (-S) ",&args.sort}
- X};
- X
- X/******************************************************************************/
- X/* */
- 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 */
- X/* */
- X/******************************************************************************/
- X
- static DIR_PTR dir_ent_head, /* head of directory node info list */
- X dir_ent_tail, /* tail....... */
- X *link_dir_ent(), /* link active directory node */
- X *find_dir(); /* for searching the list */
- X
- static size_t ent_factor; /* ent. size memory allocation factor */
- X
- static int home_len, /* length of home_dir */
- X get_year(), /* get current year value */
- X proc_dir(); /* process current directory */
- X
- static short def_slot_wid; /* default slot width */
- X
- static char home_dir[MAXPATHLEN+3];
- X
- static void unlink_dir_ent(); /* unlink active directory node */
- X
- X/******************************************************************************/
- X/* */
- X/* M A I N P R O C E S S I N G */
- X/* */
- X/******************************************************************************/
- X
- main(argc,argv)
- X /******* FORMAL PARAMETERS *******/
- X int argc; /* number of run-time arguments */
- X char **argv; /* run-time argument strings */
- X
- X{ /*** main ***/
- X /******** LOCAL VARIABLES ********/
- X short retval; /* return value from proc_dir() */
- X
- X
- X /* check the command-line arguments and set up 1) the screen width and 2)
- X * the slot width
- X */
- X
- X get_args(argc,argv,&args);
- X
- X curr_year = get_year(); /* get the current year */
- X
- X strcpy(home_dir,getenv("HOME"));
- X home_len = strlen(home_dir);
- X
- X /* initialize/allocate all of the windows that will be needed and get
- X * the necessary control strings from the termcap database
- X */
- X
- X initialize(&spec_win,&main_win,&stat_win,&node_row_max,&node_col_max);
- X
- X /* initialize some global factors, such as the ent_factor and default
- X * slot width
- X */
- X
- X set_args(&args,&def_slot_wid,&ent_factor);
- X
- X /* set up the active directory linked list */
- X
- X dir_ent_head.next = &dir_ent_tail;
- X dir_ent_head.prev = &dir_ent_tail;
- X dir_ent_tail.next = &dir_ent_head;
- X dir_ent_tail.prev = &dir_ent_head;
- X
- X /* go for it -- process the directories and any thing else that the
- X * user might desire
- X */
- X
- X do
- X {
- X retval = proc_dir();
- X }
- X while(retval == RECALL_PROC);
- X
- X clean_up(); /* reset things */
- X
- X} /*** main ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: proc_dir
- X
- X Purpose: Process the current directory. This includes allocating memory
- X for storing the information about the files and handling all
- X of the user responses. This routine is recursive and is called
- X each time the user "selects" a new directory; the current dir-
- X ectory is switched and this routine is called again. When the
- X user exits a directory, this routine frees up the memory that
- X was allocated for the directory and returns. The cursor is
- X left pointing to the directory that was just exited.
- X
- X This is a *RECURSIVE* function.
- X
- X Global variables:
- X
- X Name Examine/Modify/Use/Read/Write
- X ---- -----------------------------
- X args X X
- X user_dir X
- X ent_factor X
- X def_slot_wid X X
- X main_rows X
- X main_win X
- X home_dir X
- X home_len X
- X node_row_max X
- X dir_ent_head X
- X dir_ent_tail X
- X
- X Return Codes:
- X
- X Code Reason
- X ---- ------
- X 0 return normally
- X RECALL_PROC return and force this procedure to be recalled
- X immediately
- X EMPTY_DIR the directory entry selected to get us here is
- X empty
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- static int proc_dir()
- X
- X{ /*** proc_dir ***/
- X /********* LOCAL VARIABLES ********/
- register int term_code; /* code for keystroke */
- X DIR_PTR *dir_ent_ptr; /* pointer to directory info node */
- X ENT_DEF *dirptr, /* pointer to directory information */
- X *entptr, /* pointer to directory entry */
- X *prev_ptr; /* ptr to file from previous command */
- X POOL_DEF *first_pool, /* pointer to first memory pool */
- X *curr_pool; /* pointer to current memory pool */
- X char *dir_text= NULL, /* pointer to directory text descrip */
- X *dir_name; /* current directory name */
- X long num_block = 0L; /* number of blocks in directory */
- X u_int dirsize; /* size of directory info memory */
- X size_t pool_length; /* length for allocating new pools */
- X time_t stat_time; /* last mod time for directory */
- X int scr_col, /* current screen column */
- X scr_row; /* current screen row */
- X u_short prev_command; /* last command -- used for repeating */
- X short num_col, /* number of columns for full screen */
- X node_col, /* current node array column */
- X node_row, /* current node array row */
- X slot_width, /* slot width for current directory */
- X num_row, /* number of rows for full screen */
- X num_file = 0, /* number of files in directory */
- X curr_screen = 1, /* current screen of directory */
- X num_screen = 0, /* number of screens in directory */
- X scr_file, /* number of files for current screen */
- X num_slot, /* number of slots per screen */
- X branched = FALSE, /* TRUE if we Branched to a directory */
- X filemarks_flag = 0, /* TRUE if marks processed in dir */
- X sort_flag = 0, /* TRUE if entries have been sorted */
- X text_flag = 0; /* text descrip file processed flag */
- X /** above vars MUST remain automatic **/
- static COM_DEF *comm_ptr; /* for saving pointer to commands */
- static char *tptr; /* temporary character pointer */
- static int curr_type, /* type of current file */
- X status; /* return code status */
- static short temp, /* temporary value */
- X temp2, /* temporary value #2 */
- X save_width, /* temporary slot width holder */
- X change_dir, /* set if we're changing directories */
- X new_screen, /* new screen when locating files */
- X level; /* what recursion level we are at */
- static DIR_SUMM dirmem[MAX_DIR]; /* summary info for all directories */
- static struct stat statbuf; /* for getting access time for dir */
- static u_char mess_flag, /* set if information mess on screen */
- X cursor_flag, /* set if cursor needs to be set */
- X exec_flag, /* set if we just executed commands */
- X pass; /* for one-time execution of stuff */
- static char slot_buf[BUFSIZ]; /* for formatting screen slots */
- X
- X
- X cursor_flag = 0;
- X prev_ptr = NULL; /* no previous command yet */
- X slot_width = def_slot_wid; /* initialize the slot width */
- X num_row = node_row_max; /* set number of rows for now */
- X
- X /* this is kind of weird; we need to get the directory name soon after
- X * entering proc_dir() and BEFORE calling get_num_file() in case we hit
- X * hit an empty directory; the reason is that we might be coming backing
- X * in to a directory that was previously non-empty and thus would need to
- X * find the node in the active directory list for this directory and delete
- X * it; and since we search the list by directory, we need the directory
- X * name; grrr......
- X */
- X
- X dir_name = (char *) malloc(MAXPATHLEN+3);
- X
- X#if defined(SYSV) && !defined(sun)
- X getcwd(dir_name,MAXPATHLEN+2);
- X#else
- X getwd(dir_name);
- X#endif
- X
- X /* find the active node for this directory, if it exists */
- X
- X dir_ent_ptr = find_dir(&dir_ent_head,&dir_ent_tail,dir_name);
- X
- X num_file = get_num_file(&args); /* get number of files in directory */
- X
- X if(num_file == 0 || stat(".",&statbuf) != 0)
- X {
- X /* have we been here before? if so, we need to free up the memory
- X * pools
- X */
- X
- X if(dir_ent_ptr != NULL)
- X {
- X free_pool(dir_ent_ptr->first_pool);
- X dir_ent_ptr->num_file = 0; /* gone but not forgotten */
- X unlink_dir_ent(dir_ent_ptr);
- X }
- X
- X return(EMPTY_DIR);
- X }
- X
- X stat_time = statbuf.st_ctime; /* save time directory last changed */
- X sort_flag = args.sort;
- X
- X if(dir_ent_ptr != NULL)
- X {
- X /* this directory is currently active */
- X
- X free(dir_name); /* don't need this anymore */
- X dirptr = dir_ent_ptr->dirptr;
- X dir_name = dir_ent_ptr->dir_name;
- X first_pool = dir_ent_ptr->first_pool;
- X curr_pool = dir_ent_ptr->curr_pool;
- X pool_length = dir_ent_ptr->pool_length;
- X num_file = dir_ent_ptr->num_file;
- X dir_ent_ptr->count += 1; /* update the active count */
- X }
- X else
- X {
- X /* this directory currently has no activity; this *doesn't* mean that
- X * it hasn't seen before; it just means that the user hasn't visited
- X * it, Branched out, and returned to it
- X */
- X
- X /* get some memory to hold info about individual files */
- X
- X get_dir_mem(&dirptr,&dirsize,num_file);
- X
- X /* initialize the memory pools for holding the full filenames of the
- X * files in the directory
- X */
- X
- X pool_length = (num_file + 1) * ent_factor;
- X init_pool(&first_pool,pool_length);
- X curr_pool = first_pool; /* set current pool pointer */
- X
- X /* get all of the information about the files in the directory */
- X
- X get_dir(dirptr,&args,&num_block,&curr_pool,&num_file,pool_length);
- X
- X /* were there any files to get? there might not be, depending on the
- X * volatility of the directory and file protections
- X */
- X
- X if(!num_file)
- X {
- X free_pool(first_pool); /* free up the memory pools first */
- X
- X /* now free up the memory for the directory information */
- X
- X free((char *) dirptr);
- X return(EMPTY_DIR);
- X }
- X
- X get_text(&args,dirptr,&curr_pool,&dir_text,&mess_flag,&slot_width,
- X &text_flag,pool_length,num_file);
- X
- X /* make a directory node entry and add it to the list */
- X
- X dir_ent_ptr = link_dir_ent(&dir_ent_head,&dir_ent_tail,dirptr,dir_name,
- X first_pool,curr_pool,pool_length,stat_time,
- X num_file);
- X }
- X
- X global_row = &scr_row; /* mostly for handling signals */
- X global_col = &scr_col;
- X
- X dirmem[level].ptr = dirptr; /* save a pointer to this memory */
- X dirmem[level].num_file = num_file;
- X
- X /* count this recursion level; when it equals one, it means that we are in
- X * the top-level directory for this session
- X */
- X
- X level++;
- X
- X /* all of the information about the files in the directory has been
- X * obtained; now initialize the screen parameters, including the screen
- X * nodes and the number of screens for the directory
- X */
- X
- X set_screen(&num_screen,&scr_file,num_file,slot_width,node_row_max,&num_col);
- X
- X num_slot = scr_file; /* save number of slots per screen */
- X
- X /* initialize the screen slot node pointers for the screen */
- X
- X set_nodes(nodes,node_row_max,&scr_file,num_screen,curr_screen,num_file,
- X slot_width,num_col);
- X
- X /* write the directory statistics line at the bottom of the display
- X * and the directory spec/page number line at the top of the display
- X */
- X
- X put_spec(spec_win,dir_name,home_dir,home_len,num_screen);
- X put_stat(stat_win,num_block,num_file);
- X
- X if(args.text) /* write text descrip for directory? */
- X put_text(spec_win,dir_text);
- X
- X /* clear the main virtual display; we do this every time we enter a
- X * directory to make things simple; some directories might have text
- X * descriptors and some might not; this way, we make sure that we have
- X * a clean display to work with, no matter what
- X */
- X
- X werase(main_win);
- X
- X /* put the information about the files for the first screen on the screen */
- X
- X make_screen(main_win,nodes,dirptr,&args,curr_screen,node_row_max,
- X node_col_max,scr_file,num_slot,slot_width,text_flag);
- X
- X /* position the cursor to the first file in the directory */
- X
- X node_row = 0; /* start in top left of nodes array */
- X node_col = 0;
- X scr_row = (int) nodes[0][0].row; /* start in top left of screen, too */
- X scr_col = (int) nodes[0][0].column;
- X
- X /* write the options line only once */
- X
- X if(!pass)
- X {
- X put_options(stat_win);
- X pass++;
- X }
- X
- X /* set the cursor position to the first file */
- X
- X wmove(main_win,scr_row,scr_col);
- X wrefresh(main_win);
- X
- X /* this is the main processing loop for the whole program; each keystroke
- X * is read and appropriate action is taken for each; this is an infinite
- X * loop and the only way out is to break out from the middle and return
- X * to a previous invocation of this function
- X */
- X
- X for(;;) /* loop forever......... */
- X {
- X /* get a keystroke from the keyboard (store in term_code) */
- X
- X term_code = wgetch(main_win);
- X
- X if(mess_flag) /* was a message on the screen? */
- X {
- X clear_mess(main_win); /* clear the message */
- X mess_flag = 0; /* clear the message flag */
- X
- X /* reset the cursor to where it should be */
- X
- X wmove(main_win,scr_row,scr_col);
- X }
- X
- X /* now look at the key that was pressed and take appropriate action */
- X
- X switch(term_code)
- X {
- X case(CONTROL_I): /**************************************/
- X case(' '): /* right-arrow */
- X case('>'): /**************************************/
- X case('L'):
- X case('l'):
- X case(KEY_RIGHT):
- X
- X /* update the pointer to the screen and then update the position
- X * of the physical cursor; we must use temp to get the up_row
- X * position and then assign it to node_row because we can't have
- X * node_row changing before we use it to get node_col
- X */
- X
- X temp = (short) nodes[node_row][node_col].right_row;
- X node_col = (short) nodes[node_row][node_col].right_col;
- X node_row = temp;
- X scr_row = (int) nodes[node_row][node_col].row;
- X scr_col = (int) nodes[node_row][node_col].column;
- X
- X cursor_flag++; /* reset the cursor down below */
- X break;
- X
- X case(BACKSPACE): /**************************************/
- X case('<'): /* left-arrow */
- X case('H'): /**************************************/
- X case(KEY_BACKSPACE):
- X case('h'):
- X case(KEY_LEFT):
- X
- X /* update the pointer to the screen and then update the position
- X * of the physical cursor; we must use temp to get the up_row
- X * position and then assign it to node_row because we can't have
- X * node_row changing before we use it to get node_col
- X */
- X
- X temp = (short) nodes[node_row][node_col].left_row;
- X node_col = (short) nodes[node_row][node_col].left_col;
- X node_row = temp;
- X scr_row = (int) nodes[node_row][node_col].row;
- X scr_col = (int) nodes[node_row][node_col].column;
- X
- X cursor_flag++; /* reset the cursor down below */
- X break;
- X
- X case(LINEFEED): /**************************************/
- X case('J'): /* down-arrow */
- X case('j'): /**************************************/
- X case(KEY_DOWN):
- X
- X /* update the pointer to the screen and then update the position
- X * of the physical cursor; we must use temp to get the up_row
- X * position and then assign it to node_row because we can't have
- X * node_row changing before we use it to get node_col
- X */
- X
- X temp = (short) nodes[node_row][node_col].down_row;
- X node_col = (short) nodes[node_row][node_col].down_col;
- X node_row = temp;
- X scr_row = (int) nodes[node_row][node_col].row;
- X scr_col = (int) nodes[node_row][node_col].column;
- X
- X cursor_flag++; /* reset the cursor down below */
- X break;
- X
- X case('^'): /**************************************/
- X case('K'): /* up-arrow */
- X case('k'): /**************************************/
- X case(KEY_UP):
- X
- X /* update the pointer to the screen and then update the position
- X * of the physical cursor; we must use temp to get the up_row
- X * position and then assign it to node_row because we can't have
- X * node_row changing before we use it to get node_col
- X */
- X
- X temp = (short) nodes[node_row][node_col].up_row;
- X node_col = (short) nodes[node_row][node_col].up_col;
- X node_row = temp;
- X scr_row = (int) nodes[node_row][node_col].row;
- X scr_col = (int) nodes[node_row][node_col].column;
- X
- X cursor_flag++; /* reset the cursor down below */
- X break;
- X
- X case(CARRIAGE_RETURN): /**************************************/
- X /* carriage return */
- X /**************************************/
- X
- X /* go to left of screen and down one row on the screen */
- X
- X node_row = nodes[node_row][0].down_row;
- X node_col = 0;
- X scr_row = (int) nodes[node_row][node_col].row;
- X scr_col = (int) nodes[node_row][node_col].column;
- X
- X cursor_flag++; /* reset the cursor down below */
- X break;
- X
- X case('='): /**************************************/
- X case('+'): /* plus-screen */
- X case(CONTROL_F): /**************************************/
- X case(KEY_NPAGE):
- X
- X if(num_screen > 1) /* more than one screen? */
- X {
- X curr_screen++; /* go to next screen */
- X if(curr_screen > num_screen)
- X curr_screen = 1; /* oops, I meant the first screen */
- X
- X if((curr_screen == 1) || (curr_screen == num_screen))
- X {
- X set_nodes(nodes,node_row_max,&scr_file,num_screen,
- X curr_screen,num_file,slot_width,num_col);
- X }
- X
- X /* update the page number in the corner */
- X
- X put_pagnum(spec_win,curr_screen,num_screen);
- X
- X /* write the files to the screen */
- X
- X make_screen(main_win,nodes,dirptr,&args,curr_screen,
- X node_row_max,node_col_max,scr_file,num_slot,
- X slot_width,text_flag);
- X
- X /* reset screen and node pointers */
- X
- X node_row = 0;
- X node_col = 0;
- X scr_row = (int) nodes[0][0].row;
- X scr_col = (int) nodes[0][0].column;
- X
- X /* home the cursor */
- X
- X cursor_flag++; /* reset the cursor down below */
- X }
- X
- X break;
- X
- X case('-'): /**************************************/
- X case('_'): /* minus-screen */
- X case(CONTROL_B): /**************************************/
- X case(KEY_PPAGE):
- X
- X /* reset the screen nodes if we have to */
- X
- X if(num_screen > 1)
- X {
- X curr_screen--; /* go to previous screen */
- X if(curr_screen == 0) /* were we on the first screen? */
- X curr_screen = num_screen; /* oops, go to last screen */
- X
- X if(curr_screen >= (num_screen-1))
- X {
- X set_nodes(nodes,node_row_max,&scr_file,num_screen,
- X curr_screen,num_file,slot_width,num_col);
- X }
- X
- X /* update the page number in the corner */
- X
- X put_pagnum(spec_win,curr_screen,num_screen);
- X
- X /* write the files to the screen */
- X
- X make_screen(main_win,nodes,dirptr,&args,curr_screen,
- X node_row_max,node_col_max,scr_file,num_slot,
- X slot_width,text_flag);
- X
- X /* reset screen and node pointers */
- X
- X node_row = 0;
- X node_col = 0;
- X scr_row = (int) nodes[0][0].row;
- X scr_col = (int) nodes[0][0].column;
- X
- X /* home the cursor */
- X
- X cursor_flag++; /* reset the cursor down below */
- X }
- X
- X break;
- X
- X case('/'): /**************************************/
- X /* Locate-file */
- X /**************************************/
- X
- X /* user wants to search for a filename; go for it */
- X
- X temp = (short) file_locate(main_win,dirptr,num_file);
- X
- X if(temp >= 0)
- X {
- X /* file was found; recompute the node indexes so that we
- X * can change the cursor on the screen
- X */
- X
- X new_screen = (temp / num_slot) + 1;
- X
- X /* get us to the current screen */
- X
- X temp2 = temp - ((new_screen - 1) * num_slot);
- X node_col = temp2 / num_row;
- X node_row = temp % num_row;
- X
- X /* do we need to go to a new screen? if so, make the new
- X * one now
- X */
- X
- X if(new_screen != curr_screen)
- X {
- X /* create the new screen by first putting the new page
- X * number in the upper-right and then rebuilding the
- X * main display
- X */
- X
- X /* do we need to update the screen node pointers? */
- X
- X if((new_screen == num_screen) ||
- X (curr_screen == num_screen))
- X {
- X /* set the nodes */
- X
- X set_nodes(nodes,node_row_max,&scr_file,num_screen,
- X new_screen,num_file,slot_width,num_col);
- X }
- X
- X curr_screen = new_screen;
- X
- X /* put the new page number on the screen */
- X
- X put_pagnum(spec_win,curr_screen,num_screen);
- X
- X /* build the display for the new screen */
- X
- X make_screen(main_win,nodes,dirptr,&args,curr_screen,
- X node_row_max,node_col_max,scr_file,num_slot,
- X slot_width,text_flag);
- X }
- X
- X /* make the cursor point to the file that was found */
- X
- X scr_row = (int) nodes[node_row][node_col].row;
- X scr_col = (int) nodes[node_row][node_col].column;
- X }
- X else if(temp == -1)
- X {
- X /* no file found; just put up a message and that's it */
- X
- X beep();
- X info_mess("File not found");
- X mess_flag++;
- X }
- X
- X /* set the cursor where it is supposed to be, whether on the
- X * file that was found or the file that it was on when the
- X * failed search request was initiated
- X */
- X
- X cursor_flag++; /* reset the cursor down below */
- X break;
- X
- X case('U'): /**************************************/
- X case('u'): /* Unmark */
- X /**************************************/
- X
- X /* first get the entry pointer for the file selected */
- X
- X entptr = dirptr + ((curr_screen - 1) * (num_row * num_col)) +
- X (node_col * num_row) + node_row;
- X
- X /* now cancel all commands for the file entry and free up the
- X * command structure that was allocated for it
- X */
- X
- X mark_cancel(entptr);
- X
- X /* remake the slot so it can be written */
- X
- X temp = make_slot(slot_buf,entptr,&args,slot_width,text_flag);
- X
- X /* now write the file information to the screen in the
- X * right spot
- X */
- X
- X put_slot(main_win,scr_row,scr_col+1,slot_buf,A_NORMAL);
- X
- X if(args.auto_feed == TRUE)
- X {
- X /* move to the next logical file on the screen; basically, we are
- X * just performing the same stuff we do for a down-arrow
- X */
- X
- X temp = (short) nodes[node_row][node_col].down_row;
- X node_col = (short) nodes[node_row][node_col].down_col;
- X node_row = temp;
- X scr_row = (int) nodes[node_row][node_col].row;
- X scr_col = (int) nodes[node_row][node_col].column;
- X }
- X
- X cursor_flag++;
- X break;
- X
- X case('S'): /**************************************/
- X case('s'): /* Select */
- X /**************************************/
- X case('B'): /* Branch */
- X case('b'): /**************************************/
- X
- X change_dir = FALSE; /* just to be safe */
- X
- X entptr = dirptr + ((curr_screen - 1) * (num_row * num_col)) +
- X (node_col * num_row) + node_row;
- X
- X /* if the current file is a symbolic link, try to find out what
- X * it is pointing to in case we need it later
- X */
- X
- X if(entptr->type == LINK)
- X curr_type = follow_link(entptr->filename);
- X else
- X curr_type = entptr->type; /* just use what we already have */
- X
- X if(term_code == 'S' || term_code == 's')
- X {
- X /* now see what was Selected */
- X
- X if(entptr->type == REGULAR || curr_type == REGULAR)
- X {
- X /* Selecting a file; just call the PAGER */
- X
- X if(access(entptr->filename,R_OK) != 0)
- X status = CANT_OPEN;
- X else if(entptr->size != 0)
- X {
- X /* the file is not empty; go ahead and try to look at it */
- X
- X status = file_select(entptr->filename);
- X touchwin(main_win);
- X touchwin(spec_win);
- X touchwin(stat_win);
- X wrefresh(main_win);
- X wrefresh(spec_win);
- X wrefresh(stat_win);
- X }
- X else
- X status = EMPTY_FILE; /* file is empty */
- X
- X switch(status) /* what happened with the file? */
- X {
- X case(FAILURE):
- X
- X beep();
- X info_mess("Cannot display selected file");
- X mess_flag++;
- X break;
- X
- X case(EMPTY_FILE):
- X
- X beep();
- X info_mess("Selected file is empty");
- X mess_flag++;
- X break;
- X
- X case(CANT_OPEN):
- X
- X beep();
- X info_mess("Cannot open file");
- X mess_flag++;
- X break;
- X
- X default:
- X break;
- X }
- X }
- X else if(entptr->type == DIRECTORY || curr_type == DIRECTORY)
- X {
- X /* Selected a directory; first see if we can even change
- X * to it
- X */
- X
- X if(chdir(entptr->filename) != 0)
- X {
- X beep();
- X info_mess("Cannot change to selected directory");
- X mess_flag++;
- X cursor_flag++;
- X }
- X else
- X {
- X if(term_code == 'b') /* ask for confirmation first */
- X {
- X info_mess("There are commands in this directory. Execute them before branching? [y] ");
- X
- X term_code = wgetch(main_win);
- X
- X if(term_code == 'N' || term_code == 'n')
- X break;
- X }
- X
- X change_dir = TRUE;
- X }
- X }
- X }
- X else
- X {
- X /* must be a Branch command */
- X
- X prompt_getstr(main_win,"Directory: ",slot_buf,main_rows,
- X sizeof(slot_buf));
- X
- X if(slot_buf[0] == '\0')
- X {
- X /* user just hit a return */
- X
- X cursor_flag++;
- X }
- X else if(chdir(slot_buf) != 0)
- X {
- X beep();
- X info_mess("Cannot change to specified directory");
- X mess_flag++;
- X cursor_flag++;
- X }
- X else
- X {
- X /* it worked; save the directory name and set the
- X * flag that says we are Jumping
- X */
- X
- X branched = TRUE;
- X change_dir = TRUE;
- X }
- X }
- X
- X if(change_dir == TRUE)
- X {
- X /* now call ourselves and start over with the new directory */
- X
- X /***********************************
- X * R E C U R S I V E C A L L *
- X ***********************************/
- X
- X do
- X {
- X temp = proc_dir();
- X }
- X while(temp == RECALL_PROC);
- X
- X baseptr = dirptr; /* point to current directory */
- X
- X /* change back to the directory that we should be in */
- X
- X if(chdir(dir_name) != 0)
- X {
- X /* problems changing to directory; scream at the user
- X * and get out of here
- X */
- X
- X beep();
- X info_mess("Cannot reset directory....exiting...");
- X sleep(2);
- X exit(0);
- X }
- X
- X /* see if the current directory has changed; if it has, we
- X * need to rebuild it
- X */
- X
- X if(stat(".",&statbuf) != 0)
- X exit();
- X
- X if(stat_time < statbuf.st_ctime)
- X {
- X /* see if there are any commands to execute */
- X
- X if(check_marks(dirptr,num_file) == TRUE)
- X {
- X info_mess("Directory has been updated. Execute marks before rebuilding? [Y] ");
- X term_code = wgetch(main_win);
- X clear_mess(main_win);
- X
- X if(term_code != 'N' && term_code != 'n')
- X xecute(dirptr,dir_text,num_file);
- X else
- X {
- X /* free up the memory for any command structures that
- X * might have been allocated
- X */
- X
- X free_comm(dirptr,num_file);
- X }
- X }
- X
- X info_mess("Rebuilding directory.....");
- X level--; /* decrement recursion level counter */
- X
- X /* free up the memory pools first */
- X
- X free_pool(first_pool);
- X unlink_dir_ent(dir_ent_ptr);
- X
- X /* now free up the memory for the directory information */
- X
- X free((char *) dirptr);
- X
- X werase(main_win); /* erase display to be sure... */
- X return(RECALL_PROC); /* go back to where we were called */
- X }
- X
- X if(temp == EMPTY_DIR) /* did the user make a good choice? */
- X {
- X /* the directory that was selected was empty */
- X
- X beep();
- X info_mess("Directory is empty...........");
- X
- X if(exec_flag)
- X {
- X sleep(2); /* only pause if we just executed */
- X clear_mess(main_win);
- X }
- X else
- X mess_flag++; /* clear it on next keystroke */
- X }
- X
- X /* reset some things on the screen since we are actually
- X * returning from a directory
- X */
- X
- X if((args.text) && (!text_flag) && temp != EMPTY_DIR)
- X {
- X /* when we left this directory to go down, the
- X * text descriptors were not included (at least not
- X * not on the screen, anyway); when we were in
- X * one of the descendant directories, the text
- X * descriptors were selected; we must read them
- X * in here; first, update the slot width on the
- X * assumption that we can get the text descriptors
- X * for the current directory without any trouble and
- X * set the flag that signifies that we have text
- X * descriptors read in for the current directory
- X */
- X
- X if(args.text == DISPLAY_TEXT) /* room to display descrips? */
- X slot_width += TEXT_MAX + 1; /* yes, assume we get them */
- X
- X text_flag = args.text;
- X
- X /* erase the display to make sure we don't have any
- X * garbage left over if we need to reformat the screen
- X */
- X
- X werase(main_win);
- X
- X temp = read_text_des(dirptr,&curr_pool,&dir_text,
- X pool_length,num_file);
- X
- X if(temp == BAD_FILE)
- X {
- X beep();
- X info_mess("Invalid format for text descriptor file");
- X mess_flag++;
- X text_flag = 0;
- X
- X if(args.text == DISPLAY_TEXT)
- X slot_width = slot_width - (TEXT_MAX + 1);
- X
- X sleep(1);
- X }
- X else if(temp == CANT_OPEN)
- X {
- X beep();
- X info_mess("Cannot open text descriptor file");
- X mess_flag++;
- X text_flag = 0;
- X
- X if(args.text == DISPLAY_TEXT)
- X slot_width = slot_width - (TEXT_MAX + 1);
- X
- X sleep(1);
- X }
- X else if(temp == NO_FILE)
- X {
- X text_flag = 0;
- X
- X if(args.text == DISPLAY_TEXT)
- X slot_width = slot_width - (TEXT_MAX + 1);
- X }
- X else if(temp == 0)
- X {
- X /* reset the screen parameters, just in case they need
- X * to be changed to reflect text descriptors
- X */
- X
- X set_screen(&num_screen,&scr_file,num_file,slot_width,
- X node_row_max,&num_col);
- X num_slot = scr_file;
- X }
- X }
- X
- X if(args.filemarks && !filemarks_flag)
- X {
- X /* the user has filemarks selected from a descendent
- X * directory but we don't have them included in the
- X * current directory; add them here
- X */
- X
- X get_filemarks(dirptr,num_file);
- X filemarks_flag = 1;
- X }
- X
- X if(args.sort && !sort_flag)
- X {
- X /* the user turned on sorting in a descendent directory
- X * but the directory isn't sorted; go ahead and sort now
- X */
- X
- X sort_files(num_file - 1,args.sort);
- X sort_flag = 1;
- X }
- X/*
- X if((temp == EMPTY_DIR && exec_flag) || temp != EMPTY_DIR)
- X {
- X*/
- X /* we just executed commands in a directory so we must
- X * rebuild stuff
- X */
- X
- X set_nodes(nodes,node_row_max,&scr_file,num_screen,
- X curr_screen,num_file,slot_width,num_col);
- X
- X /* rewrite all of the stuff local to this directory */
- X
- X put_spec(spec_win,dir_name,home_dir,home_len,num_screen);
- X put_stat(stat_win,num_block,num_file);
- X
- X if(args.text) /* text descriptor to write? */
- X put_text(spec_win,dir_text);
- X
- X /* this is important; we have to look for the directory
- X * that we were on when the last Select was done and de-
- X * termine what page it is on; we might have to change the
- X * current page and everything just to put the cursor back
- X * in the right spot
- X */
- X
- X screen_reset(nodes,dirptr,entptr->filename,&node_row,
- X &node_col,&scr_file,&curr_screen,node_row_max,
- X num_file,num_slot,num_screen,slot_width,
- X num_row,num_col);
- X
- X /* put the new page number on the screen */
- X
- X put_pagnum(spec_win,curr_screen,num_screen);
- X
- X /* create and write the screen again for the current
- X * directory
- X */
- X
- X make_screen(main_win,nodes,dirptr,&args,curr_screen,
- X node_row_max,node_col_max,scr_file,
- X num_slot,slot_width,text_flag);
- X
- X exec_flag = 0; /* make sure to reset this */
- X
- X /* reset the screen row and column */
- X
- X scr_row = (int) nodes[node_row][node_col].row;
- X scr_col = (int) nodes[node_row][node_col].column;
- X/*
- X }
- X*/
- X }
- X
- X exec_flag = 0;
- X cursor_flag++; /* reset the cursor down below */
- X break;
- X
- X case('X'): /**************************************/
- X case('x'): /* eXecute */
- X /**************************************/
- X
- X if(args.confirm) /* should we ask to make sure? */
- X {
- X /* the user wants to be asked if they REALLY want to execute
- X * the commands for the directory
- X */
- X
- X info_mess("REALLY eXecute commands? [N] ");
- X term_code = wgetch(main_win);
- X
- X /* now look at what the keystroke is; if it is not Y or y,
- X * then we DO NOT execute the commands for the directory
- X */
- X
- X if((term_code != 'Y') && (term_code != 'y'))
- X {
- X /* clear out the prompt message first and then set the
- X * flag to reset the cursor
- X */
- X
- X clear_mess(main_win);
- X cursor_flag++; /* reset the cursor */
- X break; /* nope, don't do anything yet..... */
- X }
- X }
- X
- X /* execute the file commands for all of the files in the current
- X * directory; informational messages will appear for each action
- X * for each file
- X */
- X
- X xecute(dirptr,dir_text,num_file);
- X exec_flag++; /* set flag saying we just executed */
- X
- X /* just fall through here and do what we would normally do for
- X * a REBUILD command; no sense in putting the code in two places,
- X * now is there?
- X */
- X
- X case(CONTROL_R): /**************************************/
- X /* rebuild the directory */
- X /**************************************/
- X
- X /* if we are really just rebuilding, free up any command
- X * structures for the directory
- X */
- X
- X if(!exec_flag)
- X free_comm(dirptr,num_file);
- X
- X /* tell the user we are doing something so they don't worry */
- X
- X xmess("Rebuilding directory information......",0);
- X
- X /* decrement the recursion level before returning */
- X
- X --level;
- X
- X /* free the memory pools first */
- X
- X free_pool(first_pool);
- X unlink_dir_ent(dir_ent_ptr);
- X
- X /* now free up the memory for the directory information */
- X
- X free((char *) dirptr);
- X
- X return(RECALL_PROC); /* force proc_dir() to be recalled */
- X
- X case('?'): /**************************************/
- X /* Help */
- X /**************************************/
- X
- X give_help(main_win);
- X mess_flag++;
- X cursor_flag++;
- X break;
- X
- X case('D'): /**************************************/
- X case('d'): /* Delete */
- X /**************************************/
- X
- X /* first get the entry pointer for the file indicated */
- X
- X entptr = dirptr + ((curr_screen - 1) * (num_row * num_col)) +
- X (node_col * num_row) + node_row;
- X
- X mark_delete(entptr); /* mark file for deletion */
- X
- X temp = make_slot(slot_buf,entptr,&args,slot_width,text_flag);
- X
- X /* now write the file information to the screen in the right spot */
- X
- X put_slot(main_win,scr_row,scr_col+1,slot_buf,A_BOLD);
- X
- X if(args.auto_feed == TRUE)
- X {
- X /* move to the next logical file on the screen; basically, we are
- X * just performing the same stuff we do for a down-arrow
- X */
- X
- X temp = (short) nodes[node_row][node_col].down_row;
- X node_col = (short) nodes[node_row][node_col].down_col;
- X node_row = temp;
- X scr_row = (int) nodes[node_row][node_col].row;
- X scr_col = (int) nodes[node_row][node_col].column;
- X }
- X
- X cursor_flag++;
- X prev_ptr = entptr; /* save in case user wants to repeat */
- X prev_command = DELETE;
- X break;
- X
- X case('P'): /**************************************/
- X case('p'): /* Protect */
- X /**************************************/
- X
- X /* first get the entry pointer for the file indicated */
- X
- X entptr = dirptr + ((curr_screen - 1) * (num_row * num_col)) +
- X (node_col * num_row) + node_row;
- X
- X tag_file(main_win,scr_row,scr_col);
- X
- X /* get the new filename and mark the file to be renamed */
- X
- X temp = mark_protect(main_win,entptr,0,FALSE);
- X
- X if(temp != SUCCESS) /* wot happen? */
- X {
- X beep();
- X info_mess("Invalid protection string");
- X mess_flag++;
- X }
- X else
- X {
- X /* highlite the file slot */
- X
- X highlite(main_win,slot_buf,entptr,&args,scr_row,scr_col+1,
- X slot_width,text_flag);
- X prev_ptr = entptr; /* save in case user wants to repeat */
- X prev_command = PROTECT;
- X }
- X
- X erase_tag(main_win,scr_row,scr_col);
- X cursor_flag++; /* reset the cursor down below */
- X break;
- X
- X case('F'): /**************************************/
- X case('f'): /* Finish */
- X /**************************************/
- X
- X
- X if(level == 1) /* are we at the top? */
- X {
- X /* beep and continue, ignoring the Finish command */
- X
- X beep();
- X break; /* yes, we can't go up any more */
- X }
- X
- X /* check for marked files first; if some are marked, ask the user
- X * if Finishing is the right thing to do
- X */
- X
- X if(check_marks(dirptr,num_file) == TRUE && term_code == 'f')
- X {
- X info_mess("There are commands in this directory. Execute them before finishing? [y] ");
- X
- X term_code = wgetch(main_win);
- X clear_mess(main_win);
- X cursor_flag++;
- X
- X if(term_code != 'N' && term_code != 'n')
- X xecute(dirptr,dir_text,num_file);
- X else
- X free_comm(dirptr,num_file);
- X }
- X
- X /* the user is finished with the current directory; free up the
- X * memory that was allocated for the directory and just return;
- X * whether we return to the mainline or to a previous call to
- X * proc_dir() is no matter to us at this point
- X */
- X
- X level--; /* decrement recursion level counter */
- X
- X /* free up the memory pools first */
- X
- X free_pool(first_pool);
- X
- X /* now free up the memory for the directory information */
- X
- X free((char *) dirptr);
- X
- X /* unlink the active directory node from the list */
- X
- X unlink_dir_ent(dir_ent_ptr);
- X
- X return(0); /* go back to where we were called */
- X
- X case('E'): /**************************************/
- X case('e'): /* Edit */
- X /**************************************/
- X
- X entptr = dirptr + ((curr_screen - 1) * (num_row * num_col)) +
- X (node_col * num_row) + node_row;
- X
- X if(entptr->type != DIRECTORY)
- X {
- X /* Editing a file; fine... */
- X
- X if(access(entptr->filename,R_OK) != 0)
- X {
- X beep();
- X info_mess("Cannot open file");
- X mess_flag++;
- X }
- X else
- X {
- X /* the file is not empty; go ahead and try to edit it */
- X
- X /* subtract the number of blocks for the file from the total
- X * for the directory because the size of the file might be
- X * different
- X */
- X
- X num_block -= get_bnum(entptr->filename);
- X
- X status = edit(entptr->filename);
- X touchwin(main_win);
- X touchwin(spec_win);
- X touchwin(stat_win);
- X wrefresh(main_win);
- X wrefresh(spec_win);
- X wrefresh(stat_win);
- X }
- X
- X if(status == FAILURE)
- X {
- X beep();
- X info_mess("Cannot edit selected file");
- X mess_flag++;
- X }
- X
- X /* rebuild the file entry for the file to reflect the new info;
- X * save the command pointer and re-attach it to the entry because
- X * make_ent() will wipe it out
- X */
- X
- X comm_ptr = entptr->command;
- X make_ent(entptr,entptr->filename,&num_block);
- X entptr->command = comm_ptr;
- X status = make_slot(slot_buf,entptr,&args,slot_width,text_flag);
- X put_slot(main_win,scr_row,scr_col+1,slot_buf,status);
- X
- X /* update the stat line */
- X
- X put_stat(stat_win,num_block,num_file);
- X cursor_flag++;
- X }
- X else
- X {
- X beep();
- X info_mess("Cannot edit a directory");
- X mess_flag++;
- X cursor_flag++;
- X }
- X
- X break;
- X
- X case('I'): /**************************************/
- X case('i'): /* Info */
- X /**************************************/
- X
- X /* first get the entry pointer for the file indicated */
- X
- X entptr = dirptr + ((curr_screen - 1) * (num_row * num_col)) +
- X (node_col * num_row) + node_row;
- X
- X /* display all of the information about the file on the screen */
- X
- X if(info(entptr,&args) != SUCCESS)
- X {
- X beep();
- X info_mess("Cannot obtain information for file");
- X mess_flag++;
- X }
- X
- X touchwin(main_win); /* to force it to be refreshed */
- X wnoutrefresh(main_win);
- X touchwin(stat_win);
- X wnoutrefresh(stat_win);
- X doupdate();
- X cursor_flag++; /* reset the cursor */
- X
- X break;
- X
- X case('R'): /**************************************/
- X case('r'): /* Rename */
- X /**************************************/
- X
- X /* first get the entry pointer for the file indicated */
- X
- X entptr = dirptr + ((curr_screen - 1) * (num_row * num_col)) +
- X (node_col * num_row) + node_row;
- X
- X tag_file(main_win,scr_row,scr_col);
- X
- X /* get the new filename and mark the file to be renamed */
- X
- X temp = mark_copy_ren(main_win,entptr,RENAME,NULL,FALSE);
- X
- X if(temp != SUCCESS) /* wot happen? */
- X {
- X beep();
- X info_mess("Error in trying to rename file");
- X mess_flag++;
- X }
- X else
- X {
- X /* highlite the file slot */
- X
- X highlite(main_win,slot_buf,entptr,&args,scr_row,scr_col+1,
- X slot_width,text_flag);
- X prev_ptr = entptr; /* save in case user wants to repeat */
- X prev_command = RENAME;
- X }
- X
- X erase_tag(main_win,scr_row,scr_col);
- X cursor_flag++; /* reset the cursor down below */
- X
- X break;
- X
- X case('C'): /**************************************/
- X case('c'): /* Copy */
- X /**************************************/
- X
- X /* first get the entry pointer for the file indicated */
- X
- X entptr = dirptr + ((curr_screen - 1) * (num_row * num_col)) +
- X (node_col * num_row) + node_row;
- X
- X if(entptr->type != DIRECTORY)
- X {
- X tag_file(main_win,scr_row,scr_col);
- X
- X /* get the new filename and mark the file to be copied */
- X
- X temp = mark_copy_ren(main_win,entptr,COPY,NULL,FALSE);
- X
- X if(temp != SUCCESS) /* wot happen? */
- X {
- X beep();
- X info_mess("Error in trying to copy file");
- X mess_flag++;
- X }
- X else
- X {
- X /* highlite the file slot */
- X
- X highlite(main_win,slot_buf,entptr,&args,scr_row,scr_col+1,
- X slot_width,text_flag);
- X prev_ptr = entptr; /* save in case user wants to repeat */
- X prev_command = COPY;
- X }
- X
- X erase_tag(main_win,scr_row,scr_col);
- X }
- X else
- X {
- X beep();
- X info_mess("Copy is invalid for that file");
- X mess_flag++;
- X }
- X
- X cursor_flag++;
- X wrefresh(main_win); /* make sure screen is up to date */
- X break;
- X
- X case('T'): /**************************************/
- X case('t'): /* Text */
- X /**************************************/
- X
- X /* first save what file the cursor was pointing to */
- X
- X entptr = dirptr + ((curr_screen - 1) * (num_row * num_col)) +
- X (node_col * num_row) + node_row;
- X
- X if(!text_flag)
- X {
- X /* were text descriptors already turned on? */
- X
- X if(!args.text)
- X {
- X /* now see what we need to set the text global run-time
- X * flag to (whether we should display text descriptors
- X * or not
- X */
- X
- X save_width = slot_width;
- X
- X if((slot_width + TEXT_MAX + 1) <= COLS)
- X {
- X /* Good news! The text descriptors will fit on the
- X * screen; update the current slot width but leave the
- X * global slot width alone
- X */
- X
- X slot_width = slot_width + TEXT_MAX + 1;
- X args.text = DISPLAY_TEXT;
- X }
- X else
- X {
- X /* no, the text descriptors will not fit on the screen;
- X * but we want them read in from now on anyway
- X */
- X
- X args.text = SLOT_OVF;
- X }
- X }
- X
- X /* text descriptors have NOT been read in for the current dir-
- X * ectory; first we must see if the text descriptor file exists;
- X * if it is there, we will use it; if not, we will ask if they
- X * want to create one
- X */
- X
- X text_flag = args.text;
- X
- X temp = read_text_des(dirptr,&curr_pool,&dir_text,pool_length,
- X num_file);
- X
- X if(temp == NO_FILE)
- X {
- X /* the text descriptor file does not exist; ask the user if
- X * it should be created
- X */
- X
- X temp = create_text(main_win);
- X }
- X
- X switch(temp) /* what happened with the file? */
- X {
- X case(NEW_FILE): /* new text descriptor file? */
- X
- X /* ask the user if the commands should be executed
- X * before rebuilding things
- X */
- X
- X if(check_marks(dirptr,num_file) == TRUE)
- X {
- X info_mess("Commands will be wiped out. eXecute them?\
- X [y] ");
- X
- X term_code = wgetch(main_win);
- X clear_mess(main_win);
- X
- X if(term_code != 'N' && term_code != 'n')
- X {
- X /* execute the stuff first */
- X
- X /* make sure we don't try to create a text descriptor
- X * file before eXecuting the commands
- X */
- X
- X xecute(dirptr,dir_text,num_file);
- X }
- X else
- X free_comm(dirptr,num_file);
- X }
- X
- X /* free up the memory pools first */
- X
- X free_pool(first_pool);
- X unlink_dir_ent(dir_ent_ptr);
- X
- X /* now free up the memory for the directory info */
- X
- X free((char *) dirptr);
- X
- X --level; /* don't count this level anymore */
- X
- X /* return here and force the routine to be called
- X * again; this makes the function epilogue (don't
- X * you just love those programming language terms?)
- X * do all of the work by allocating and initializing
- X * all of the automatic variables; this is a neat
- X * way to take advantage of the recursive structure
- X * we have set up for ourselves because all of the
- X * code to reinitialize a directory does not have
- X * to be duplicated
- X */
- X
- X return(RECALL_PROC);
- X
- X case(SUCCESS): /* text descriptors read in ok? */
- X
- X /* the text descriptors were read in ok; now rebuild the
- X * nodes for the directory and remake the screen
- X */
- X
- X text_flag = args.text;
- X set_screen(&num_screen,&scr_file,num_file,slot_width,
- X node_row_max,&num_col);
- X num_slot = scr_file;
- X set_nodes(nodes,node_row_max,&scr_file,num_screen,
- X curr_screen,num_file,slot_width,num_col);
- X put_spec(spec_win,dir_name,home_dir,home_len,num_screen);
- X put_text(spec_win,dir_text);
- X
- X /* we have to look for the file that was being point to
- X * when the Text command was done and determine what page
- X * it is on; we might have to change the current page and
- X * everything just to put the cursor back in the right spot
- X */
- X
- X screen_reset(nodes,dirptr,entptr->filename,&node_row,
- X &node_col,&scr_file,&curr_screen,
- X node_row_max,num_file,num_slot,num_screen,
- X slot_width,num_row,num_col);
- X
- X /* put the page number on the screen again, just in case
- X * it might have changed
- X */
- X
- X put_pagnum(spec_win,curr_screen,num_screen);
- X
- X /* clear the screen to make sure we don't have any
- X * any garbage left over when we put the text des-
- X * criptors on the screen
- X */
- X
- X werase(main_win);
- X
- X /* remake the virtual display now that it is clear */
- X
- X make_screen(main_win,nodes,dirptr,&args,curr_screen,
- X node_row_max,node_col_max,scr_file,
- X num_slot,slot_width,text_flag);
- X
- X /* reset the screen cursor values */
- X
- X scr_row = (int) nodes[node_row][node_col].row;
- X scr_col = (int) nodes[node_row][node_col].column;
- X
- X /* make the sure pool length is set properly */
- X
- X pool_length = (num_file + 1) * ent_factor;
- X cursor_flag++; /* reset the cursor */
- X break;
- X
- X case(BAD_FILE):
- X
- X /* bad format for text descriptor file */
- X
- X info_mess("Invalid format for text descriptor file");
- X beep();
- X
- X /* reset the slot width */
- X
- X slot_width = save_width;
- X text_flag = 0;
- X mess_flag++;
- X break;
- X
- X case(CANT_OPEN):
- X
- X beep();
- X info_mess("Cannot open text descriptor file");
- X
- X /* reset the slot width */
- X
- X slot_width = save_width;
- X text_flag = 0;
- X mess_flag++;
- X break;
- X
- X case(DONT_CREATE):
- X default:
- X
- X /* reset the slot width */
- X
- X slot_width = save_width;
- X text_flag = 0;
- X break;
- X }
- X }
- X else
- X {
- X /* the text descriptors have already been read in; get the
- X * text descriptor for the selected file and store it in a
- X * memory pool
- X */
- X
- X /* first get the entry pointer for the file indicated */
- X
- X entptr = dirptr + ((curr_screen - 1) * (num_row * num_col)) +
- X (node_col * num_row) + node_row;
- X
- X tag_file(main_win,scr_row,scr_col);
- X
- X /* get the text descriptor and mark the file */
- X
- X temp = mark_text(main_win,entptr,NULL,FALSE);
- X
- X if(temp != SUCCESS) /* did everything go ok? */
- X {
- X beep();
- X info_mess("Invalid text descriptor");
- X mess_flag++;
- X }
- X else
- X {
- X /* highlite the file slot */
- X
- X highlite(main_win,slot_buf,entptr,&args,scr_row,scr_col+1,
- X slot_width,text_flag);
- X prev_ptr = entptr; /* save in case user wants to repeat */
- X prev_command = TEXT;
- X }
- X
- X erase_tag(main_win,scr_row,scr_col);
- X }
- X
- X cursor_flag++; /* reset the cursor down below */
- X break;
- X
- X case('.'): /**************************************/
- X /* Repeat */
- X /**************************************/
- X
- X entptr = dirptr + ((curr_screen - 1) * (num_row * num_col)) +
- X (node_col * num_row) + node_row;
- X
- X if(prev_ptr != NULL)
- X {
- X mark_repeat(main_win,entptr,prev_ptr,prev_command);
- X highlite(main_win,slot_buf,entptr,&args,scr_row,scr_col+1,
- X slot_width,text_flag);
- X }
- X else
- X {
- X beep();
- X info_mess("No previous command");
- X mess_flag++;
- X }
- X
- X cursor_flag++;
- X break;
- X
- X case('Q'): /**************************************/
- X case('q'): /* Quit */
- X /**************************************/
- X
- X /* check for marked files first; if some are marked, ask the user
- X * if Quitting is the right thing to do
- X */
- X
- X for(temp = 0,status = FALSE; temp < level && status == FALSE;
- X temp++)
- X status = check_marks(dirmem[temp].ptr,dirmem[temp].num_file);
- X
- X if(status == TRUE && term_code == 'q')
- X {
- X info_mess("There are commands in this directory. Execute them before quitting? [y] ");
- X
- X term_code = wgetch(main_win);
- X clear_mess(main_win);
- X cursor_flag++;
- X
- X if(term_code != 'N' && term_code != 'n')
- X xecute(dirptr,dir_text,num_file);
- X }
- X
- X clean_up();
- X exit(0); /* now we can exit */
- X
- X break;
- X
- X case('!'): /**************************************/
- X /* Shell escape */
- X /**************************************/
- X
- X /* clear out the options line so we can jump to the shell
- X * a little cleaner
- X */
- X
- X wmove(stat_win,STAT_WINDOW_ROWS - 1,0);
- X wclrtoeol(stat_win);
- X wrefresh(stat_win);
- X
- X if(spawn() == FAILURE) /* fork the shell */
- X info_mess("Cannot fork");
- X
- X /* refresh the screen */
- X
- X put_options(stat_win);
- X touchwin(main_win);
- X touchwin(spec_win);
- X wrefresh(main_win);
- X wrefresh(spec_win);
- X wrefresh(stat_win);
- X cursor_flag++;
- X break;
- X
- X case(CONTROL_W): /**************************************/
- X case(CONTROL_L): /* repaint screen */
- X /**************************************/
- X
- X touchwin(spec_win);
- X touchwin(main_win);
- X touchwin(stat_win);
- X wnoutrefresh(spec_win);
- X wnoutrefresh(main_win);
- X wnoutrefresh(stat_win);
- X doupdate();
- X cursor_flag++;
- X break;
- X
- X case(CONTROL_G): /**************************************/
- X /* Goto */
- X /**************************************/
- X
- X /* ask for a new screen number */
- X
- X temp = get_scr_num(main_win,curr_screen,num_screen);
- X
- X if(temp == BAD_SCREEN_NO) /* was it a bad screen number? */
- X {
- X beep();
- X info_mess("Invalid page number");
- X mess_flag++;
- X }
- X else
- X {
- X /* was the page number specified different from the
- X * current one? If not, don't do anything
- X */
- X
- X if(curr_screen != temp)
- X {
- X /* the page number specified was valid; set up the new page */
- X
- X curr_screen = temp; /* store the new current screen */
- X
- X /* update the screen nodes array */
- X
- X set_nodes(nodes,node_row_max,&scr_file,num_screen,
- X curr_screen,num_file,slot_width,num_col);
- X
- X /* update the page number in the corner */
- X
- X put_pagnum(spec_win,curr_screen,num_screen);
- X
- X /* remake the screen to reflect the new screen specified */
- X
- X make_screen(main_win,nodes,dirptr,&args,curr_screen,
- X node_row_max,node_col_max,scr_file,num_slot,
- X slot_width,text_flag);
- X
- X /* reset the screen and node pointers */
- X
- X node_row = 0;
- X node_col = 0;
- X scr_row = (int) nodes[0][0].row;
- X scr_col = (int) nodes[0][0].column;
- X }
- X }
- X
- X cursor_flag++; /* set the cursor */
- X break;
- X
- X case('o'): /**************************************/
- X /* Owner */
- X /**************************************/
- X
- X#if !defined(SYSV) || defined(sun)
- X if(geteuid() != 0)
- X {
- X beep();
- X info_mess("Only the superuser can use the Owner command");
- X mess_flag++;
- X cursor_flag++;
- X break;
- X }
- X#endif
- X
- X /* change the owner of a file */
- X
- X entptr = dirptr + ((curr_screen - 1) * (num_row * num_col)) +
- X (node_col * num_row) + node_row;
- X
- X tag_file(main_win,scr_row,scr_col);
- X
- X temp = mark_owner(main_win,entptr,0,FALSE);
- X
- X if(temp == SUCCESS)
- X {
- X /* highlite the file slot */
- X
- X highlite(main_win,slot_buf,entptr,&args,scr_row,scr_col+1,
- X slot_width,text_flag);
- X prev_ptr = entptr; /* save in case user wants to repeat */
- X prev_command = OWNER;
- X }
- X else if(temp == BAD_OWNER)
- X {
- X info_mess("Invalid owner specified");
- X beep();
- X mess_flag++;
- X }
- X
- X erase_tag(main_win,scr_row,scr_col);
- X cursor_flag++; /* reset the cursor down below */
- X break;
- X
- X
- X case('G'): /**************************************/
- X case('g'): /* Group */
- X /**************************************/
- X
- X /* change the group of a file */
- X
- X entptr = dirptr + ((curr_screen - 1) * (num_row * num_col)) +
- X (node_col * num_row) + node_row;
- X
- X tag_file(main_win,scr_row,scr_col);
- X
- X temp = mark_group(main_win,entptr,0,FALSE);
- X
- X if(temp == SUCCESS)
- X {
- X /* highlite the file slot */
- X
- X highlite(main_win,slot_buf,entptr,&args,scr_row,scr_col+1,
- X slot_width,text_flag);
- X prev_ptr = entptr; /* save in case user wants to repeat */
- X prev_command = GROUP;
- X }
- X else if(temp == BAD_GROUP)
- X {
- X info_mess("Invalid group specified");
- X beep();
- X mess_flag++;
- X }
- X
- X erase_tag(main_win,scr_row,scr_col);
- X cursor_flag++; /* reset the cursor down below */
- X break;
- X
- X case('O'): /**************************************/
- X /* Options */
- X /**************************************/
- X
- X /* first get the entry pointer for the current file */
- X
- X entptr = dirptr + ((curr_screen - 1) * (num_row * num_col)) +
- X (node_col * num_row) + node_row;
- X
- X temp = config_options(&args);
- X
- X /* reinitialize the global factors */
- X
- X set_args(&args,&def_slot_wid,&ent_factor);
- X
- X /* slot width has probably changed */
- X
- X slot_width = def_slot_wid;
- X
- X if(temp & REBUILD_DIRECTORY)
- X {
- X /* ask the user if the commands should be executed
- X * before rebuilding things
- X */
- X
- X if(check_marks(dirptr,num_file) == TRUE)
- X {
- X touchwin(main_win);
- X wnoutrefresh(main_win);
- X doupdate();
- X info_mess("Commands will be wiped out. eXecute them? [y] ");
- X term_code = wgetch(main_win);
- X clear_mess(main_win);
- X
- X if(term_code != 'N' && term_code != 'n')
- X {
- X /* execute the stuff first */
- X
- X xecute(dirptr,dir_text,num_file);
- X }
- X else
- X free_comm(dirptr,num_file);
- X }
- X
- X /* refresh the stat window because we overwrote it */
- X
- X touchwin(stat_win);
- X wrefresh(stat_win);
- X
- X /* free up the memory pools first */
- X
- X free_pool(first_pool);
- X unlink_dir_ent(dir_ent_ptr);
- X
- X /* now free up the memory for the directory info */
- X
- X free((char *) dirptr);
- X
- X --level; /* don't count this level anymore */
- X
- X return(RECALL_PROC); /* recall proc_dir() to rebuild */
- X }
- X
- X if(temp & REBUILD_SCREEN)
- X {
- X if(temp & REBUILD_WITH_FILEMARKS)
- X {
- X get_filemarks(dirptr,num_file);
- X filemarks_flag = args.filemarks;
- X }
- X
- X if(temp & REBUILD_WITH_SORT)
- X {
- X tptr = entptr->filename;
- X sort_files(num_file - 1,args.sort);
- X sort_flag = args.sort;
- X }
- X
- X if(text_flag && !args.text)
- X {
- X /* text descriptors were turned off; make sure that we
- X * wipe out any directory text descriptor
- X */
- X
- X put_text(spec_win,NULL);
- X text_flag = 0;
- X }
- X
- X get_text(&args,dirptr,&curr_pool,&dir_text,&mess_flag,
- X &slot_width,&text_flag,pool_length,num_file);
- X
- X /* reinitialize the screen parameters */
- X
- X set_screen(&num_screen,&scr_file,num_file,slot_width,
- X node_row_max,&num_col);
- X
- X num_slot = scr_file; /* save number of slots per screen */
- X
- X /* search for the filename of the file we were on so we can
- X * go back to it; we might as well do this every time, es-
- X * pecially since the search for it is fast (we're only
- X * comparing pointer values instead of strings
- X */
- X
- X temp = (short) file_ptr_search(dirptr,tptr,num_file);
- X
- X if(temp >= 0)
- X {
- X /* file was found; recompute the node indexes so that we
- X * can change the cursor on the screen
- X */
- X
- X new_screen = (temp / num_slot) + 1;
- X
- X /* get us to the current screen */
- X
- X temp2 = temp - ((new_screen - 1) * num_slot);
- X node_col = temp2 / num_row;
- X node_row = temp % num_row;
- X curr_screen = new_screen;
- X }
- X
- X /* create the new screen by first putting the new page
- X * number in the upper-right and then rebuilding the
- X * main display
- X */
- X
- X put_pagnum(spec_win,curr_screen,num_screen);
- X
- X set_nodes(nodes,node_row_max,&scr_file,num_screen,new_screen,
- X num_file,slot_width,num_col);
- X
- X if(args.text) /* write text descrip for directory? */
- X put_text(spec_win,dir_text);
- X
- X werase(main_win); /* make sure we start clean */
- X
- X /* display the current screen */
- X
- X make_screen(main_win,nodes,dirptr,&args,curr_screen,
- X node_row_max,node_col_max,scr_file,num_slot,
- X slot_width,text_flag);
- X
- X /* get the cursor coordinates so we can reset it */
- X
- X scr_row = (int) nodes[node_row][node_col].row;
- X scr_col = (int) nodes[node_row][node_col].column;
- X }
- X
- X put_stat(stat_win,num_block,num_file);
- X put_options(stat_win);
- X touchwin(stat_win);
- X touchwin(main_win);
- X wnoutrefresh(main_win);
- X wnoutrefresh(stat_win);
- X doupdate();
- X cursor_flag++;
- X break;
- X
- X case(0): /**************************************/
- X /* something weird :-C */
- X /**************************************/
- X break;
- X
- X default: /**************************************/
- X /* all others */
- X /**************************************/
- X
- X /* scream at the user (ring the bell) */
- X
- X beep();
- X break;
- X
- X } /* switch(term_code) */
- X
- X /* do we need reposition the cursor? */
- X
- X if(cursor_flag)
- X {
- X /* set the cursor where it should be */
- X
- X wmove(main_win,scr_row,scr_col);
- X wrefresh(main_win); /* make sure screen is up to date */
- X cursor_flag = 0; /* clear the cursor set flag */
- X }
- X
- X } /* for(;;) */ /* end of main processing loop */
- X
- X} /*** proc_dir ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: find_dir
- X
- X Purpose: Search for a directory info node in the link list. If one
- X is found, it means that the directory is currently active.
- X
- X Global variables:
- X
- X Name Examine/Modify/Use/Read/Write
- X ---- -----------------------------
- X none
- X
- X Return Codes:
- X
- X Code Reason
- X ---- ------
- X none
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- static DIR_PTR *find_dir(head,tail,dir_name)
- X /******* FORMAL PARAMETERS *******/
- X DIR_PTR *head, /* pointer to head of dir info nodes */
- X *tail; /* pointer to end of dir info nodes */
- X char *dir_name; /* directory name to search for */
- X
- X{ /*** find_dir ***/
- X
- X head = head->next;
- X
- X while(head != tail && strcmp(head->dir_name,dir_name) != 0)
- X head = head->next;
- X
- X if(head == tail)
- X return(NULL);
- X
- X return(head);
- X
- X} /*** find_dir ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: link_dir_ent
- X
- X Purpose: Link the info for the current directory into the active
- X directory linked list.
- X
- X Global variables:
- X
- X Name Examine/Modify/Use/Read/Write
- X ---- -----------------------------
- X none
- X
- X Return Codes:
- X
- X Code Reason
- X ---- ------
- X temp_ptr pointer to new node
- X NULL couldn't get memory for node
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- static DIR_PTR *link_dir_ent(dir_ent_head,dir_ent_tail,dirptr,dir_name,
- X first_pool,curr_pool,pool_length,stat_time,
- X num_file)
- X /******* FORMAL PARAMETERS *******/
- X DIR_PTR *dir_ent_head, /* head of directory chain list */
- X *dir_ent_tail; /* tail of directory chain list */
- X ENT_DEF *dirptr; /* pointer to directory information */
- X char *dir_name; /* name of current directory */
- X POOL_DEF *first_pool, /* first memory pool for directory */
- X *curr_pool; /* current memory pool */
- X size_t pool_length; /* length to allocate for new pool */
- X time_t stat_time; /* time directory was last modified */
- X short num_file; /* number of files in directory */
- X
- X{ /*** link_dir_ent ***/
- X /******** LOCAL VARIABLES ********/
- X DIR_PTR *new_ptr, /* new node pointer */ *temp_ptr; /* previous node in list */
- X
- X
- X /* allocate the node first */
- X
- X new_ptr = (DIR_PTR *) malloc(sizeof(DIR_PTR));
- X
- X if(new_ptr == NULL)
- X return(NULL); /* couldn't get the memory */
- X
- X /* got the memory for the node; link it in */
- X
- X temp_ptr = dir_ent_tail->prev; /* save where we were */
- X dir_ent_tail->prev = new_ptr;
- X new_ptr->next = dir_ent_tail;
- X temp_ptr->next = new_ptr;
- X new_ptr->prev = temp_ptr;
- X
- X new_ptr->dirptr = dirptr;
- X new_ptr->dir_name = dir_name;
- X new_ptr->first_pool = first_pool;
- X new_ptr->curr_pool = curr_pool;
- X new_ptr->pool_length = pool_length;
- X new_ptr->num_file = num_file;
- X new_ptr->stat_time = stat_time;
- X new_ptr->count = 1; /* first time here */
- X
- X return(new_ptr); /* return pointer to new node */
- X
- X} /*** link_dir_ent ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: unlink_dir_ent
- X
- X Purpose: Unlink the info for the current directory from the active
- X directory linked list.
- X
- X Global variables:
- X
- X Name Examine/Modify/Use/Read/Write
- X ---- -----------------------------
- X none
- X
- X Return Codes:
- X
- X Code Reason
- X ---- ------
- X none
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- static void unlink_dir_ent(current)
- X /******* FORMAL PARAMETERS *******/
- X DIR_PTR *current; /* active directory list node */
- X
- X{ /*** unlink_dir_ent ***/
- X /******** LOCAL VARIABLES ********/
- X DIR_PTR *temp; /* temporary node pointer */
- X
- X
- X if(current->count > 1) /* can we unlink it? */
- X {
- X current->count -= 1;
- X return; /* nope, still active */
- X }
- X
- X temp = current->prev;
- X temp->next = current->next;
- X temp = current->next;
- X temp->prev = current->prev;
- X free(current->dir_name); /* free up directory name string */
- X free(current); /* free up the node itself */
- X
- X return;
- X
- X} /*** unlink_dir_ent ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: get_year
- X
- X Purpose: Obtain and return the value for the current year.
- X
- X Global variables:
- X
- X Name Examine/Modify/Use/Read/Write
- X ---- -----------------------------
- X none
- X
- X Return Codes:
- X
- X Code Reason
- X ---- ------
- X tstr->tm_year current year value
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- static int get_year()
- X
- X{ /*** get_year ***/
- X /******** LOCAL VARIABLES ********/
- X long clock; /* binary time value */
- struct tm *tstr; /* time structure pointer */
- X
- X
- X clock = (long) time((long *) 0); /* get current time */
- X tstr = localtime(&clock); /* fill in the time structure */
- X return(tstr->tm_year); /* return the current year value */
- X
- X} /*** get_year ***/
- END_OF_FILE
- if test 78195 -ne `wc -c <'main.c'`; then
- echo shar: \"'main.c'\" unpacked with wrong size!
- fi
- # end of 'main.c'
- fi
- echo shar: End of archive 7 \(of 7\).
- cp /dev/null ark7isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 7 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-