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: Associate commands with individual file entries or cancel
- all commands for a file.
-
- Arguments: See individual routines
-
- External variables: See individual routines
-
- External functions:
-
- Defined: mark_text, mark_delete, mark_copy_ren, mark_protect,
- mark_group, mark_owner, mark_rename, mark_cancel,
- mark_repeat
-
- Called: new_comm, add_filetype, prot_str_to_val, prompt_getstr,
- free_comstr, squeeze_str
-
- 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 */
- /* */
- /******************************************************************************/
-
- #include <ctype.h>
- #include <math.h>
- #include <malloc.h>
- #ifdef ultrix
- #include <cursesX.h>
- #else
- #include <curses.h>
- #endif
- #include <string.h>
- #include <grp.h>
- #include <pwd.h>
- #include "maint.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 main_rows;
-
- #ifndef ultrix
- extern void free();
- #endif
-
- extern COM_DEF *new_comm();
-
- extern u_short add_filetype();
-
- extern short prot_str_to_val();
-
- extern void prompt_getstr(),
- squeeze_str(),
- free_comstr();
-
- int mark_text(),
- mark_delete(),
- mark_copy_ren(),
- mark_protect(),
- mark_group(),
- mark_owner(),
- mark_rename(),
- mark_repeat();
-
- void mark_cancel();
-
- /******************************************************************************/
- /* */
- /* 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 short prot_abs_to_val();
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: mark_delete
-
- Purpose: The selected file is to be deleted; allocate memory for the
- command structure (if necessary), link it to the entry, and
- set up the command structure so that the file can be deleted.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- none
-
- Return Codes:
-
- Code Reason
- ---- ------
- 0 completed successfully
- -1 problems allocating memory
-
- Termination Codes:
-
- Code Reason
- ---- ------
- SUCCESS
- FAILURE
-
- ********************************************************************************
- *******************************************************************************/
-
- int mark_delete(ent)
- /******* FORMAL PARAMETERS *******/
- register ENT_DEF *ent; /* entry for file to be deleted */
-
- { /*** mark_delete ***/
- /******** LOCAL VARIABLES ********/
- register COM_DEF *tptr; /* temporary command structure ptr */
-
-
- /* do we need a command structure or does the file already have one? */
-
- if(ent->command == NULL)
- {
- /* we need command structure; allocate it and link it to the file entry */
-
- tptr = new_comm();
-
- if(tptr == NULL)
- return(FAILURE); /* problems allocating memory */
-
- ent->command = tptr; /* link it to the file entry */
- }
- else
- tptr = ent->command; /* else use the one already there */
-
- tptr->comm_del = 1;
-
- /* deallocate all of the memory that might have been used for things
- * like renaming the file and for a text descriptor
- */
-
- if(tptr->ren_name != NULL) /* need to deallocate rename name? */
- {
-
- free(tptr->ren_name);
- tptr->comm_ren = 0; /* make sure to shut of renaming */
- tptr->ren_name = NULL; /* reset the rename name stuff */
- tptr->ren_len = 0;
- }
-
- if(tptr->text != NULL) /* need to deallocate text descrip? */
- {
- free(tptr->text);
- tptr->comm_text = 0; /* make sure to shut off text descrip */
- tptr->text = NULL; /* reset the text descriptor stuff */
- tptr->text_len = 0;
- }
-
- return(SUCCESS); /* no problem..... */
-
- } /*** mark_delete ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: mark_copy_ren
-
- Purpose: The selected file is to be copied or renamed; allocate the
- memory for the command structure (if necessary), link it to
- the file entry, and set the command in the command structure.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- none
-
- Return Codes:
-
- Code Reason
- ---- ------
- 0 completed successfully
- -1 problems allocating memory
-
- Termination Codes:
-
- Code Reason
- ---- ------
- SUCCESS
- CANT_ALLOCATE cannot allocate necessary memory
-
- ********************************************************************************
- *******************************************************************************/
-
- int mark_copy_ren(window,ent,command,prev_str,repeat)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* where to read/write */
- register ENT_DEF *ent; /* entry for file to be deleted */
- u_short command; /* either RENAME or COPY */
- char *prev_str; /* string to use from mark_repeat() */
- u_short repeat; /* set if called from mark_repeat() */
-
- { /*** mark_copy_ren ***/
- /******** LOCAL VARIABLES ********/
- register COM_DEF *tptr; /* temporary command structure ptr */
- char *dest_ptr; /* temporary character pointer */
- int length; /* length of string read in */
- char buf[FULL_SPEC_MAX+1], /* array for new filename */
- prompt[PROMPT_MAX+1]; /* prompt array */
-
-
- if(!repeat)
- {
- buf[0] = '\0'; /* reset the buffer */
-
- /* set up the prompt for the filename */
-
- if(command == COPY)
- strcpy(prompt,"Copy to: ");
- else
- strcpy(prompt,"Rename to: ");
-
- /* read in the file spec */
-
- prompt_getstr(window,prompt,buf,main_rows,FULL_SPEC_MAX);
-
- /* was anything specified for the filename? */
-
- if(*buf == '\0')
- return(SUCCESS);
- }
- else
- strcpy(buf,prev_str); /* use string from mark_repeat() */
-
- length = strlen(buf);
-
- /* ok, we have a filename; now determine if we need to allocate a command
- * structure for this file or if one already exists from a previous command
- */
-
- if(ent->command == NULL)
- {
- /* we need command structure; allocate it and link it to the file entry */
-
- tptr = new_comm();
-
- if(tptr == NULL)
- exit(CANT_ALLOCATE); /* problems allocating memory */
-
- ent->command = tptr; /* link it to the file entry */
- }
- else
- {
- tptr = ent->command; /* else use the one already there */
- }
-
- /* is there already enough room to put the new name in a memory pool? if
- * there is, just reuse the memory we already have; otherwise, free up
- * the memory (if there is any) and allocate some to hold the new name
- */
-
- if(command == COPY)
- {
- if(length > tptr->copy_len)
- {
- /* nope, we need more memory; first free the old memory if there
- * was any
- */
-
- if(tptr->copy_len != 0)
- free(tptr->copy_name);
-
- /* now allocate some new memory to hold the longer filename
- * AND the nul character
- */
-
- tptr->copy_name = (char *) malloc((u_int) (length + 1));
-
- if(tptr->copy_name == NULL)
- {
- exit(CANT_ALLOCATE);
- }
-
- tptr->copy_len = length; /* save the length of the memory */
- }
-
- dest_ptr = tptr->copy_name; /* get where to copy the filename to */
- tptr->comm_copy = 1; /* set the command in the structure */
- }
- else
- {
- if(length > tptr->ren_len)
- {
- /* nope, we need more memory; first free the old memory if there
- * was any
- */
-
- if(tptr->ren_len != 0)
- free(tptr->ren_name);
-
- /* now allocate some new memory to hold the longer filename
- * AND the nul character
- */
-
- tptr->ren_name = (char *) malloc((u_int) (length + 1));
-
- if(tptr->ren_name == NULL)
- exit(CANT_ALLOCATE);
-
- tptr->ren_len = length; /* save the length of the memory */
- }
-
- dest_ptr = tptr->ren_name; /* get where to copy the filename to */
- tptr->comm_ren = TRUE; /* set the command in the structure */
- tptr->comm_del = FALSE; /* rename implies no delete */
- }
-
- strcpy(dest_ptr,buf); /* copy it to the right place */
-
- return(SUCCESS);
-
- } /*** mark_copy_ren ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: mark_text
-
- Purpose: The selected file is to get a text descriptor; allocate the
- memory for the command structure (if necessary), link it to
- the file entry, and set the command in the command structure.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- none
-
- Return Codes:
-
- Code Reason
- ---- ------
- SUCCESS
- FAILURE
-
- Termination Codes:
-
- Code Reason
- ---- ------
- SUCCESS
- FAILURE
-
- ********************************************************************************
- *******************************************************************************/
-
- int mark_text(window,ent,text,repeat)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* where to read/write */
- register ENT_DEF *ent; /* entry for file to be deleted */
- char *text; /* from mark_repeat */
- u_short repeat; /* set if called by mark_repeat() */
-
- { /*** mark_text ***/
- /******** LOCAL VARIABLES ********/
- register COM_DEF *tptr; /* temporary command structure ptr */
- int length; /* length of string read in */
- char buf[TEXT_MAX+1]; /* array for text descriptor */
-
-
- buf[0] = '\0'; /* reset the buffer */
-
- /* first put the character that marks the maximum number of characters
- * that can be specified for the text descriptor
- */
-
- if(!repeat)
- prompt_getstr(window,"Text descriptor: ",buf,main_rows,TEXT_MAX);
- else
- strcpy(buf,text); /* use text descrip from mark_repeat */
-
- length = strlen(buf); /* make sure it's not too long */
-
- /* ok, we have the text descriptor; determine if we need to allocate a
- * command structure for this file or if one already exists from a
- * previous command
- */
-
- if(ent->command == NULL)
- {
- /* we need command structure; allocate it and link it to the file entry */
-
- tptr = new_comm();
-
- if(tptr == NULL)
- return(FAILURE); /* problems allocating memory */
-
- ent->command = tptr; /* link it to the file entry */
- }
- else
- tptr = ent->command; /* else use the one already there */
-
- /* is there already enough room to store the text descriptor?
- * if there is, just reuse the memory we already have; otherwise,
- * allocate some new memory
- */
-
- if(length > tptr->text_len)
- {
- /* we need more memory; first free up any old memory if there was any */
-
- if(tptr->text_len != 0)
- free(tptr->text);
-
- /* allocate some memory to hold the text descriptor AND the null char */
-
- tptr->text = (char *) malloc((u_int) (length + 1));
-
- if(tptr->text == NULL)
- exit(CANT_ALLOCATE);
-
- tptr->text_len = length; /* we have a new length */
- }
-
- if(length)
- strcpy(tptr->text,buf); /* copy it to its resting place */
- else
- tptr->text = NULL;
-
- /* set the command in the command structure */
-
- tptr->comm_text = TRUE;
- tptr->comm_del = FALSE; /* text descriptor implies no delete */
-
- return(SUCCESS);
-
- } /*** mark_text ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: mark_protect
-
- Purpose: The selected file is to be reprotected; allocate the memory
- for the command structure (if necessary), link it to the file
- entry, and set the command in the command structure.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- main_rows X
-
- Return Codes:
-
- Code Reason
- ---- ------
- SUCCESS
- FAILURE
-
- ********************************************************************************
- *******************************************************************************/
-
- int mark_protect(window,ent,prot,repeat)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* where to read/write */
- register ENT_DEF *ent; /* entry for file to be deleted */
- u_short prot, /* from mark_repeat() */
- repeat; /* set if called from mark_repeat() */
-
- { /*** mark_protect ***/
- /******** LOCAL VARIABLES ********/
- register COM_DEF *tptr; /* temporary command structure ptr */
- u_short prot_val; /* temporary protection value */
- char buf[PROT_INP_MAX+1]; /* array for protection string */
-
-
- if(!repeat)
- {
- buf[0] = '\0'; /* initialize input buffer */
-
- /* prompt for and read in the protection string */
-
- prompt_getstr(window,"Protection: ",buf,main_rows,PROT_INP_MAX);
-
- /* if nothing was specified for the protection string, just return from
- * right here
- */
-
- if(*buf == '\0')
- return(SUCCESS);
-
- squeeze_str(buf); /* squeeze the blanks out */
-
- /* now determine if the protection string specified is valid */
-
- if(prot_str_to_val(buf,&prot_val) == FAILURE)
- {
- /* maybe it's an absolute number; try to convert it */
-
- if(prot_abs_to_val(buf,&prot_val) == FAILURE)
- return(FAILURE); /* invalid protection string */
- }
- }
- else
- prot_val = prot; /* use value from mark_repeat() */
-
- /* at this point, the protection string has been edited and is considered
- * valid; get the integer value for the protection string and store it in
- * in the command structure; first, do we need a command structure or does
- * the file have one from a previous command?
- */
-
- if(ent->command == NULL)
- {
- /* we need command structure; allocate it and link it to the file entry */
-
- tptr = new_comm();
-
- if(tptr == NULL)
- return(-1); /* problems allocating memory */
-
- ent->command = tptr; /* link it to the file entry */
- }
- else
- tptr = ent->command; /* else use the one already there */
-
- tptr->comm_prot = 1; /* set the command in the structure */
- tptr->prot = add_filetype(ent->type,prot_val);
- tptr->comm_del = 0; /* protection implies no delete */
-
- return(SUCCESS); /* fine......... */
-
- } /*** mark_protect ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: mark_cancel
-
- Purpose: Cancel all commands for the specified file entry and deallocate
- the command structure for the file.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- none
-
- Return Codes:
-
- Code Reason
- ---- ------
- 0 completed successfully
- -1 problems allocating memory
-
- ********************************************************************************
- *******************************************************************************/
-
- void mark_cancel(ent)
- /******* FORMAL PARAMETERS *******/
- ENT_DEF *ent; /* file entry pointer */
-
- { /*** mark_cancel ***/
-
-
- if(ent->command != NULL)
- {
- /* first free up any memory that might be holding character strings */
-
- free_comstr(ent->command);
-
- ent->command = NULL; /* no more structure for file entry */
- }
-
- return;
-
- } /*** mark_cancel ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: mark_repeat
-
- Purpose: Repeat the last command on the current file.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- none
-
- Return Codes:
-
- Code Reason
- ---- ------
- SUCCESS
- FAILURE
-
- ********************************************************************************
- *******************************************************************************/
-
- int mark_repeat(window,ent,prev_ptr,command)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* needed to pass along */
- ENT_DEF *ent, /* what is to be marked */
- *prev_ptr; /* where to find previous mark */
- u_short command; /* command to be used */
-
- { /*** mark_repeat ***/
- /******** LOCAL VARIABLES ********/
- COM_DEF *comm_ptr; /* previous entry's commands */
- int retval; /* return value */
-
-
- comm_ptr = prev_ptr->command;
-
- switch(command)
- {
- case(DELETE):
-
- retval = mark_delete(ent);
- break;
-
- case(PROTECT):
-
- retval = mark_protect(window,ent,comm_ptr->prot,TRUE);
- break;
-
- case(RENAME):
-
- retval = mark_copy_ren(window,ent,RENAME,comm_ptr->ren_name,TRUE);
- break;
-
- case(COPY):
-
- retval = mark_copy_ren(window,ent,COPY,comm_ptr->copy_name,TRUE);
- break;
-
- case(OWNER):
-
- retval = mark_owner(window,ent,comm_ptr->owner,TRUE);
- break;
-
- case(GROUP):
-
- retval = mark_group(window,ent,comm_ptr->group,TRUE);
- break;
-
- case(TEXT):
-
- retval = mark_text(window,ent,comm_ptr->text,TRUE);
- break;
-
- default:
- break;
- }
-
- return(retval);
-
- } /*** mark_repeat ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: mark_group
-
- Purpose: Prompt for the new group of the file and look it up in the
- group file. If it doesn't exist, just use the numeric version.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- main_rows X
-
- Return Codes:
-
- Code Reason
- ---- ------
- SUCCESS
- FAILURE
- BAD_GROUP invalid group specified
-
- ********************************************************************************
- *******************************************************************************/
-
- int mark_group(window,ent,group,repeat)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* where to read/write */
- ENT_DEF *ent; /* file entry pointer */
- gid_t group; /* from mark_repeat() */
- u_short repeat; /* set if called by mark_repeat() */
-
- { /*** mark_group ***/
- /******** LOCAL VARIABLES ********/
- struct group *gid_ptr; /* from getgrnam() */
- COM_DEF *tptr; /* temporary pointer */
- char *tptr2; /* for checking for digit string */
- gid_t gid; /* temporary group id holder */
- char buf[ID_STR_MAX+1]; /* for getting group string */
-
-
- if(!repeat)
- {
- prompt_getstr(window,"Change group to: ",buf,main_rows,ID_STR_MAX);
-
- if(*buf == '\0')
- return(SUCCESS);
-
- /* see if the group is valid */
-
- gid_ptr = getgrnam(buf);
-
- if(gid_ptr == NULL)
- {
- /* not found, try to use numeric value */
-
- tptr2 = buf;
-
- /* skip leading blanks first */
-
- while(isspace(*tptr2))
- ++tptr2;
-
- while(*tptr2 && isdigit(*tptr2))
- ++tptr2;
-
- if(*tptr2 != '\0')
- return(BAD_GROUP);
-
- /* it's ok; change it to a integer and store it */
-
- gid = (gid_t) atoi(buf);
- }
- else
- gid = gid_ptr->gr_gid; /* found; use it */
- }
- else
- gid = group; /* use group from mark_repeat() */
-
- if(ent->command == NULL)
- {
- /* we need command structure; allocate it and link it to the file entry */
-
- tptr = new_comm();
-
- if(tptr == NULL)
- return(FAILURE); /* problems allocating memory */
-
- ent->command = tptr; /* link it to the file entry */
- }
- else
- tptr = ent->command; /* else use the one already there */
-
- tptr->comm_grp = 1;
- tptr->group = gid;
- tptr->comm_del = 0; /* Group implies !Delete */
-
- return(SUCCESS);
-
- } /*** mark_group ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: mark_owner
-
- Purpose: Prompt for the new owner of the file and look it up in the
- passwd file. If it doesn't exist, just use the numeric version.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- main_rows X
-
- Return Codes:
-
- Code Reason
- ---- ------
- SUCCESS
- FAILURE
- BAD_OWNER invalid owner specified
-
- ********************************************************************************
- *******************************************************************************/
-
- int mark_owner(window,ent,owner,repeat)
- /******* FORMAL PARAMETERS *******/
- WINDOW *window; /* where to read/write */
- ENT_DEF *ent; /* file entry pointer */
- uid_t owner; /* from mark_repeat() */
- u_short repeat; /* set if called by mark_repeat() */
-
- { /*** mark_owner ***/
- /******** LOCAL VARIABLES ********/
- struct passwd *uid_ptr; /* from getpwnam() */
- COM_DEF *tptr; /* temporary pointer */
- char *tptr2; /* for checking for digit string */
- uid_t uid; /* temporary group id holder */
- char buf[ID_STR_MAX+1]; /* for getting group string */
-
-
- if(!repeat)
- {
- prompt_getstr(window,"Change owner to: ",buf,main_rows,ID_STR_MAX);
-
- if(*buf == '\0')
- return(SUCCESS);
-
- /* see if the owner is valid */
-
- uid_ptr = getpwnam(buf);
-
- if(uid_ptr == NULL)
- {
- /* not found, try to use numeric value */
-
- tptr2 = buf;
-
- /* skip leading blanks first */
-
- while(isspace(*tptr2))
- ++tptr2;
-
- while(*tptr2 && isdigit(*tptr2))
- ++tptr2;
-
- if(*tptr2 != '\0')
- return(BAD_OWNER);
-
- /* it's ok; change it to a integer and store it */
-
- uid = (uid_t) atoi(buf);
- }
- else
- uid = uid_ptr->pw_uid; /* found; use it */
- }
- else
- uid = owner; /* use owner from mark_repeat() */
-
- if(ent->command == NULL)
- {
- /* we need command structure; allocate it and link it to the file entry */
-
- tptr = new_comm();
-
- if(tptr == NULL)
- return(FAILURE); /* problems allocating memory */
-
- ent->command = tptr; /* link it to the file entry */
- }
- else
- tptr = ent->command; /* else use the one already there */
-
- tptr->comm_own = 1;
- tptr->owner = uid;
- tptr->comm_del = 0;
-
- return(SUCCESS);
-
- } /*** mark_owner ***/
-
- /*******************************************************************************
- ********************************************************************************
-
- Function: prot_abs_to_val
-
- Purpose: See if a string is an absolute protection mode and calculate
- the integer value if possible.
-
- Global variables:
-
- Name Examine/Modify/Use/Read/Write
- ---- -----------------------------
- none
-
- Return Codes:
-
- Code Reason
- ---- ------
- SUCCESS
- FAILURE
-
- ********************************************************************************
- *******************************************************************************/
-
- static short prot_abs_to_val(buffer,mode)
- /******* FORMAL PARAMETERS *******/
- register char *buffer; /* mode string */
- u_short *mode; /* where to put the mode value */
-
- { /*** prot_abs_to_val ***/
- /******** LOCAL VARIABLES ********/
- register int temp; /* temporary mode holder */
-
-
- temp = 0;
-
- while(*buffer >= '0' && *buffer <= '7')
- {
- temp = (temp << 3) + (*buffer - '0');
- ++buffer;
- }
-
- while(isspace(*buffer)) /* skip any trailing whitespace */
- ++buffer;
-
- if(*buffer != '\0')
- return(FAILURE);
-
- *mode = temp;
- return(SUCCESS);
-
- } /*** prot_abs_to_val ***/
-