home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume26
/
maint
/
part03
/
text.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-13
|
20KB
|
652 lines
/******************************************************************************
*******************************************************************************
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: Routines for dealing with text descriptors.
Arguments: See individual routines
External variables: See individual routines
External functions:
Defined: create_text, put_text, read_text_des, text_match,
text_search
Called: clear_mess, get_name, get_pool_mem, prompt_getstr,
put_pool, strindex
Files accessed:
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 <stdio.h>
#ifdef ultrix
#include <cursesX.h>
#else
#include <curses.h>
#endif
#include <string.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;
extern char *get_pool_mem();
extern int strindex();
extern void put_pool(),
prompt_getstr(),
clear_mess(),
*get_name();
char *text_search(),
*text_match();
int read_text_des(),
create_text();
void put_text();
/******************************************************************************/
/* */
/* 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 */
/* */
/******************************************************************************/
/*******************************************************************************
********************************************************************************
Function: read_text_des
Purpose: Attempt to read in the text descriptors from the text des-
criptor file for the current directory.
Global variables:
Name Examine/Modify/Use/Read/Write
---- -----------------------------
none
Return Codes:
Code Reason
---- ------
NO_FILE file does not exist
CANT_OPEN cannot open MAINT.TDF file
BAD_FILE bad text descriptor file
0 text descriptor file successfully read
Termination Codes:
Code Reason
---- ------
none
********************************************************************************
*******************************************************************************/
int read_text_des(dirptr,curr_pool,dir_text,pool_length,num_file)
/******* FORMAL PARAMETERS *******/
register ENT_DEF *dirptr; /* pointer to directory entries */
POOL_DEF **curr_pool; /* pointer to pointer to current pool */
char **dir_text; /* directory text descriptor array */
size_t pool_length; /* length of pool to allocate */
short num_file; /* number of files in directory */
{ /*** read_text_des ***/
/******** LOCAL VARIABLES ********/
FILE *fptr; /* text file pointer */
ENT_DEF *currptr; /* current entry for searching */
int length; /* length of string */
char *tptr, /* temporary character pointer */
*status, /* return code status holder */
*temp,
text_buf[TEXT_REC_MAX+10];
/* open the text descriptor file */
fptr = fopen(TEXT_FILE,"r");
if(fptr == NULL)
return(NO_FILE); /* no problem; just no file */
/* get the first record; this is the text descriptor for the directory;
* the format for this record is
* >>><text descriptor for directory>
*/
status = fgets(text_buf,TEXT_REC_MAX+1,fptr);
if(status == NULL)
{
*dir_text = NULL;
fclose(fptr);
return(CANT_OPEN);
}
/* make sure this record is in the right form */
if(strindex(text_buf,">>>") != 0)
{
/* close the text descriptor file */
fclose(fptr);
return(BAD_FILE);
}
/* store this in the memory pools and set the dir_text pointer to point
* to it
*/
length = strlen(text_buf);
text_buf[length - 1] = '\0'; /* lop off the \n */
put_pool(dir_text,curr_pool,&text_buf[3],strlen(&text_buf[3]),pool_length);
/* skip the comment lines in the text descriptor file */
status = fgets(text_buf,TEXT_REC_MAX+1,fptr);
while(status != NULL && text_buf[0] == '>')
status = fgets(text_buf,TEXT_REC_MAX+1,fptr);
if(status == NULL)
{
fclose(fptr);
return(SUCCESS); /* end-of-file here.... */
}
/* now get each text descriptor record and match it up with a filename */
/* set the current file entry pointer to actually pointer to one entry
* BEFORE the current entry; it will be updated inside text_search to
* point to the correct entry; this is done so that text_search can be
* more general
*/
currptr = dirptr - 1; /* set where we start to look */
while(status != NULL)
{
/* search for a match with the filename in the text descriptor record */
length = strlen(text_buf);
text_buf[length - 1] = '\0';
if((tptr = text_search(dirptr,&currptr,text_buf,num_file)) != NULL)
{
/* match; store the text descriptor in a memory pool */
/* put_pool(&(currptr->text),curr_pool,tptr,(size_t) strlen(tptr),
pool_length);*/
put_pool(&temp,curr_pool,tptr,(size_t) strlen(tptr),
pool_length);
currptr->text = temp;
}
status = fgets(text_buf,TEXT_REC_MAX+1,fptr);
}
fclose(fptr);
return(SUCCESS); /* everything done */
} /*** read_text_des ***/
/*******************************************************************************
********************************************************************************
Function: text_search
Purpose: Search the directory entries for a match with the current
text descriptor record. If one is found, return a pointer
to the actual text of the text descriptor and update the
current directory entry pointer to point to the NEXT entry
to check for a text descriptor match.
Global variables:
Name Examine/Modify/Use/Read/Write
---- -----------------------------
none
Return Codes:
Code Reason
---- ------
retval pointer to actual text of text descriptor
NULL no match for text descriptor
Termination Codes:
Code Reason
---- ------
none
********************************************************************************
*******************************************************************************/
char *text_search(dirptr,currptr,text_rec,num_file)
/******* FORMAL PARAMETERS *******/
ENT_DEF *dirptr, /* pointer to all directory entries */
**currptr; /* pointer to current directory entry */
char *text_rec; /* current text descriptor record */
short num_file; /* number of files in directory */
{ /*** text_search ***/
/******** LOCAL VARIABLES ********/
register ENT_DEF *ptr; /* current file entry pointer */
ENT_DEF *origptr; /* original directory pointer */
char *retval; /* return value */
u_long curr_index; /* index value for setting pointer */
/* get pointer to directory that we need; this is the one following
* (modulo the number of files in the directory) the entry that we
* were on the last time through
*/
curr_index = *currptr - dirptr; /* get current entry index */
curr_index = (curr_index + 1L) % (u_long) num_file;
ptr = dirptr + curr_index; /* get pointer to the NEW entry */
/* first check to see if we have a match with the current entry */
if((retval = text_match(ptr->filename,text_rec)) != NULL)
{
/* we have a match; return the pointer to the beginning of the
* actual text of the text descriptor AND update the currptr
* return value to point to the next entry so that the next time
* this routine is called, we can start up one after where we
* left off here
*/
*currptr = ptr; /* return pointer to current entry */
return(retval); /* match.... */
}
/* no match with the current entry; search the entries until 1) we find a
* a match, or until we have examined all of the entries
*/
origptr = ptr; /* save where we are right now */
curr_index = (curr_index + 1L) % (u_long) num_file;
ptr = dirptr + curr_index;
while(ptr != origptr) /* until we are back where we started */
{
/* check for a match */
if((retval = text_match(ptr->filename,text_rec)) != NULL)
{
/* we have a match; return the pointer to the beginning of the
* actual text of the text descriptor AND update the currptr
* return value to point to the current directory entry so that
* we know where we left off last time through
*/
*currptr = ptr;
return(retval);
}
/* update the current entry pointer to point to the next entry */
curr_index = (curr_index + 1L) % (u_long) num_file;
ptr = dirptr + curr_index;
}
return(NULL); /* no match for this text descriptor */
} /*** text_search ***/
/*******************************************************************************
********************************************************************************
Function: text_match
Purpose: Determine if a text descriptor record is the correct one
for a file entry.
Global variables:
Name Examine/Modify/Use/Read/Write
---- -----------------------------
none
Return Codes:
Code Reason
---- ------
NULL no match for text descriptor record
text_rec + 1L pointer to beginning of text descriptor part
of the record
Termination Codes:
Code Reason
---- ------
none
********************************************************************************
*******************************************************************************/
char *text_match(filename,text_rec)
/******* FORMAL PARAMETERS *******/
register char *filename, /* filename to look for */
*text_rec; /* current text descriptor record */
{ /*** text_match ***/
while((*filename == *text_rec) && (*filename != '\0'))
{
filename++;
text_rec++;
}
/* now check to see if we had a match */
if(*text_rec == ' ')
{
/* return a pointer to the beginning of the text descriptor */
return(text_rec + 1L);
}
return(NULL); /* not correct record for file */
} /*** text_match ***/
/*******************************************************************************
********************************************************************************
Function: put_text
Purpose: Put the text descriptor for the directory on the screen.
Global variables:
Name Examine/Modify/Use/Read/Write
---- -----------------------------
COLS X
Return Codes:
Code Reason
---- ------
SUCCESS Everything fine
FAILURE Error parsing new filename
********************************************************************************
*******************************************************************************/
void put_text(window,text_desc)
/******* FORMAL PARAMETERS *******/
WINDOW *window; /* where to write */
char *text_desc; /* text descriptor buffer */
{ /*** put_text ***/
/******** LOCAL VARIABLES ********/
size_t length; /* string length holder */
static char buf[MAX_SCREEN_COLS+5], /* formatting buffer */
spaces[] = /* spaces array for centering stuff */
" ";
if(text_desc != NULL) /* is there anything to write? */
{
length = (COLS - strlen(text_desc))/2;
spaces[length] = '\0'; /* make spaces for centering */
cat(5,buf,spaces,text_desc,spaces," ");
buf[COLS] = '\0'; /* make sure we have the right length */
spaces[length] = ' '; /* reset spaces array for next time */
/* write directory text descriptor in reverse video at top of screen */
mvwaddstr(window,SPEC_WINDOW_ROWS-1,0,buf);
}
else
{
/* erase the one that might be on the screen, since this directory
* doesn't have a text descriptor
*/
wmove(window,SPEC_WINDOW_ROWS-1,0);
wclrtoeol(window);
}
wrefresh(window);
return;
} /*** put_text ***/
/*******************************************************************************
********************************************************************************
Function: create_text
Purpose: Attempt to create the text descriptor file if the user wants
to. The user is prompted for the text descriptor for the
directory and the file is written with the entry for the
text descriptor file itself.
Global variables:
Name Examine/Modify/Use/Read/Write
---- -----------------------------
none
Return Codes:
Code Reason
---- ------
DONT_CREATE user does not want text descriptor file created
CANT_OPEN error opening/writing text descriptor file
NEW_FILE new text descriptor file created
********************************************************************************
*******************************************************************************/
int create_text(window)
/******* FORMAL PARAMETERS *******/
WINDOW *window; /* where to read/write */
{ /*** create_text ***/
/******** LOCAL VARIABLES ********/
FILE *fptr; /* text file pointer */
char term_code, /* keystroke read in */
buf[MAX_SCREEN_COLS+1], /* for all kinds of output stuff */
text_buf[DIR_TEXT_MAX+1]; /* buffer for reading from screen */
sprintf(buf,"Text descriptor file %s does not exist. Create it? [y] ",
TEXT_FILE);
/* prompt the user to see if they want to create the text descriptor file */
info_mess(buf);
term_code = wgetch(window); /* get their response */
clear_mess(window); /* clear the prompt from the screen */
/* now see what key was pressed */
if(term_code == 'N' || term_code == 'n')
return(DONT_CREATE); /* don't create the file here, either */
/* ok, we need to create the file; open it for writing */
fptr = fopen(TEXT_FILE,"w");
if(fptr == NULL)
return(CANT_OPEN);
/* the file has been opened ok; get the descriptor for the directory,
* format it, and write it to the text descriptor file
*/
/* prompt for and read in the text descriptor for the directory itself */
prompt_getstr(window,"Text descriptor for directory: ",text_buf,main_rows,
DIR_TEXT_MAX);
text_buf[DIR_TEXT_MAX] = '\0'; /* make sure it's not too long */
cat(4,buf,">>>",text_buf,"\n"); /* format it correctly */
/* now write the directory text descriptor record to the file */
fputs(buf,fptr);
fputs(">\n",fptr); /* write a spacing record */
/* now write the text descriptor entry for the text descriptor file
* itself; this is so the user knows what the file is when they bring
* the text descriptors in
*/
cat(3,buf,TEXT_FILE," text descriptor file\n");
fputs(buf,fptr);
fclose(fptr);
return(NEW_FILE);
} /*** create_text ***/
/*******************************************************************************
********************************************************************************
Function: get_text
Purpose: Set up and get the text descriptors for the current
directory. Being able to update slot_width is essential
for proc_dir() and is one of the reasons this routine
exists. slot_width is set in set_args() but set_args()
is only called from main().
Global variables:
Name Examine/Modify/Use/Read/Write
---- -----------------------------
args.text X X
args.text_startup X
Return Codes:
Code Reason
---- ------
none
********************************************************************************
*******************************************************************************/
void get_text(args,dirptr,curr_pool,dir_text,mess_flag,slot_width,text_flag,
pool_length,num_file)
/******* FORMAL PARAMETERS *******/
ARG_DEF *args; /* run-time arguments */
ENT_DEF *dirptr; /* pointer to directory information */
POOL_DEF **curr_pool; /* pointer to current memory pool */
char **dir_text, /* pointer to directory text descrip */
*mess_flag; /* set if information mess on screen */
short *slot_width, /* slot width for current directory */
*text_flag; /* set if descrip file was processed */
size_t pool_length; /* length for allocating new pools */
short num_file; /* number of files in directory */
{ /*** get_text ***/
/******** LOCAL VARIABLES ********/
short status; /* return status from read_text_des() */
*text_flag = 0;
if(args->text)
{
/* yes, read in the text descriptors */
*text_flag = args->text; /* set descrip flag for this direct. */
if(args->text == DISPLAY_TEXT && !args->text_startup)
*slot_width += TEXT_MAX + 1; /* assume we will get text descrips */
status = read_text_des(dirptr,curr_pool,dir_text,pool_length,num_file);
/* check to see if there were any problems getting the text descriptors */
if(status == BAD_FILE)
{
info_mess("Invalid format for text descriptor file");
*mess_flag = 1;
*text_flag = 0; /* no text descrips for directory */
if(args->text == DISPLAY_TEXT) /* only update slot_width if needed */
*slot_width = *slot_width - (TEXT_MAX + 1);
sleep(1);
}
else if(status == CANT_OPEN)
{
info_mess("Cannot open text descriptor file");
*mess_flag = 1;
*text_flag = 0; /* no text descrips for directory */
if(args->text == DISPLAY_TEXT) /* only update slot_width if needed */
*slot_width = *slot_width - (TEXT_MAX + 1);
sleep(1);
}
else if(status == NO_FILE)
{
*text_flag = 0; /* no text descrips for directory */
if(args->text == DISPLAY_TEXT) /* update slot_width if it needs it */
*slot_width = *slot_width - (TEXT_MAX + 1);
}
}
return;
} /*** get_text ***/