home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume26
/
maint
/
part02
/
slot.c
< prev
Wrap
C/C++ Source or Header
|
1992-05-13
|
17KB
|
547 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 creating file slots and gathering info for
Expanding.
Arguments: See individual routines.
External variables: None
WMU external functions:
Defined: get_group, get_owner, make_slot
Called: add_filetype, mystrcpy, mystrmcpy, padcpy,
prot_val_to_str, set_date
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 <stdio.h>
#include <string.h>
#include <ctype.h>
#include <pwd.h>
#include <grp.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 char *mystrcpy(),
*mystrmcpy(),
*prot_val_to_str(),
*padcpy(),
*set_date();
#if defined(SYSV) || defined(sun)
extern void setpwent(),
setgrent();
#else
extern int setpwent(),
setgrent();
#endif
extern u_short add_filetype();
char *get_owner(),
*get_group();
int make_slot();
/******************************************************************************/
/* */
/* 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: make_slot
Purpose: Make a slot to be displayed on the screen for a file depending
on the (possible) commands associated with the file. In
some cases, some funny stuff will be done with the screen
slot to connotate that the file has some commands associated
with it.
Global variables:
Name Examine/Modify/Use/Read/Write
---- -----------------------------
none
Return Codes:
Code Reason
---- ------
A_NORMAL file slot is normal
A_BOLD file has commands; highlite it
********************************************************************************
*******************************************************************************/
int make_slot(buf,ent,args,slot_width,text_flag)
/******* FORMAL PARAMETERS *******/
char *buf; /* where to put the screen slot */
register ENT_DEF *ent; /* file entry pointer */
register ARG_DEF *args; /* run-time arguments */
short slot_width, /* width of a screen slot */
text_flag; /* whether we display text descrips */
{ /*** make_slot ***/
/******** LOCAL VARIABLES ********/
register char *tptr; /* temporary pointer */
char *text_ptr = NULL; /* pointer to text descriptor */
COM_DEF *ptr; /* pointer to possible command struct */
static u_short pass; /* set if we've been here before */
static char gap_buf[FIELD_GAP+1], /* inter-field gap buffer */
gap_buf2[SLOT_GAP+1], /* inter-slot gap buffer */
text_buf[TEXT_MAX+1], /* for formatting text descriptors */
size_buf[SIZE_MAX+1], /* for formatting size of file */
blnk_text[TEXT_MAX+1], /* blank text descriptor */
del_str1[] = {"<del>"},
del_str2[] = {"<delete>"};
if(!pass)
{
for(pass = 0; pass < FIELD_GAP; pass++)
gap_buf[pass] = ' ';
for(pass = 0; pass < SLOT_GAP; pass++)
gap_buf2[pass] = ' ';
for(pass = 0; pass < TEXT_MAX; pass++)
blnk_text[pass] = ' ';
pass = 1;
}
/* now see if there are commands associated with the file; we do things
* a little differently if there are
*/
ptr = ent->command;
if(ptr != NULL)
{
if(ptr->comm_del) /* is the file going to be deleted? */
{
/* yes, now see if there is enough room to put in the "<delete>"
* string
*/
if(slot_width <= (DISP_MAX + sizeof(del_str2)))
{
/* the slot is only big enough to use <del> to signify that the
* file is marked for deletion
*/
strcpy(buf,ent->scr_name);
strcpy(&buf[DISP_MAX - sizeof(del_str1) + 1],del_str1);
if(ent->disp_len > (DISP_MAX - sizeof(del_str1) + 1))
{
buf[slot_width] = FLAG_CHAR;
buf[slot_width + 1] = '\0';
}
}
else
{
/* use the regular "<delete>" string to show that the user
* marked the file to be deleted
*/
sprintf(buf,"%s%s \
",ent->scr_name,del_str2);
if(ent->disp_len > DISP_MAX)
buf[DISP_MAX + sizeof(del_str2) - 1] = FLAG_CHAR;
*(buf + slot_width + SLOT_GAP) = '\0';
}
return((int) A_BOLD); /* just return from here */
}
/* no, the file is not going to be deleted, but it might have some other
* command associated with it; check them to be sure
*/
/* which text descriptor pointer should we use? */
if(text_flag == DISPLAY_TEXT) /* should we display text descriptor? */
{
/* yes, text descriptors are to be displayed on the screen; now
* determine which, if any, text descriptor to use for the
* current file
*/
if(ptr->comm_text) /* use new text descriptor? */
{
/* use the new text descriptor for the slot */
padcpy(text_buf,ptr->text,TEXT_MAX);
text_ptr = text_buf; /* set the pointer to the text desc. */
}
else if(ent->text != NULL) /* or should we use the original? */
{
/* use the original text descriptor for the file */
padcpy(text_buf,ent->text,TEXT_MAX);
text_ptr = text_buf; /* set the pointer to the text desc. */
}
else /* or should we use a blank desc? */
{
/* this file has no text descriptor; use a blank one to make
* sure that we completely write over any text descriptor that
* might been written in the current slot before this
*/
text_ptr = blnk_text; /* use a blank text descriptor */
}
}
}
/* now create the slot */
if(text_flag == DISPLAY_TEXT && !text_ptr)
{
/* yes, we want text descriptors, they don't overflow the slots,
* and this file doesn't have a new one specified for it
*/
if(ent->text != NULL) /* is there a text descriptor? */
{
/* there IS a text descriptor for this file; pad the text descriptor
* on the right with spaces so that if there was a descriptor on the
* screen in this slot (perhaps from a previous page) it will be
* completely overwritten by the current one
*/
padcpy(text_buf,ent->text,TEXT_MAX);
text_ptr = text_buf; /* set the pointer to the text desc. */
}
else
text_ptr = blnk_text; /* use a blank text descriptor */
}
/* collect all of the information necessary to make the slot */
tptr = buf;
tptr = mystrcpy(buf,ent->scr_name);
/* write a gap buf just in case a file still has a FLAG_CHAR there
* from before; this can happen when the displayed filename will just fit
* on the screen, the user selects Delete, and then Unmarks it;
* we don't move tptr because if there is anything else that will
* go into this slot, it will just overwrite the extra gap_buf
*/
mystrcpy(tptr,gap_buf);
if(args->owner)
{
tptr = mystrcpy(tptr,gap_buf);
tptr = mystrmcpy(tptr,get_owner(ent->uid),OWNER_MAX);
}
if(args->group)
{
tptr = mystrcpy(tptr,gap_buf);
tptr = mystrmcpy(tptr,get_group(ent->gid),GROUP_MAX);
}
if(args->size) /* should the size be included? */
{
tptr = mystrcpy(tptr,gap_buf);
sprintf(size_buf,"%8d",ent->size);
tptr = mystrcpy(tptr,size_buf);
}
if(args->date)
{
tptr = mystrcpy(tptr,gap_buf);
tptr = mystrcpy(tptr,set_date(ent->time));
}
if(args->prot)
{
tptr = mystrcpy(tptr,gap_buf);
tptr = mystrcpy(tptr,prot_val_to_str(ent->prot));
}
if(text_flag == DISPLAY_TEXT) /* do we display the text descrips? */
{
/* yes, they don't overflow the file slots; now see if there is one
* for the current file
*/
tptr = mystrcpy(tptr,gap_buf);
if(text_ptr != NULL) /* use new text descriptor? */
tptr = mystrcpy(tptr,text_ptr);
else
tptr = mystrcpy(tptr,blnk_text);
}
if(ent->name_len > DNAME_MAX) /* flag it if it's too long */
{
if(buf[DISP_MAX] == '\0')
{
buf[DISP_MAX] = FLAG_CHAR;
buf[DISP_MAX+1] = '\0';
}
else
buf[DISP_MAX] = FLAG_CHAR;
tptr++;
}
tptr = mystrcpy(tptr,gap_buf2);
return(ent->command ? (int) A_BOLD : (int) A_NORMAL);
} /*** make_slot ***/
/*******************************************************************************
********************************************************************************
Function: get_group
Purpose: Return the string associated with a group id. Gids that are
successfully translated are saved to speed up future trans-
lations.
Global variables:
Name Examine/Modify/Use/Read/Write
---- -----------------------------
none
Return Codes:
Code Reason
---- ------
retptr pointer to group string, padded out to
ID_STR_MAX with spaces
********************************************************************************
*******************************************************************************/
char *get_group(gid)
/******* FORMAL PARAMETERS *******/
gid_t gid; /* group id value */
{ /*** get_group ***/
/******** LOCAL VARIABLES ********/
struct group *gptr; /* for using getgrent */
char *retptr; /* group string to return */
u_short i; /* loop and array index */
static u_short count; /* number of group ids saved */
static ID_ENT groups[GROUP_SAVE]; /* list of groups already retrieved */
static char buf[ID_STR_MAX+1]; /* used for formatting */
/* first search the groups that are already saved */
i = 0;
while((i < count) && gid != groups[i].id)
++i;
if(i >= count) /* did we find the gid? */
{
gptr = getgrgid((int) gid); /* nope, go get it.... */
if(gptr != NULL) /* did we find it? */
{
/* we found it; now save it if we have room */
if(count < GROUP_SAVE) /* do we have room? */
{
groups[count].id = gid; /* yes, save the gid and string... */
padcpy(groups[count].str,gptr->gr_name,ID_STR_MAX);
retptr = groups[count].str;
count++; /* count it since we saved it */
}
else
{
/* no room to save it; put it in buf, padded with spaces on the
* right
*/
padcpy(buf,gptr->gr_name,ID_STR_MAX);
retptr = buf;
}
}
else
{
/* we didn't find it; convert the gid to a string and use that */
sprintf(buf,"%-8d",gid);
/* we might as well save it just in case we get another file
* that has the same gid
*/
if(count < GROUP_SAVE) /* do we have room? */
{
groups[count].id = gid; /* yes, save the gid and string... */
padcpy(groups[count].str,buf,ID_STR_MAX);
retptr = groups[count].str; /* set return pointer */
count++;
}
else
retptr = buf; /* no room to save it */
}
setgrent(); /* to rewind the file, basically..... */
}
else
retptr = groups[i].str; /* we found it.... */
return(retptr);
} /*** get_group ***/
/*******************************************************************************
********************************************************************************
Function: get_owner
Purpose: Return the string corresponding to the owner of a file
based on the uid that is passed. Uids that are successfully
translated are saved to speed up future translations.
Global variables:
Name Examine/Modify/Use/Read/Write
---- -----------------------------
none
Return Codes:
Code Reason
---- ------
retptr pointer to owner string, padded out to
ID_STR_MAX with spaces
********************************************************************************
*******************************************************************************/
char *get_owner(uid)
/******* FORMAL PARAMETERS *******/
uid_t uid; /* user id value */
{ /*** get_owner ***/
/******** LOCAL VARIABLES ********/
struct passwd *uptr; /* for using getpwuid */
char *retptr; /* owner string to return */
u_short i; /* loop and array index */
static u_short count; /* number of user ids saved */
static ID_ENT owners[OWNER_SAVE]; /* list of user ids already retrieved */
static char buf[ID_STR_MAX+1]; /* used for formatting */
/* first search the uids that are already saved */
i = 0;
while((i < count) && uid != owners[i].id)
++i;
if(i >= count) /* did we find the uid? */
{
uptr = getpwuid((int) uid); /* nope, go get it.... */
if(uptr != NULL) /* did we find it? */
{
/* we found it; now save it if we have room */
if(count < OWNER_SAVE) /* do we have room? */
{
owners[count].id = uid; /* yes, save the uid and string... */
padcpy(owners[count].str,uptr->pw_name,ID_STR_MAX);
retptr = owners[count].str;
count++; /* count it since we saved it */
}
else
{
/* no room to save it; put it in buf, padded with spaces on the
* right
*/
padcpy(buf,uptr->pw_name,ID_STR_MAX);
retptr = buf;
}
}
else
{
/* we didn't find it; convert the gid to a string and use that */
sprintf(buf,"%-8d",uid);
/* we might as well save it just in case we get another file
* that has the same uid
*/
if(count < OWNER_SAVE) /* do we have room? */
{
owners[count].id = uid; /* yes, save the gid and string... */
padcpy(owners[count].str,buf,ID_STR_MAX);
retptr = owners[count].str;
count++; /* count it since we saved it */
}
else
retptr = buf;
}
setpwent(); /* to rewind the file, basically..... */
}
else
retptr = owners[i].str; /* we found it.... */
return(retptr);
} /*** get_owner ***/