home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-05-13 | 64.8 KB | 2,481 lines |
- Newsgroups: comp.sources.unix
- From: peirce@gw.wmich.edu (Leonard J. Peirce)
- Subject: v26i053: maint - full-screen file and directory maintenance tool, Part05/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 53
- Archive-Name: maint/part05
-
- #! /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 5 (of 7)."
- # Contents: misc.c
- # Wrapped by vixie@cognition.pa.dec.com on Thu May 14 23:05:43 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'misc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'misc.c'\"
- else
- echo shar: Extracting \"'misc.c'\" \(62395 characters\)
- sed "s/^X//" >'misc.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: Miscellaneous routines for MAINT.
- X
- X Arguments: See individual routines.
- X
- X External variables: curr_year
- X spec_win
- X stat_win
- X main_win
- X args
- X
- X External functions:
- X
- X Defined: add_filetype, banystr, cat, check_marks, cont_after_stop,
- X follow_link, get_bnum, get_dir, get_dir_mem, get_filemarks,
- X get_num_file, make_ent, make_screen, mystrcpy, mystrmcpy,
- X padcpy, prot_str_to_val, prot_val_to_str, rename, set_args,
- X set_date, set_nodes, set_screen, set_width, spawn,
- X squeeze_str, strindex, strtcpy
- X
- X Called: date_qsort, make_slot, name_qsort, put_pool, put_slot,
- X size_qsort, sort_files
- X
- X Files accessed: See individual routines.
- X
- X Return codes: See individual routines.
- X
- X Compiling instructions: See Makefile.
- X
- X Linking instructions: See Makefile.
- X
- X Other information: (C) Copyright 1992, Leonard J. Peirce
- 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#else
- X#include <curses.h>
- X#endif
- X#include <sys/param.h>
- X#include <malloc.h>
- X#include <time.h>
- X#include <string.h>
- X#if !defined(SYSV) || defined(sun)
- X#include <sys/wait.h>
- X#endif
- X#include <errno.h>
- X#include <ctype.h>
- X#include <varargs.h>
- X#include "maint.h"
- X#include <sys/stat.h>
- X
- X/******************************************************************************/
- X/* */
- X/* # D E F I N E S */
- X/* */
- X/******************************************************************************/
- 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 int curr_year;
- X
- extern ENT_DEF *baseptr;
- X
- extern WINDOW *spec_win,
- X *main_win,
- X *stat_win;
- X
- extern ARG_DEF args;
- X
- extern char *getenv();
- X
- extern int execve(),
- X vfork(),
- X put_slot(),
- X make_slot();
- X
- extern u_short cont_flag;
- X
- extern void put_pool(),
- X date_qsort(),
- X size_qsort(),
- X name_qsort(),
- X sort_files();
- X
- X char *mystrcpy(),
- X *mystrmcpy(),
- X *prot_val_to_str(),
- X *padcpy(),
- X *set_date(),
- X *cat();
- X
- X#if !defined(SYSV) || defined(sun)
- X long get_bnum();
- X#endif
- X
- X int check_marks(),
- X strtcpy(),
- X follow_link(),
- X make_ent(),
- X
- X#if defined(SYSV) && !defined(sun)
- X rename(),
- X#endif
- X
- X strindex();
- X
- X u_short add_filetype();
- X
- X short banystr(),
- X get_num_file(),
- X prot_str_to_val();
- X
- X u_char filetype_char();
- X
- X void set_screen(),
- X set_width(),
- X set_args(),
- X set_nodes(),
- X get_dir_mem(),
- X get_dir(),
- X message(),
- X squeeze_str(),
- X make_screen(),
- X cont_after_stop(),
- X get_filemarks();
- 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 char *get_name();
- X
- static u_short check_nlen();
- X
- static u_char set_type();
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: set_screen
- X
- X Purpose: Compute values for parameters that relate to the screen,
- X including number of columns, number of files, and the number
- X of screens needed for the directory.
- X
- X Global variables:
- X
- X Name Examine/Modify/Use/Read/Write
- X ---- -----------------------------
- X COLS X
- X
- X Return Codes:
- X
- X Code Reason
- X ---- ------
- X none
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- void set_screen(num_screen,scr_file,num_file,slot_width,node_row_max,num_col)
- X /******* FORMAL PARAMETERS *******/
- X short *num_screen, /* number of screens in directory */
- X *scr_file, /* number of file slots per screen */
- X num_file, /* number of files in directory */
- X slot_width; /* width of file slot */
- X u_short node_row_max; /* max. # of rows in node array */
- X short *num_col; /* number of columns for full screen */
- X
- X{ /*** set_screen ***/
- X
- X
- X /* compute the number of files per row of the screen */
- X
- X *num_col = (short) COLS/(slot_width + SLOT_GAP + 1);
- X
- X if(*num_col == 0)
- X *num_col = 1; /* must have at least one column */
- X
- X /* now compute how many file slots will fit on a screen */
- X
- X *scr_file = *num_col * (short) node_row_max;
- X
- X /* compute how many screens will be needed for this directory */
- X
- X *num_screen = num_file/(*scr_file);
- X
- X if((num_file % (*scr_file)) != 0)
- X *num_screen += 1;
- X
- X return;
- X
- X} /*** set_screen ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: set_nodes
- X
- X Purpose: Initialize the screen slot node pointers for the current
- X directory.
- 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
- void set_nodes(nodes,node_row_max,scr_file,num_screen,curr_screen,num_file,
- X slot_width,num_col)
- X /******* FORMAL PARAMETERS *******/
- register NODE_DEF nodes[][MAX_NODE_COL+1]; /* screen node matrix */
- X u_short node_row_max; /* max. # of rows in node array */
- X short *scr_file, /* number of files on current screen */
- X num_screen, /* number of screens for directory */
- X curr_screen, /* current screen */
- X num_file, /* number of files in directory */
- X slot_width, /* number of characters for file slot */
- X num_col; /* number of columns per screen */
- X
- X{ /*** set_nodes ***/
- X /******** LOCAL VARIABLES ********/
- register NODE_DEF *tptr; /* temporary node pointer */
- register int i, /* loop and array index */
- X j; /* ditto.... */
- static short left_val, /* left pointer for node */
- X up_val, /* up pointer for node */
- X column_val, /* current column value */
- X num_row, /* number of rows for this screen */
- X full_row, /* number of full rows for screen */
- X full_col; /* number of full columns */
- X
- X
- X if(curr_screen == num_screen) /* if this is the last page */
- X {
- X /* recompute the number of columns; it might be different because
- X * this is the last page of the directory
- X */
- X
- X /* compute how many files will be on this screen of the directory */
- X
- X *scr_file = num_file - (num_col * node_row_max * (curr_screen - 1));
- X
- X /* now compute how many columns are needed for the last screen */
- X
- X num_col = *scr_file / node_row_max;
- X
- X if((*scr_file % node_row_max) != 0)
- X num_col++;
- X }
- X else
- X {
- X /* compute how many files will be on this screen of the directory */
- X
- X *scr_file = num_col * (short) node_row_max;
- X }
- X
- X if(*scr_file < node_row_max) /* determine number of rows */
- X num_row = *scr_file;
- X else
- X num_row = node_row_max;
- X
- X left_val = num_col - 1; /* set left and right pointers */
- X j = 0; /* start with the first column */
- X column_val = 0; /* cursor on screen starts @ (0,0) */
- X full_col = *scr_file / node_row_max; /* calculate number of full columns */
- X
- X if(full_col == 0) /* must have at least one full column */
- X full_col = 1;
- X
- X full_row = *scr_file - (full_col * num_row);
- X
- X if(full_row == 0)
- X full_row = *scr_file / full_col;
- X
- X /* first initialize the node matrix just like it would be a full screen;
- X * then we will "trim" the edges to make sure that things point to the right
- X * places in case the cursor would to need to wrap around the screen
- X */
- X
- X up_val = num_row - 1;
- X i = 0;
- X
- X while(i < num_row)
- X {
- X j = 0;
- X left_val = num_col - 1; /* left j value */
- X column_val = 0;
- X
- X while(j < num_col)
- X {
- X tptr = &(nodes[i][j]); /* get a pointer to the current node */
- X tptr->right_col = (j + 1) % num_col;
- X tptr->left_col = left_val;
- X tptr->up_col = j;
- X tptr->down_col = j;
- X
- X tptr->right_row = i;
- X tptr->left_row = i;
- X tptr->up_row = up_val;
- X tptr->down_row = (i + 1) % num_row;
- X
- X tptr->row = i;
- X tptr->column = column_val;
- X column_val = column_val + slot_width + SLOT_GAP + 1;
- X left_val = (left_val + 1) % num_col;
- X j++;
- X }
- X
- X up_val = (up_val + 1) % num_row;
- X i++;
- X }
- X
- X /* now trim the edges of the matrix just in case this is the last screen
- X * of the directory
- X */
- X
- X /* first go along the top of the screen */
- X
- X i = 0;
- X
- X for(j = 0; j < num_col; j++)
- X {
- X tptr = &(nodes[i][j]); /* get a pointer to the node */
- X
- X if(!j) /* are we in the top left node? */
- X {
- X /* top left node; the values for going up from this node should
- X * point to bottom node in the last column on the screen
- X */
- X
- X tptr->up_row = full_row - 1;
- X tptr->up_col = num_col - 1;
- X }
- X else
- X {
- X tptr->up_col = j - 1;
- X tptr->up_row = num_row - 1;
- X }
- X }
- X
- X /* now go along the left of the screen */
- X
- X j = 0;
- X
- X for(i = 0; i < num_row; i++)
- X {
- X tptr = &(nodes[i][j]);
- X
- X if(!i)
- X {
- X /* we are in the top left of the screen; going left from here
- X * should go to the bottom, right-most node
- X */
- X
- X tptr->left_row = full_row - 1;
- X tptr->left_col = num_col - 1;
- X }
- X else
- X {
- X if(i < full_row + 1)
- X tptr->left_col = num_col - 1;
- X else
- X tptr->left_col = full_col - 1;
- X
- X tptr->left_row = (i - 1) % num_row;
- X }
- X }
- X
- X /* trim the bottom full columns */
- X
- X i = num_row - 1;
- X
- X for(j = 0; j < full_col; j++)
- X {
- X tptr = &(nodes[i][j]); /* get a pointer to the node */
- X tptr->down_col = j + 1;
- X }
- X
- X /* now go along the right side of the last full column */
- X
- X j = full_col - 1;
- X
- X for(i = full_row; i < num_row; i++)
- X {
- X tptr = &(nodes[i][j]);
- X tptr->right_row = (i + 1) % num_row;
- X tptr->right_col = 0;
- X }
- X
- X /* trim along the last column, whether it be full or not */
- X
- X j = num_col - 1;
- X
- X for(i = 0; i < full_row; i++)
- X {
- X tptr = &(nodes[i][j]);
- X tptr->right_row = (i + 1) % num_row;
- X tptr->right_col = 0;
- X }
- X
- X /* set the last node on the screen; this is a special case */
- X
- X tptr = &(nodes[full_row-1][num_col-1]);
- X tptr->down_row = 0;
- X tptr->down_col = 0;
- X
- X return;
- X
- X} /*** set_nodes ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: make_ent
- X
- X Purpose: Gather all the information about an individual file, including
- X the protection string and filename that will be displayed on
- X the screen. This information is stored in the directory entry.
- 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 SUCCESS
- X FAILURE
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- int make_ent(ent,filename,num_block)
- X /******* FORMAL PARAMETERS *******/
- register ENT_DEF *ent; /* pointer to file entry */
- register char *filename; /* file to be looked up */
- X long *num_block; /* number of blocks in directory */
- X
- X{ /*** make_ent ***/
- X /******** LOCAL VARIABLES ********/
- static int status; /* return code status holder */
- static struct stat statbuf; /* file stat structure */
- X
- X
- X#if !defined(SYSV) || defined(sun)
- X status = lstat(filename,&statbuf);
- X#else
- X status = stat(filename,&statbuf);
- X#endif
- X
- X if(status != 0)
- X return(FAILURE);
- X
- X ent->type = set_type(statbuf.st_mode);
- X ent->prot = statbuf.st_mode;
- X ent->time = statbuf.st_mtime;
- X ent->size = statbuf.st_size;
- X ent->command = NULL;
- X ent->text = NULL;
- X ent->gid = statbuf.st_gid;
- X ent->uid = statbuf.st_uid;
- X ent->name_len = check_nlen(filename);
- X
- X /* set the filename that will be displayed on the screen */
- X
- X strcpy(ent->scr_name,get_name(filename,&(ent->disp_len),ent->prot,
- X ent->type));
- X
- X#if defined(SYSV) && !defined(sun)
- X *num_block += kbytes(statbuf.st_size);
- X#else
- X *num_block += statbuf.st_blocks;
- X#endif
- X
- X return(SUCCESS);
- X
- X} /*** make_ent ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: make_screen
- X
- X Purpose: Create the individual screen entries for the current screen
- X of the directory and write them to the virtual display.
- X
- X This routine will also clear out the slots on the screen where
- X the files should not appear. This would happen only on the
- X last page of a directory.
- 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
- void make_screen(window,nodes,dirptr,args,curr_screen,node_row_max,
- X node_col_max,scr_file,num_slot,slot_width,text_flag)
- X /******* FORMAL PARAMETERS *******/
- X WINDOW *window; /* window to write to */
- X NODE_DEF nodes[][MAX_NODE_COL+1]; /* screen node matrix */
- X ENT_DEF *dirptr; /* pointer to directory information */
- register ARG_DEF *args; /* command-line arguments */
- X short curr_screen; /* current screen number */
- X u_short node_row_max, /* max. # of rows in node array */
- X node_col_max; /* max. # of columns in node array */
- register short scr_file; /* number of files for current screen */
- X short num_slot, /* number of slots per screen */
- X slot_width, /* width of a filename screen slot */
- X text_flag; /* whether we display text descrips */
- X
- X{ /*** make_screen ***/
- X /******** LOCAL VARIABLES ********/
- register ENT_DEF *ent; /* pointer to current directory entry */
- register short file_count = 0; /* number of files processed */
- static int rend_set, /* rendition setting for slots */
- X scr_row, /* what row on screen to write to */
- X scr_col; /* what column on screen to write to */
- static short i, /* loop and array index */
- X j; /* " " " " */
- X char buf[BUFSIZ+1]; /* formatting buffer */
- X
- X
- X /* get pointer to the first directory entry for the current screen */
- X
- X ent = dirptr + (u_long) ((curr_screen - 1) * num_slot);
- X j = 0;
- X
- X while((j < node_col_max) && (file_count < scr_file))
- X {
- X i = 0;
- X scr_col = nodes[i][j].column + 1; /* get column value for now */
- X scr_row = 0;
- X
- X while((i < node_row_max) && (file_count < scr_file))
- X {
- X /* create the screen slot for the file; this included determining
- X * if we need to put something special up in case the file has
- X * some command(s) associated with it
- X */
- X
- X rend_set = make_slot(buf,ent,args,slot_width,text_flag);
- X
- X /* now write the file information to the screen in the right spot */
- X
- X put_slot(window,scr_row,scr_col,buf,rend_set);
- X i++; /* move to next column */
- X file_count++; /* count this file as processed */
- X scr_row++; /* move to next row on screen */
- X ent++; /* go to next directory entry */
- X }
- X
- X j++; /* go down the screen node matrix */
- X }
- X
- X if(num_slot > scr_file) /* do we need to clear out some of */
- X { /* the slots on the screen? */
- X /* clear out the slots */
- X
- X while(i++ < node_row_max)
- X {
- X wmove(window,scr_row++,scr_col);
- X wclrtoeol(window);
- X }
- X
- X if(j < node_col_max)
- X {
- X /* we have more than one column to clear out */
- X
- X scr_col += slot_width + 1;
- X scr_row = 0;
- X
- X while(scr_row < node_row_max)
- X {
- X wmove(window,scr_row++,scr_col);
- X wclrtoeol(window);
- X }
- X }
- X }
- X
- X return;
- X
- X} /*** make_screen ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: check_marks
- X
- X Purpose: Check to see if there are any marks in the current directory.
- 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 TRUE marks exist in current directory
- X FALSE no marks in current directory
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- int check_marks(ent,num_files)
- X /******* FORMAL PARAMETERS *******/
- register ENT_DEF *ent; /* pointer to current file entry */
- register short num_files; /* number of files in directory */
- X
- X{ /*** check_marks ***/
- X
- X while(num_files--) /* check all entries if necessary */
- X {
- X if(ent->command) /* command for this file? */
- X return(TRUE); /* yes, no need to check any more */
- X
- X ent++; /* nope, go to next entry */
- X }
- X
- X return(FALSE);
- X
- X} /*** check_marks ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: get_dir_mem
- X
- X Purpose: Compute the amount of memory needed for the current directory
- X and allocate it. Also set the global pointer to the base of
- X the memory so that it may be used for sorting if so desired.
- X
- X Global variables:
- X
- X Name Examine/Modify/Use/Read/Write
- X ---- -----------------------------
- X baseptr X X
- X
- X Return Codes:
- X
- X Code Reason
- X ---- ------
- X none
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- void get_dir_mem(dirptr,dirsize,num_file)
- X /******* FORMAL PARAMETERS *******/
- X ENT_DEF **dirptr; /* where to store pointer to memory */
- X u_int *dirsize; /* amount of memory allocated */
- X short num_file; /* number of files in directory */
- X
- X{ /*** get_dir_mem ***/
- X /******** LOCAL VARIABLES ********/
- X u_int memsize; /* amount of memory to allocated */
- X
- X
- X /* allocate enough memory to hold the information about each of the
- X * files in the current directory; we get the amount of memory by multi-
- X * plying the number of files (plus 1, in case we want to sort them)
- X * in the directory by the length the structure definition that holds
- X * the information about a file
- X */
- X
- X /* compute how much memory to allocate */
- X
- X memsize = (u_int) ((num_file + 1) * sizeof(ENT_DEF));
- X *dirsize = memsize;
- X
- X baseptr = (ENT_DEF *) malloc(memsize);
- X
- X if(baseptr == NULL)
- X {
- X exit(CANT_ALLOCATE);
- X }
- X else
- X *dirptr = baseptr;
- X
- X /* memory allocated for the directory */
- X return;
- X
- X} /*** get_dir_mem ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: get_dir
- X
- X Purpose: Get the number of files in the current directory, allocate the
- X necessary memory to store the information about the directory,
- X and obtain the information about the individual files.
- 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
- void get_dir(dirptr,args,num_block,curr_pool,num_file,pool_length)
- X /******* FORMAL PARAMETERS *******/
- register ENT_DEF *dirptr; /* pointer to allocated memory */
- register ARG_DEF *args; /* run-time argument flags */
- X long *num_block; /* number of blocks in directory */
- X POOL_DEF **curr_pool; /* pointer to current memory pool */
- X short *num_file; /* number of files in directory */
- X size_t pool_length; /* length to allocate for new pools */
- X
- X{ /*** get_dir ***/
- X /******** LOCAL VARIABLES ********/
- X#if !defined(SYSV)
- register struct direct *dir_ent; /* pointer to directory file entry */
- X#else
- register struct dirent *dir_ent; /* Suns use this as well as SysV */
- X#endif
- X size_t name_length; /* length of filename */
- X DIR *dptr; /* pointer to directory file */
- X
- X
- X dptr = opendir("."); /* open directory so we can read it */
- X
- X if(dptr == NULL)
- X return;
- X
- X /* process all of the directory entries that we can get */
- X
- X while((dir_ent = readdir(dptr)) != NULL)
- X {
- X /*try to make the directory entry for this file */
- X
- X if(args->dot_files == TRUE || dir_ent->d_name[0] != '.')
- X {
- X if(make_ent(dirptr,dir_ent->d_name,num_block) == SUCCESS)
- X {
- X /* everything ok so far; store the full filename in a memory pool */
- X
- X name_length = strlen(dir_ent->d_name);
- X put_pool(&(dirptr->filename),curr_pool,dir_ent->d_name,name_length,
- X pool_length);
- X dirptr++;
- X }
- X else
- X *num_file -= 1; /* bummer; subtract one from num_file */
- X }
- X }
- X
- X closedir(dptr);
- X
- X /* create a dummy entry at the end in case we want to sort */
- X
- X if(sizeof(int) == 4)
- X {
- X dirptr->size = 0xEFFFFFFF;
- X dirptr->time = 0xEFFFFFFF;
- X }
- X else
- X {
- X dirptr->size = 0xEFFF;
- X dirptr->time = 0xEFFF;
- X }
- X
- X put_pool(&(dirptr->filename),curr_pool,"~~~~~~~~~~",10,pool_length);
- X
- X if(args->sort)
- X sort_files(*num_file - 1,args->sort);
- X
- X/* *num_block = (long) kbytes(dbtob(*num_block)); */
- X return;
- X
- X} /*** get_dir ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: get_num_file
- X
- X Purpose: Get the number of files in the current directory.
- 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 count number of files in directory
- X -1 failure
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- short get_num_file(args)
- X /******* FORMAL PARAMETERS *******/
- register ARG_DEF *args; /* run-time arguments */
- X
- X{ /*** get_num_file ***/
- X /******** LOCAL VARIABLES ********/
- register DIR *dptr; /* pointer to directory file entry */
- register short count; /* number of files in directory */
- X#if !defined(SYSV)
- register struct direct *dir_ent; /* pointer to directory file entry */
- X#else
- register struct dirent *dir_ent; /* Suns use this as well as SysV */
- X#endif
- X
- X
- X dptr = opendir("."); /* open the current directory */
- X
- X if(dptr == NULL)
- X return(-1);
- X
- X count = 0;
- X
- X if(args->dot_files == TRUE)
- X {
- X while(readdir(dptr) != NULL)
- X ++count;
- X }
- X else
- X {
- X while((dir_ent = readdir(dptr)) != NULL)
- X {
- X if(dir_ent->d_name[0] != '.')
- X ++count;
- X }
- X }
- X
- X closedir(dptr);
- X return(count); /* return number of files */
- X
- X} /*** get_num_file ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: mystrcpy
- X
- X Purpose: Version of strcpy that copies a string and returns a pointer
- X to the null character in the destination string.
- 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 dest - 1 pointer to null character terminating the
- X destionation string
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- char *mystrcpy(dest,source)
- X /******* FORMAL PARAMETERS *******/
- X char *dest, /* destination string */
- X *source; /* source string */
- X
- X{ /*** mystrcpy ***/
- X
- X while(*dest++ = *source++) /* copy the source string to the dest */
- X ;
- X
- X return(dest - 1); /* return pointer to null character */
- X
- X} /*** mystrcpy ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: mystrmcpy
- X
- X Purpose: Version of strncpy that copies exactly n characters and
- X returns a pointer to the null character in the destination
- X string.
- 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 dest - 1 pointer to null character terminating the
- X destionation string
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- char *mystrmcpy(dest,source,length)
- X /******* FORMAL PARAMETERS *******/
- X char *dest, /* destination string */
- X *source; /* source string */
- X int length; /* max. length to copy */
- X
- X{ /*** mystrmcpy ***/
- X
- X while(*source != '\0' && length-- >= 0)
- X *dest++ = *source++;
- X
- X *(dest - 1) = '\0'; /* make sure it's a string */
- X return(dest - 1); /* return pointer to null character */
- X
- X} /*** mystrmcpy ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: prot_val_to_str
- X
- X Purpose: Create the string representing the file protection for a
- X specific file from the integer value for the protection.
- 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 buf protection string
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- char *prot_val_to_str(prot)
- X /******* FORMAL PARAMETERS *******/
- register u_short prot; /* protection word value */
- X
- X{ /*** prot_val_to_str ***/
- X /******** LOCAL VARIABLES ********/
- register char *str; /* pointer to buffer */
- register short i, /* loop and array index */
- X j,
- X k;
- static char buf[PROT_MAX+1]; /* where to put the protection string */
- X
- X
- X /* first determine what type of file it is */
- X
- X str = buf;
- X
- X switch(prot & S_IFMT)
- X {
- X case(S_IFREG):
- X *str = '-'; /* regular file */
- X break;
- X case(S_IFDIR):
- X *str = 'd'; /* directory */
- X break;
- X case(S_IFCHR):
- X *str = 'c'; /* character special file */
- X break;
- X case(S_IFIFO):
- X *str = 'p'; /* named pipe */
- X break;
- X case(S_IFBLK):
- X *str = 'b'; /* block special file */
- X break;
- X#if !defined(SYSV) || defined(sun)
- X case(S_IFLNK):
- X *str = 'l'; /* symbolic link */
- X break;
- X#endif
- X default:
- X *str = '-';
- X }
- X
- X /* create the permission string */
- X
- X k = 1; /* skip over filetype in string */
- X j = 0;
- X
- X for(i = 0; i < 3; i++)
- X {
- X if(prot & (S_IREAD >> j)) /* check for read permission */
- X *(str + k) = 'r';
- X else
- X *(str + k) = '-';
- X
- X if(prot & (S_IWRITE >> j)) /* check for write permission */
- X *(str + k + 1) = 'w';
- X else
- X *(str + k + 1) = '-';
- X
- X if(prot & (S_IEXEC >> j)) /* check for execute permission */
- X *(str + k + 2) = 'x';
- X else
- X *(str + k + 2) = '-';
- X
- X k += 3;
- X j += 3;
- X }
- X
- X /* check the setuid bit */
- X
- X if(prot & S_ISUID)
- X {
- X /* setuid is set; now see if it is executable */
- X
- X if(*(str + 3) == 'x')
- X *(str + 3) = 's';
- X else
- X *(str + 3) = 'S';
- X }
- X
- X if(prot & S_ISGID)
- X {
- X /* setgid is set; now see if it is executable */
- X
- X if(*(str + 6) == 'x')
- X *(str + 6) = 's';
- X else
- X *(str + 6) = 'S';
- X }
- X
- X if(prot & S_ISVTX)
- X {
- X /* sticky bit is set */
- X
- X *(str + 9) = 't';
- X }
- X
- X *(str + PROT_MAX) = '\0'; /* make it a string */
- X return(buf);
- X
- X} /*** prot_val_to_str ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: prot_str_to_val
- X
- X Purpose: Given a protection string and the original integer value
- X for a file's protection, edit the string and if it is valid,
- X calculate the new protection integer value.
- 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 SUCCESS
- X FAILURE invalid protection specification
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- short prot_str_to_val(str,new_val)
- X /******* FORMAL PARAMETERS *******/
- register char *str; /* protection string */
- X u_short *new_val; /* calculated protection value */
- X
- X{ /*** prot_str_to_val ***/
- X
- X /******** LOCAL VARIABLES ********/
- X u_short mode, /* protection mode value */
- X val, /* temporary value */
- X j, /* loop and array index */
- X scale; /* scaling factor for current field */
- X
- X mode = 0;
- X val = 0; /* digit value */
- X j = 0; /* start with first group */
- X scale = 0100;
- X
- X while(j < (PROT_MAX - 1))
- X {
- X switch(*(str + j))
- X {
- X case('r'):
- X val += 4;
- X break;
- X case('-'):
- X break;
- X default:
- X return(FAILURE);
- X }
- X
- X switch(*(str + j + 1))
- X {
- X case('w'):
- X val += 2;
- X break;
- X case('-'):
- X break;
- X default:
- X return(FAILURE);
- X }
- X
- X /* add the mode for the current octal digit to the overall mode value */
- X
- X mode = mode + (scale * val);
- X scale /= 010; /* scale down for next digit */
- X val = 0; /* reset temporary digit value */
- X j += 3;
- X }
- X
- X /* now handle the x/s/S field of the first TWO digits in the mode string;
- X * we'll do the sticky bit last
- X */
- X
- X switch(*(str + 2))
- X {
- X case('-'):
- X break;
- X case('x'):
- X mode += 0100;
- X break;
- X case('s'):
- X mode += 04100;
- X break;
- X case('S'):
- X mode += 04000;
- X break;
- X default:
- X return(FAILURE);
- X }
- X
- X switch(*(str + 5))
- X {
- X case('-'):
- X break;
- X case('x'):
- X mode += 010;
- X break;
- X case('s'):
- X mode += 02010;
- X break;
- X case('S'):
- X mode += 02000;
- X break;
- X default:
- X return(FAILURE);
- X }
- X
- X /* check for the last field */
- X
- X switch(*(str + 8))
- X {
- X case('-'):
- X break;
- X case('x'):
- X mode++;
- X break;
- X case('t'):
- X mode += 01000; /* sticky bit; only works for root */
- X break;
- X default:
- X return(FAILURE);
- X }
- X
- X if(*(str + 9))
- X return(FAILURE); /* string too long */
- X
- X *new_val = mode; /* ok here; set the return value */
- X return(SUCCESS);
- X
- X} /*** prot_str_to_val ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: set_args
- X
- X Purpose: Set the original values for ent_factor and slot_width along
- X with initializing some of the other flags that provide infor-
- X mation about what run-time arguments were specified.
- X
- X Global variables:
- X
- X Name Examine/Modify/Use/Read/Write
- X ---- -----------------------------
- X COLS
- X
- X Return Codes:
- X
- X Code Reason
- X ---- ------
- X none
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- void set_args(args,slot_width,ent_factor)
- X /******* FORMAL PARAMETERS *******/
- register ARG_DEF *args; /* run-time argument flags */
- X short *slot_width; /* starting slot width */
- X size_t *ent_factor; /* ent. size memory allocation factor */
- X
- X{ /*** set_args ***/
- X
- X /* initialize the width to include the length of the filename that
- X * will be displayed and the spot to hold the cursor; also update
- X * the entry size factor for later
- X */
- X
- X *slot_width = DISP_MAX;
- X *ent_factor = FUDGE_FACTOR;
- X
- X /* we have to see what info should be included to get the
- X * slot width and the entry factor
- X */
- X
- X if(args->date)
- X *slot_width = *slot_width + DATE_MAX + FIELD_GAP;
- X
- X if(args->size)
- X *slot_width = *slot_width + SIZE_MAX + FIELD_GAP;
- X
- X if(args->prot)
- X *slot_width = *slot_width + PROT_MAX + FIELD_GAP;
- X
- X if(args->owner)
- X *slot_width = *slot_width + OWNER_MAX + FIELD_GAP;
- X
- X if(args->group)
- X *slot_width = *slot_width + GROUP_MAX + FIELD_GAP;
- X
- X if(args->text)
- X {
- X /* the user wants text descriptors */
- X
- X *ent_factor = *ent_factor + TEXT_MAX + 1;
- X *slot_width = *slot_width + TEXT_MAX + FIELD_GAP;
- X
- X /* now see if there is enough room to include the text descriptors on
- X * the screen
- X */
- X
- X if(*slot_width > (COLS - 1))
- X {
- X args->text = SLOT_OVF; /* they overflow the file slots */
- X *slot_width = *slot_width - (TEXT_MAX + FIELD_GAP);
- X }
- X }
- X
- X if(*slot_width == DISP_MAX)
- X args->def = 1; /* just default info on screen */
- X else
- X args->def = 0; /* clear to be thorough..... */
- X
- X return;
- X
- X} /*** set_args ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: set_width
- X
- X Purpose: Set the slot width for the current directory based on whether
- X or not text descriptors will be included on the screen
- 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
- void set_width(slot_width,text_flag)
- X /******* FORMAL PARAMETERS *******/
- X short *slot_width, /* current slot width */
- X text_flag; /* text descrips included for dir? */
- X
- X{ /*** set_width ***/
- X
- X
- X /* should we at least TRY to get text descriptors on the screen? */
- X
- X if(text_flag == DISPLAY_TEXT)
- X {
- X /* yes, they need to be displayed; increase the slot_width
- X * to accommodate them
- X */
- X
- X *slot_width = *slot_width + TEXT_MAX + 1;
- X }
- X
- X return;
- X
- X} /*** set_width ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: banystr
- X
- X Purpose: Determine if a finite-length character string contains
- X any characters from a second null-terminated character
- X string.
- 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 >=0 match was found; return code is the offset
- X into str1 where the character is found
- X -1 no common characters in the two strings
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- short banystr(str1,str2,length)
- X /******* FORMAL PARAMETERS *******/
- register char *str1, /* string to search */
- X *str2; /* what to look for */
- X short length; /* when to stop searching */
- X
- X{ /*** banystr ***/
- X /******** LOCAL VARIABLES ********/
- register int offset1, /* offset into string str1 */
- X offset2; /* offset into string str2 */
- X
- X
- X if(str1 == NULL || str2 == NULL || length <= 0)
- X return(-1);
- X
- X if((*str1 == '\0') || (*str2 == '\0'))
- X return(-1);
- X
- X offset1 = 0;
- X
- X while(*(str1+offset1) != '\0' && length--)
- X {
- X offset2 = 0;
- X while(*(str2+offset2) != '\0')
- X {
- X if(*(str1+offset1) == *(str2+offset2))
- X {
- X return(offset1); /* match found; return offset */
- X }
- X ++offset2;
- X }
- X ++offset1;
- X }
- X
- X return(-1); /* no match; return -1 */
- X
- X} /*** banystr ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: set_type
- X
- X Purpose: Determine the type of a file and return it.
- 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 REGULAR regular file
- X DIRECTORY directory
- X CHARACTER character-type special file
- X BLOCK block special file
- X FIFO FIFO (named pipe)
- X SOCKET socket file
- X LINK symbolic link
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- static u_char set_type(mode)
- X /******* FORMAL PARAMETERS *******/
- X u_short mode; /* protection mode to examine */
- X
- X{ /*** set_type ***/
- X
- X switch(mode & S_IFMT)
- X {
- X#if !defined(SYSV) || defined(sun)
- X case(S_IFLNK):
- X return(LINK);
- X#endif
- X case(S_IFREG):
- X return(REGULAR);
- X case(S_IFDIR):
- X return(DIRECTORY);
- X case(S_IFCHR):
- X return(CHARACTER);
- X case(S_IFBLK):
- X return(BLOCK);
- X#if !defined(SYSV) || defined(sun)
- X case(S_IFSOCK):
- X return(SOCKET);
- X#endif
- X case(S_IFIFO):
- X return(FIFO);
- X default:
- X break;
- X }
- X
- X return(REGULAR); /* default is regular type */
- X
- X} /*** set_type ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: set_date
- X
- X Purpose: Create a date string for a file.
- X
- X Global variables:
- X
- X Name Examine/Modify/Use/Read/Write
- X ---- -----------------------------
- X curr_year X
- X
- X Return Codes:
- X
- X Code Reason
- X ---- ------
- X date_buf buffer where date string is stored
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- char *set_date(time_val)
- X /******* FORMAL PARAMETERS *******/
- X time_t time_val; /* binary time value */
- X
- X{ /*** set_date ***/
- X /******** LOCAL VARIABLES ********/
- struct tm *time_str; /* time structure */
- static char date_buf[DATE_MAX+1];
- static char *month[] =
- X{"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
- X
- X time_str = localtime(&time_val);
- X
- X if(time_str->tm_year == curr_year)
- X sprintf(date_buf,"%3s %2d %2d:%1d%1d",month[time_str->tm_mon],
- X time_str->tm_mday,time_str->tm_hour,time_str->tm_min/10,
- X time_str->tm_min%10);
- X else
- X sprintf(date_buf,"%3s %2d %4d",month[time_str->tm_mon],
- X time_str->tm_mday,time_str->tm_year + 1900);
- X
- X return(date_buf);
- X
- X} /*** set_date ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: padcpy
- X
- X Purpose: Copy a counted string, padding with spaces.
- 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 date_buf buffer where date string is stored
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- char *padcpy(dest,source,length)
- X /******** LOCAL VARIABLES ********/
- X char *dest, /* destination string */
- X *source; /* source string */
- X int length; /* length that destination should be */
- X
- X{ /*** padcpy ***/
- X
- X if(source != NULL && *source != '\0')
- X {
- X while(*source && length--) /* copy it */
- X *dest++ = *source++;
- X }
- X
- X while(length-- > 0) /* pad it */
- X *dest++ = ' ';
- X
- X *dest = '\0'; /* make it a string */
- X return(dest);
- X
- X} /*** padcpy ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: add_filetype
- X
- X Purpose: Set the filetype in an integer file mode.
- 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 prot new protection value
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- u_short add_filetype(type,prot)
- X /******* FORMAL PARAMETERS *******/
- X u_char type; /* type of file */
- X u_short prot; /* protection mode to work with */
- X
- X{ /*** add_filetype ***/
- X
- X
- X switch(type)
- X {
- X case(REGULAR):
- X prot |= S_IFREG;
- X break;
- X case(DIRECTORY):
- X prot |= S_IFDIR;
- X break;
- X case(CHARACTER):
- X prot |= S_IFCHR;
- X break;
- X case(BLOCK):
- X prot |= S_IFBLK;
- X break;
- X case(FIFO):
- X prot |= S_IFIFO;
- X break;
- X#if !defined(SYSV) || defined(sun)
- X case(SOCKET):
- X prot |= S_IFSOCK;
- X break;
- X case(LINK):
- X prot |= S_IFLNK;
- X break;
- X#endif
- X default:
- X prot |= S_IFREG;
- X break;
- X }
- X
- X return(prot);
- X
- X} /*** add_filetype ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: spawn
- X
- X Purpose: Fork off a process to let the user return to the shell.
- 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 SUCCESS
- X FAILURE
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- int spawn()
- X
- X{ /*** spawn ***/
- X /******** LOCAL VARIABLES ********/
- X char *tptr, /* temporary pointer */
- X *shell; /* pointer to the user's shell */
- X int child, /* pid of child process */
- X i; /* loop and return value */
- X#if !defined(SYSV) || defined(sun)
- union wait status;
- X#else
- X int status;
- X#endif
- X
- X
- X shell = getenv("SHELL"); /* get what shell to use */
- X
- X if(shell == NULL || *shell == '\0')
- X shell = DEFAULT_SHELL; /* user didn't have a SHELL variable */
- X
- X tptr = strrchr(shell,'/'); /* find last level of shell name */
- X
- X if(tptr == NULL)
- X tptr = shell;
- X else
- X tptr++;
- X
- X if((child = vfork()) == 0)
- X {
- X /* we're in the child */
- X
- X endwin(); /* make sure tty is reset */
- X execlp(shell,tptr,NULL); /* no return from this */
- X return(FAILURE); /* failure if we get here */
- X }
- X else if(child > 0)
- X {
- X /* we're in the parent; wait for the child to finish */
- X
- X while(((i = wait(&status)) != child) && i > 0)
- X ;
- X }
- X else
- X return(FAILURE); /* can't fork */
- X
- X return(SUCCESS);
- X
- X} /*** spawn ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: check_nlen
- X
- X Purpose: Check if a filename (as displayed) would be longer than
- X DISP_MAX. This info is useful in make_slot() when we are
- X deciding what has to be tagged.
- 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 count displayed length of filename
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- static u_short check_nlen(filename)
- X /******* FORMAL PARAMETERS *******/
- register char *filename; /* filename to be checked */
- X
- X{ /*** check_nlen ***/
- X /******** LOCAL VARIABLES ********/
- register u_short count; /* length of displayed filename */
- X
- X
- X count = 0;
- X
- X while(*filename)
- X {
- X if(!iscntrl(*filename))
- X count++;
- X else
- X count += 2;
- X
- X ++filename;
- X }
- X
- X return(count);
- X
- X} /*** check_nlen ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: strtcpy
- X
- X Purpose: Copy one string to another, translating control characters to
- X a two-character pair of ^ and the printable control character.
- 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 count displayed length of filename
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- int strtcpy(dest,source)
- X /******* FORMAL PARAMETERS *******/
- register char *dest, /* destination string */
- X *source; /* source string */
- X
- X{ /*** strtcpy ***/
- X /******** LOCAL VARIABLES ********/
- register int length; /* length of resulting string */
- X
- X
- X length = 0;
- X
- X while(*source)
- X {
- X if(iscntrl(*source))
- X {
- X *dest++ = '^';
- X *dest++ = *source++ + '@'; /* make it printable */
- X length += 2;
- X }
- X else
- X {
- X *dest++ = *source++;
- X ++length;
- X }
- X }
- X
- X *dest = '\0'; /* make it a string */
- X return(length);
- X
- X} /*** strtcpy ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: get_filemarks
- X
- X Purpose: Recreate the displayed names for all of the files in the
- X current directory so that they include the filemarks. This
- X is normally only done after the filemarks are selected from
- X the options menu.
- 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
- void get_filemarks(dirptr,num_file)
- X /******* FORMAL PARAMETERS *******/
- register ENT_DEF *dirptr; /* pointer to directory information */
- register short num_file; /* number of files in directory */
- X
- X{ /*** get_filemarks ***/
- X
- X while(num_file-- > 0)
- X {
- X strcpy(dirptr->scr_name,get_name(dirptr->filename,&dirptr->name_len));
- X dirptr++;
- X }
- X
- X return;
- X
- X} /*** get_filemarks ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: get_name
- X
- X Purpose: Create the filename that will be displayed in a slot, including
- X translating non-printable characters.
- X
- X Global variables:
- X
- X Name Examine/Modify/Use/Read/Write
- X ---- -----------------------------
- X args.filemarks X
- X
- X Return Codes:
- X
- X Code Reason
- X ---- ------
- X retptr pointer to displayed filename string
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- static char *get_name(filename,length,prot,type)
- X /******* FORMAL PARAMETERS *******/
- X char *filename; /* original filename */
- X u_short *length, /* length of filename minus padding */
- X prot; /* integer protection value */
- X u_char type; /* file type */
- X
- X{ /*** get_name ***/
- X /******** LOCAL VARIABLES ********/
- register char *tptr; /* temporary character pointer */
- register u_short i; /* loop and array index */
- static char newname[DISP_MAX+1]; /* where to store translated name */
- X
- X
- X i = 0;
- X tptr = newname;
- X
- X while((i < DNAME_MAX) && (*filename != '\0'))
- X {
- X if(*filename >= ' ')
- X {
- X *tptr = *filename;
- X tptr++;
- X filename++;
- X ++i;
- X }
- X else
- X {
- X *tptr++ = '^'; /* non-printable; translate it */
- X ++i;
- X
- X if(i < DNAME_MAX)
- X {
- X *tptr = *filename + '@';
- X ++i;
- X tptr++;
- X }
- X
- X filename++;
- X }
- X }
- X
- X /* pad the name with spaces */
- X
- X if(args.filemarks)
- X *tptr++ = filetype_char(prot,type);
- X else
- X *tptr++ = ' ';
- X
- X *length = ++i; /* count the filemark char */
- X
- X while(i++ < DISP_MAX)
- X *tptr++ = ' ';
- X
- X *tptr = '\0'; /* make sure it's a string */
- X return(newname);
- X
- X} /*** get_name ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: filetype_char
- X
- X Purpose: Determine what character should be appended to the filename
- X for the -F option.
- 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 retval filetype character
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- u_char filetype_char(prot,type)
- X /******* FORMAL PARAMETERS *******/
- X u_short prot; /* file protection word */
- X u_char type; /* type of file */
- X
- X{ /*** filetype_char ***/
- X /******** LOCAL VARIABLES ********/
- X u_char retval; /* file type char (for -F) */
- X
- X
- X switch(type)
- X {
- X case(DIRECTORY):
- X
- X retval = '/';
- X break;
- X
- X case(SOCKET):
- X
- X retval = '=';
- X break;
- X
- X#if !defined(SYSV) || defined(sun)
- X case(LINK):
- X
- X retval = '@';
- X break;
- X#endif
- X
- X case(REGULAR):
- X
- X /* determine if the file is executable */
- X
- X if(prot & (S_IEXEC | (S_IEXEC >> 3) | (S_IEXEC >> 6)))
- X retval = '*';
- X else
- X retval = ' ';
- X
- X break;
- X
- X default:
- X
- X retval = ' ';
- X break;
- X }
- X
- X return(retval);
- X
- X} /*** filetype_char ****/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: squeeze_str
- X
- X Purpose: Squeeze the whitespace characters out of a string
- 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
- void squeeze_str(str)
- X /******* FORMAL PARAMETERS *******/
- register char *str; /* string to be squeezed */
- X
- X{ /*** squeeze_str ***/
- X /******** LOCAL VARIABLES ********/
- register char *ptr; /* temporary pointer */
- X
- X
- X ptr = str;
- X
- X while(*ptr)
- X {
- X if(!isspace(*ptr))
- X *str++ = *ptr++;
- X else
- X ptr++;
- X }
- X
- X *str = '\0'; /* make sure it's a string */
- X return;
- X
- X} /*** squeeze_str ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: follow_link
- X
- X Purpose: Given a filename that is a symbolic link, try to find out what
- X it points to.
- 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 REGULAR
- X DIRECTORY
- X CHARACTER
- X BLOCK
- X LINK
- X SOCKET
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- int follow_link(linkname)
- X /******* FORMAL PARAMETERS *******/
- X char *linkname; /* link to follow */
- X
- X{ /*** follow_link ***/
- X /******** LOCAL VARIABLES ********/
- struct stat statbuf; /* for stat'ing the file */
- X
- X
- X if(stat(linkname,&statbuf) == -1)
- X return(FAILURE);
- X
- X switch(statbuf.st_mode & S_IFMT)
- X {
- X case(S_IFREG):
- X return(REGULAR);
- X case(S_IFDIR):
- X return(DIRECTORY);
- X case(S_IFCHR):
- X return(CHARACTER);
- X case(S_IFBLK):
- X return(BLOCK);
- X#if !defined(SYSV) || defined(sun)
- X case(S_IFLNK):
- X return(LINK);
- X case(S_IFSOCK):
- X return(SOCKET);
- X#endif
- X default:
- X break;
- X }
- X
- X return(REGULAR);
- X
- X} /*** follow_link ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: get_bnum
- X
- X Purpose: Get the number of blocks that a file occupies and return it.
- 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 kbytes(...) number of blocks the file occupies
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- long get_bnum(filename)
- X /******* FORMAL PARAMETERS *******/
- X char *filename; /* file to be examined */
- X
- X{ /*** get_bnum ***/
- X /******** LOCAL VARIABLES ********/
- struct stat statbuf; /* for doing a stat */
- X
- X
- X if(stat(filename,&statbuf) != 0)
- X return(0L);
- X
- X#if !defined(SYSV) || defined(sun)
- X return((long) statbuf.st_blocks);
- X#else
- X return((long) statbuf.st_size);
- X#endif
- X
- X} /*** get_bnum ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: cont_after_stop
- X
- X Purpose: Signal hander called when restarting after being suspended
- X
- X Global variables:
- X
- X Name Examine/Modify/Use/Read/Write
- X ---- -----------------------------
- X main_win X
- X spec_win X
- X stat_win X
- X
- X Return Codes:
- X
- X Code Reason
- X ---- ------
- X none
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- void cont_after_stop()
- X
- X{ /*** cont_after_stop ***/
- X
- X /* redraw the screen after resuming */
- X
- X touchwin(spec_win);
- X touchwin(main_win);
- X touchwin(stat_win);
- X wrefresh(spec_win);
- X wrefresh(main_win);
- X wrefresh(stat_win);
- X return;
- X
- X} /*** cont_after_stop ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: cat
- X
- X Purpose: Concatenate strings into one string.
- 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 retval pointer to destination string
- X NULL null string pointer; returned when
- X no arguments are passed
- X
- X Termination Codes:
- X
- X Code Reason
- X ---- ------
- X none
- X
- X Description of Linkage:
- X
- X char *rc,
- X *cat();
- X
- X rc = cat(num_args,dest,source1,source2,...sourcen);
- X
- X where dest is a pointer to a character string allocated by
- X the caller and is large enough to hold the resulting string
- X and source1, source2,...sourcen are pointers to character
- X strings to be concatenated.
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- char *cat(va_alist)
- X /******* FORMAL PARAMETERS *******/
- X va_dcl /* variable-length parameter list */
- X
- X{ /*** cat ***/
- X /******** LOCAL VARIABLES ********/
- static char *dest, /* pointer to destination string */
- X *source; /* pointer to current source string */
- static char *retval; /* to save pointer to destination */
- static int count; /* number of arguments passed */
- static va_list incrmtr; /* argument list incrementor */
- X
- X
- X va_start(incrmtr); /* begin everything.... */
- X
- X count = va_arg(incrmtr,int); /* get number of arguments */
- X
- X if(count <= 1) /* enough arguments? */
- X return(NULL); /* nope, get out of here... */
- X
- X dest = va_arg(incrmtr,char*); /* get the destination pointer */
- X retval = dest; /* save pointer to destination */
- X
- X --count; /* subtract for first argument */
- X
- X while(count > 0) /* process all of the source strings */
- X {
- X source = va_arg(incrmtr,char*); /* get the next argument */
- X while(*dest++ = *source++) /* cat the source to the destination */
- X ;
- X
- X dest--; /* back over the null character */
- X count--;
- X }
- X
- X *dest = '\0'; /* terminate the destination */
- X va_end(incrmtr); /* end varargs session */
- X
- X return(retval); /* return pointer to destination */
- X
- X} /*** cat ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: strindex
- X
- X Purpose: Return the position of one string in another.
- 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 -1 key not found in str or key is a null
- X pointer or str is a null pointer
- X offset offset into str where key is located
- X
- X Termination Codes:
- X
- X Code Reason
- X ---- ------
- X none
- X
- X Description of Linkage:
- X
- X int strindex();
- X rc = strindex(str,key);
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- int strindex(str,key)
- X /******* FORMAL PARAMETERS *******/
- register char *str, /* string to be searched */
- X *key; /* string to be searched for */
- X
- X{ /*** strindex ***/
- X /******** LOCAL VARIABLES ********/
- register int i, /* primary pointer to str */
- X j, /* secondary pointer to str for com- */
- X /* parison */
- X k; /* pointer to key for comparison */
- X
- X
- X if(str == NULL || key == NULL || *str == '\0' || *key == '\0')
- X return(-1);
- X
- X i = 0;
- X while(*(str+i) != '\0')
- X {
- X j = i;
- X k = 0;
- X
- X /* look for a match */
- X
- X while((*(str+j) == *(key+k)) && (*(str+j) != '\0') && (*(key+k) != '\0'))
- X {
- X ++j;
- X ++k;
- X }
- X
- X if(*(key+k) == '\0')
- X return(i); /* key was found */
- X else if(*(str+j) == '\0')
- X return(-1); /* key was not found */
- X
- X ++i; /* not sure yet; keep trying... */
- X }
- X
- X /* if we get to here, the key was not found */
- X
- X return(-1);
- X
- X} /*** strindex ***/
- X
- X/*******************************************************************************
- X********************************************************************************
- X
- X Function: rename
- X
- X Purpose: Fake a rename function for System V machines
- 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 -1 key not found in str or key is a null
- X pointer or str is a null pointer
- X offset offset into str where key is located
- X
- X Termination Codes:
- X
- X Code Reason
- X ---- ------
- X none
- X
- X********************************************************************************
- X*******************************************************************************/
- X
- X#if defined(SYSV) && !defined(sun)
- X
- int rename(source,dest)
- X /******* FORMAL PARAMETERS *******/
- X char *source, /* file to be renamed */ *dest; /* what to call it */
- X
- X{ /*** rename ***/
- X
- X if(link(source,dest))
- X return(-1);
- X
- X if(unlink(source))
- X return(-1);
- X
- X return(0);
- X
- X} /*** rename ***/
- X
- X#endif
- END_OF_FILE
- if test 62395 -ne `wc -c <'misc.c'`; then
- echo shar: \"'misc.c'\" unpacked with wrong size!
- fi
- # end of 'misc.c'
- fi
- echo shar: End of archive 5 \(of 7\).
- cp /dev/null ark5isdone
- 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
-