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