home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume26 / maint / part02 / slot.c < prev   
C/C++ Source or Header  |  1992-05-13  |  17KB  |  547 lines

  1. /******************************************************************************
  2. *******************************************************************************
  3.  
  4.    Site:    Western Michigan University Academic Computer Center
  5.  
  6.    System:    Directory/File System Maintenance
  7.   
  8.    Program:    maint
  9.  
  10.    Version=01    Level=00    01/24/92    Leonard J. Peirce
  11.  
  12.    Purpose:    Routines for creating file slots and gathering info for
  13.         Expanding.
  14.  
  15.    Arguments:    See individual routines.
  16.  
  17.    External variables:    None
  18.  
  19.    WMU external functions:
  20.  
  21.           Defined:    get_group, get_owner, make_slot
  22.  
  23.           Called:    add_filetype, mystrcpy, mystrmcpy, padcpy,
  24.             prot_val_to_str, set_date
  25.  
  26.    Files accessed:    See individual routines.
  27.  
  28.    Return codes:    See individual routines.
  29.  
  30.    Compiling instructions:    See Makefile.
  31.  
  32.    Linking instructions:    See Makefile.
  33.  
  34.    Other information:    (C) Copyright 1992, Leonard J. Peirce
  35.  
  36. ********************************************************************************
  37. *******************************************************************************/
  38.  
  39. /******************************************************************************/
  40. /*                                                                            */
  41. /*                        # I N C L U D E   F I L E S                         */
  42. /*                                                                            */
  43. /******************************************************************************/
  44.  
  45. #ifdef ultrix
  46. #include <cursesX.h>
  47. #else
  48. #include <curses.h>
  49. #endif
  50. #include <stdio.h>
  51. #include <string.h>
  52. #include <ctype.h>
  53. #include <pwd.h>
  54. #include <grp.h>
  55. #include "maint.h"
  56.  
  57. /******************************************************************************/
  58. /*                                                                            */
  59. /*                             # D E F I N E S                                */
  60. /*                                                                            */
  61. /******************************************************************************/
  62.  
  63. /******************************************************************************/
  64. /*                                                                            */
  65. /*          S T R U C T U R E S ,   U N I O N S ,   T Y P E D E F S           */
  66. /*                                                                            */
  67. /******************************************************************************/
  68.  
  69. /******************************************************************************/
  70. /*                                                                            */
  71. /*   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    */
  72. /*                                                                            */
  73. /******************************************************************************/
  74.  
  75. extern     char      *mystrcpy(),
  76.           *mystrmcpy(),
  77.           *prot_val_to_str(),
  78.           *padcpy(),
  79.           *set_date();
  80.  
  81. #if defined(SYSV) || defined(sun)
  82. extern     void      setpwent(),
  83.           setgrent();
  84. #else
  85. extern     int      setpwent(),
  86.           setgrent();
  87. #endif
  88.  
  89. extern     u_short  add_filetype();
  90.  
  91.      char      *get_owner(),
  92.           *get_group();
  93.  
  94.      int      make_slot();
  95.  
  96. /******************************************************************************/
  97. /*                                                                            */
  98. /*     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      */
  99. /*                                                                            */
  100. /******************************************************************************/
  101.  
  102. /*******************************************************************************
  103. ********************************************************************************
  104.  
  105.   Function:    make_slot
  106.  
  107.   Purpose:    Make a slot to be displayed on the screen for a file depending
  108.         on the (possible) commands associated with the file.  In
  109.         some cases, some funny stuff will be done with the screen
  110.         slot to connotate that the file has some commands associated
  111.         with it.
  112.  
  113.   Global variables:
  114.  
  115.     Name            Examine/Modify/Use/Read/Write
  116.     ----            -----------------------------
  117.     none
  118.  
  119.   Return Codes:
  120.  
  121.     Code            Reason
  122.     ----            ------
  123.     A_NORMAL        file slot is normal
  124.     A_BOLD            file has commands; highlite it
  125.  
  126. ********************************************************************************
  127. *******************************************************************************/
  128.  
  129. int make_slot(buf,ent,args,slot_width,text_flag)
  130.                      /*******   FORMAL  PARAMETERS   *******/
  131.      char      *buf;            /* where to put the screen slot          */
  132. register ENT_DEF  *ent;            /* file entry pointer              */
  133. register ARG_DEF  *args;        /* run-time arguments              */
  134.      short      slot_width,        /* width of a screen slot          */
  135.           text_flag;        /* whether we display text descrips   */
  136.  
  137. {    /*** make_slot ***/
  138.                     /********   LOCAL  VARIABLES   ********/
  139. register char      *tptr;        /* temporary pointer              */
  140.      char      *text_ptr = NULL;    /* pointer to text descriptor          */
  141.      COM_DEF  *ptr;            /* pointer to possible command struct */
  142. static     u_short  pass;            /* set if we've been here before      */
  143. static     char      gap_buf[FIELD_GAP+1],    /* inter-field gap buffer          */
  144.           gap_buf2[SLOT_GAP+1], /* inter-slot gap buffer          */
  145.           text_buf[TEXT_MAX+1],    /* for formatting text descriptors    */
  146.           size_buf[SIZE_MAX+1],    /* for formatting size of file          */
  147.           blnk_text[TEXT_MAX+1], /* blank text descriptor          */
  148.           del_str1[] = {"<del>"},
  149.           del_str2[] = {"<delete>"};
  150.  
  151.  
  152.    if(!pass)
  153.    {
  154.       for(pass = 0; pass < FIELD_GAP; pass++)
  155.      gap_buf[pass] = ' ';
  156.       for(pass = 0; pass < SLOT_GAP; pass++)
  157.      gap_buf2[pass] = ' ';
  158.       for(pass = 0; pass < TEXT_MAX; pass++)
  159.      blnk_text[pass] = ' ';
  160.       pass = 1;
  161.    }
  162.  
  163.    /* now see if there are commands associated with the file; we do things
  164.     * a little differently if there are
  165.     */
  166.  
  167.    ptr = ent->command;
  168.  
  169.    if(ptr != NULL)
  170.    {
  171.       if(ptr->comm_del)            /* is the file going to be deleted?   */
  172.       {
  173.      /* yes, now see if there is enough room to put in the "<delete>"
  174.       * string
  175.       */
  176.  
  177.      if(slot_width <= (DISP_MAX + sizeof(del_str2)))
  178.      {
  179.         /* the slot is only big enough to use <del> to signify that the
  180.          * file is marked for deletion
  181.          */
  182.  
  183.         strcpy(buf,ent->scr_name);
  184.         strcpy(&buf[DISP_MAX - sizeof(del_str1) + 1],del_str1);
  185.  
  186.         if(ent->disp_len > (DISP_MAX - sizeof(del_str1) + 1))
  187.         {
  188.            buf[slot_width] = FLAG_CHAR;
  189.            buf[slot_width + 1] = '\0';
  190.         }
  191.      }
  192.      else
  193.      {
  194.         /* use the regular "<delete>" string to show that the user
  195.          * marked the file to be deleted
  196.          */
  197.  
  198.         sprintf(buf,"%s%s                                         \
  199.                                     ",ent->scr_name,del_str2);
  200.  
  201.         if(ent->disp_len > DISP_MAX)
  202.             buf[DISP_MAX + sizeof(del_str2) - 1] = FLAG_CHAR;
  203.  
  204.         *(buf + slot_width + SLOT_GAP) = '\0';
  205.      }
  206.  
  207.      return((int) A_BOLD);        /* just return from here          */
  208.       }
  209.  
  210.       /* no, the file is not going to be deleted, but it might have some other
  211.        * command associated with it; check them to be sure
  212.        */
  213.  
  214.       /* which text descriptor pointer should we use? */
  215.  
  216.       if(text_flag == DISPLAY_TEXT)    /* should we display text descriptor? */
  217.       {
  218.      /* yes, text descriptors are to be displayed on the screen; now
  219.       * determine which, if any, text descriptor to use for the
  220.       * current file
  221.       */
  222.  
  223.      if(ptr->comm_text)        /* use new text descriptor?          */
  224.      {
  225.         /* use the new text descriptor for the slot */
  226.  
  227.         padcpy(text_buf,ptr->text,TEXT_MAX);
  228.         text_ptr = text_buf;    /* set the pointer to the text desc.  */
  229.      }
  230.      else if(ent->text != NULL)    /* or should we use the original?     */
  231.      {
  232.         /* use the original text descriptor for the file */
  233.  
  234.         padcpy(text_buf,ent->text,TEXT_MAX);
  235.         text_ptr = text_buf;    /* set the pointer to the text desc.  */
  236.      }
  237.      else                /* or should we use a blank desc?     */
  238.      {
  239.         /* this file has no text descriptor; use a blank one to make
  240.          * sure that we completely write over any text descriptor that
  241.          * might been written in the current slot before this
  242.          */
  243.  
  244.         text_ptr = blnk_text;    /* use a blank text descriptor          */
  245.      }
  246.       }
  247.    }
  248.  
  249.    /* now create the slot */
  250.  
  251.    if(text_flag == DISPLAY_TEXT && !text_ptr)
  252.    {
  253.       /* yes, we want text descriptors, they don't overflow the slots,
  254.        * and this file doesn't have a new one specified for it
  255.        */
  256.  
  257.       if(ent->text != NULL)        /* is there a text descriptor?          */
  258.       {
  259.      /* there IS a text descriptor for this file; pad the text descriptor
  260.       * on the right with spaces so that if there was a descriptor on the
  261.       * screen in this slot (perhaps from a previous page) it will be
  262.       * completely overwritten by the current one
  263.       */
  264.  
  265.      padcpy(text_buf,ent->text,TEXT_MAX);
  266.      text_ptr = text_buf;        /* set the pointer to the text desc.  */
  267.       }
  268.       else
  269.      text_ptr = blnk_text;        /* use a blank text descriptor          */
  270.    }
  271.  
  272.    /* collect all of the information necessary to make the slot */
  273.  
  274.    tptr = buf;
  275.    tptr = mystrcpy(buf,ent->scr_name);
  276.  
  277.    /* write a gap buf just in case a file still has a FLAG_CHAR there
  278.     * from before; this can happen when the displayed filename will just fit
  279.     * on the screen, the user selects Delete, and then Unmarks it;
  280.     * we don't move tptr because if there is anything else that will
  281.     * go into this slot, it will just overwrite the extra gap_buf
  282.     */
  283.  
  284.    mystrcpy(tptr,gap_buf);
  285.  
  286.    if(args->owner)
  287.    {
  288.       tptr = mystrcpy(tptr,gap_buf);
  289.       tptr = mystrmcpy(tptr,get_owner(ent->uid),OWNER_MAX);
  290.    }
  291.  
  292.    if(args->group)
  293.    {
  294.       tptr = mystrcpy(tptr,gap_buf);
  295.       tptr = mystrmcpy(tptr,get_group(ent->gid),GROUP_MAX);
  296.    }
  297.  
  298.    if(args->size)            /* should the size be included?          */
  299.    { 
  300.       tptr = mystrcpy(tptr,gap_buf);
  301.       sprintf(size_buf,"%8d",ent->size);
  302.       tptr = mystrcpy(tptr,size_buf);
  303.    }
  304.  
  305.    if(args->date)
  306.    {
  307.       tptr = mystrcpy(tptr,gap_buf);
  308.       tptr = mystrcpy(tptr,set_date(ent->time));
  309.    }
  310.  
  311.    if(args->prot)
  312.    {
  313.       tptr = mystrcpy(tptr,gap_buf);
  314.       tptr = mystrcpy(tptr,prot_val_to_str(ent->prot));
  315.    }
  316.  
  317.    if(text_flag == DISPLAY_TEXT)    /* do we display the text descrips?   */
  318.    {
  319.       /* yes, they don't overflow the file slots; now see if there is one
  320.        * for the current file
  321.        */
  322.  
  323.       tptr = mystrcpy(tptr,gap_buf);
  324.  
  325.       if(text_ptr != NULL)        /* use new text descriptor?          */
  326.      tptr = mystrcpy(tptr,text_ptr);
  327.       else
  328.      tptr = mystrcpy(tptr,blnk_text);
  329.    }
  330.  
  331.    if(ent->name_len > DNAME_MAX)    /* flag it if it's too long          */
  332.    {
  333.       if(buf[DISP_MAX] == '\0')
  334.       {
  335.      buf[DISP_MAX] = FLAG_CHAR;
  336.      buf[DISP_MAX+1] = '\0';
  337.       }
  338.       else
  339.      buf[DISP_MAX] = FLAG_CHAR;
  340.  
  341.       tptr++;
  342.    }
  343.  
  344.    tptr = mystrcpy(tptr,gap_buf2);
  345.  
  346.    return(ent->command ? (int) A_BOLD : (int) A_NORMAL);
  347.  
  348. }    /*** make_slot ***/
  349.  
  350. /*******************************************************************************
  351. ********************************************************************************
  352.  
  353.   Function:    get_group    
  354.  
  355.   Purpose:    Return the string associated with a group id.  Gids that are
  356.         successfully translated are saved to speed up future trans-
  357.         lations.
  358.  
  359.   Global variables:
  360.  
  361.     Name            Examine/Modify/Use/Read/Write
  362.     ----            -----------------------------
  363.     none
  364.  
  365.   Return Codes:
  366.  
  367.     Code            Reason
  368.     ----            ------
  369.     retptr            pointer to group string, padded out to
  370.                 ID_STR_MAX with spaces
  371.  
  372. ********************************************************************************
  373. *******************************************************************************/
  374.  
  375. char *get_group(gid)
  376.                     /*******   FORMAL  PARAMETERS   *******/
  377.      gid_t      gid;            /* group id value              */
  378.  
  379. {    /*** get_group ***/
  380.                     /********   LOCAL  VARIABLES   ********/
  381. struct     group      *gptr;        /* for using getgrent              */
  382.      char      *retptr;        /* group string to return          */
  383.      u_short  i;            /* loop and array index              */
  384. static     u_short  count;        /* number of group ids saved          */
  385. static     ID_ENT      groups[GROUP_SAVE];    /* list of groups already retrieved   */
  386. static     char      buf[ID_STR_MAX+1];    /* used for formatting              */
  387.  
  388.  
  389.    /* first search the groups that are already saved */
  390.  
  391.    i = 0;
  392.    while((i < count) && gid != groups[i].id)
  393.       ++i;
  394.  
  395.    if(i >= count)            /* did we find the gid?              */
  396.    {
  397.       gptr = getgrgid((int) gid);    /* nope, go get it....              */
  398.  
  399.       if(gptr != NULL)            /* did we find it?              */
  400.       {
  401.      /* we found it; now save it if we have room */
  402.  
  403.      if(count < GROUP_SAVE)        /* do we have room?              */
  404.      {
  405.         groups[count].id = gid;    /* yes, save the gid and string...    */
  406.         padcpy(groups[count].str,gptr->gr_name,ID_STR_MAX);
  407.         retptr = groups[count].str;
  408.         count++;            /* count it since we saved it          */
  409.      }
  410.      else
  411.      {
  412.         /* no room to save it; put it in buf, padded with spaces on the
  413.          * right
  414.          */
  415.  
  416.         padcpy(buf,gptr->gr_name,ID_STR_MAX);
  417.         retptr = buf;
  418.      }
  419.       }
  420.       else
  421.       {
  422.      /* we didn't find it; convert the gid to a string and use that */        
  423.      sprintf(buf,"%-8d",gid);
  424.  
  425.      /* we might as well save it just in case we get another file
  426.       * that has the same gid
  427.       */
  428.  
  429.      if(count < GROUP_SAVE)        /* do we have room?              */
  430.      {
  431.         groups[count].id = gid;    /* yes, save the gid and string...    */
  432.         padcpy(groups[count].str,buf,ID_STR_MAX);
  433.         retptr = groups[count].str;    /* set return pointer              */
  434.         count++;
  435.      }
  436.      else
  437.         retptr = buf;        /* no room to save it              */
  438.       }
  439.  
  440.       setgrent();            /* to rewind the file, basically..... */
  441.    }
  442.    else
  443.       retptr = groups[i].str;        /* we found it....              */
  444.  
  445.    return(retptr);
  446.  
  447. }    /*** get_group ***/
  448.  
  449. /*******************************************************************************
  450. ********************************************************************************
  451.  
  452.   Function:    get_owner    
  453.  
  454.   Purpose:    Return the string corresponding to the owner of a file
  455.         based on the uid that is passed.  Uids that are successfully
  456.         translated are saved to speed up future translations.
  457.  
  458.   Global variables:
  459.  
  460.     Name            Examine/Modify/Use/Read/Write
  461.     ----            -----------------------------
  462.     none
  463.  
  464.   Return Codes:
  465.  
  466.     Code            Reason
  467.     ----            ------
  468.     retptr            pointer to owner string, padded out to
  469.                 ID_STR_MAX with spaces
  470.  
  471. ********************************************************************************
  472. *******************************************************************************/
  473.  
  474. char *get_owner(uid)
  475.                     /*******   FORMAL  PARAMETERS   *******/
  476.      uid_t      uid;            /* user id value              */
  477.  
  478. {    /*** get_owner ***/
  479.                     /********   LOCAL  VARIABLES   ********/
  480. struct     passwd      *uptr;        /* for using getpwuid              */
  481.      char      *retptr;        /* owner string to return          */
  482.      u_short  i;            /* loop and array index              */
  483. static     u_short  count;        /* number of user ids saved          */
  484. static     ID_ENT      owners[OWNER_SAVE];    /* list of user ids already retrieved */
  485. static     char      buf[ID_STR_MAX+1];    /* used for formatting              */
  486.  
  487.  
  488.    /* first search the uids that are already saved */
  489.  
  490.    i = 0;
  491.    while((i < count) && uid != owners[i].id)
  492.       ++i;
  493.  
  494.    if(i >= count)            /* did we find the uid?              */
  495.    {
  496.       uptr = getpwuid((int) uid);    /* nope, go get it....              */
  497.  
  498.       if(uptr != NULL)            /* did we find it?              */
  499.       {
  500.      /* we found it; now save it if we have room */
  501.  
  502.      if(count < OWNER_SAVE)        /* do we have room?              */
  503.      {
  504.         owners[count].id = uid;    /* yes, save the uid and string...    */
  505.         padcpy(owners[count].str,uptr->pw_name,ID_STR_MAX);
  506.         retptr = owners[count].str;
  507.         count++;            /* count it since we saved it          */
  508.      }
  509.      else
  510.      {
  511.         /* no room to save it; put it in buf, padded with spaces on the
  512.          * right
  513.          */
  514.  
  515.         padcpy(buf,uptr->pw_name,ID_STR_MAX);
  516.         retptr = buf;
  517.      }
  518.       }
  519.       else
  520.       {
  521.      /* we didn't find it; convert the gid to a string and use that */        
  522.      sprintf(buf,"%-8d",uid);
  523.  
  524.      /* we might as well save it just in case we get another file
  525.       * that has the same uid
  526.       */
  527.  
  528.      if(count < OWNER_SAVE)        /* do we have room?              */
  529.      {
  530.         owners[count].id = uid;    /* yes, save the gid and string...    */
  531.         padcpy(owners[count].str,buf,ID_STR_MAX);
  532.         retptr = owners[count].str;
  533.         count++;            /* count it since we saved it          */
  534.      }
  535.      else
  536.         retptr = buf;
  537.       }
  538.  
  539.       setpwent();            /* to rewind the file, basically..... */
  540.    }
  541.    else
  542.       retptr = owners[i].str;        /* we found it....              */
  543.  
  544.    return(retptr);
  545.  
  546. }    /*** get_owner ***/
  547.