home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / maint / part03 / mark.c next >
Encoding:
C/C++ Source or Header  |  1992-05-13  |  25.9 KB  |  950 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:    Associate commands with individual file entries or cancel
  13.         all commands for a file.
  14.  
  15.    Arguments:    See individual routines
  16.  
  17.    External variables:    See individual routines
  18.  
  19.    External functions:
  20.  
  21.     Defined:    mark_text, mark_delete, mark_copy_ren, mark_protect,
  22.             mark_group, mark_owner, mark_rename, mark_cancel,
  23.             mark_repeat
  24.  
  25.     Called:        new_comm, add_filetype, prot_str_to_val, prompt_getstr,
  26.             free_comstr, squeeze_str
  27.  
  28.    Files accessed:    See individual routines
  29.  
  30.    Return codes:    See individual routines
  31.  
  32.    Compiling instructions:    See Makefile
  33.  
  34.    Linking instructions:    See Makefile
  35.  
  36.    Other information:    (C) Copyright 1992, Leonard J. Peirce
  37.  
  38. ********************************************************************************
  39. *******************************************************************************/
  40.  
  41. /******************************************************************************/
  42. /*                                                                            */
  43. /*                        # I N C L U D E   F I L E S                         */
  44. /*                                                                            */
  45. /******************************************************************************/
  46.  
  47. #include <ctype.h>
  48. #include <math.h>
  49. #include <malloc.h>
  50. #ifdef ultrix
  51. #include <cursesX.h>
  52. #else
  53. #include <curses.h>
  54. #endif
  55. #include <string.h>
  56. #include <grp.h>
  57. #include <pwd.h>
  58. #include "maint.h"
  59.  
  60. /******************************************************************************/
  61. /*                                                                            */
  62. /*                             # D E F I N E S                                */
  63. /*                                                                            */
  64. /******************************************************************************/
  65.  
  66. /******************************************************************************/
  67. /*                                                                            */
  68. /*          S T R U C T U R E S ,   U N I O N S ,   T Y P E D E F S           */
  69. /*                                                                            */
  70. /******************************************************************************/
  71.  
  72. /******************************************************************************/
  73. /*                                                                            */
  74. /*   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    */
  75. /*                                                                            */
  76. /******************************************************************************/
  77.  
  78. extern     int      main_rows;
  79.  
  80. #ifndef ultrix
  81. extern     void      free();
  82. #endif
  83.  
  84. extern     COM_DEF  *new_comm();
  85.  
  86. extern     u_short  add_filetype();
  87.  
  88. extern     short      prot_str_to_val();
  89.  
  90. extern     void      prompt_getstr(),
  91.           squeeze_str(),
  92.           free_comstr();
  93.  
  94.      int      mark_text(),
  95.           mark_delete(),
  96.           mark_copy_ren(),
  97.           mark_protect(),
  98.           mark_group(),
  99.           mark_owner(),
  100.           mark_rename(),
  101.           mark_repeat();
  102.  
  103.      void      mark_cancel();
  104.  
  105. /******************************************************************************/
  106. /*                                                                            */
  107. /*     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      */
  108. /*                                                                            */
  109. /******************************************************************************/
  110.  
  111. static     short      prot_abs_to_val();
  112.  
  113. /*******************************************************************************
  114. ********************************************************************************
  115.  
  116.   Function:    mark_delete
  117.  
  118.   Purpose:    The selected file is to be deleted; allocate memory for the
  119.         command structure (if necessary), link it to the entry, and
  120.         set up the command structure so that the file can be deleted.
  121.  
  122.   Global variables:
  123.  
  124.     Name            Examine/Modify/Use/Read/Write
  125.     ----            -----------------------------
  126.     none
  127.  
  128.   Return Codes:
  129.  
  130.     Code            Reason
  131.     ----            ------
  132.       0            completed successfully
  133.      -1            problems allocating memory
  134.  
  135.   Termination Codes:
  136.  
  137.     Code            Reason
  138.     ----            ------
  139.     SUCCESS
  140.     FAILURE
  141.  
  142. ********************************************************************************
  143. *******************************************************************************/
  144.  
  145. int mark_delete(ent)
  146.                     /*******   FORMAL  PARAMETERS   *******/
  147. register ENT_DEF  *ent;            /* entry for file to be deleted          */
  148.  
  149. {    /*** mark_delete ***/
  150.                     /********   LOCAL  VARIABLES   ********/
  151. register COM_DEF  *tptr;        /* temporary command structure ptr    */
  152.  
  153.  
  154.    /* do we need a command structure or does the file already have one? */
  155.  
  156.    if(ent->command == NULL)
  157.    {
  158.       /* we need command structure; allocate it and link it to the file entry */
  159.  
  160.       tptr = new_comm();
  161.  
  162.       if(tptr == NULL)
  163.      return(FAILURE);        /* problems allocating memory          */
  164.  
  165.       ent->command = tptr;        /* link it to the file entry          */
  166.    }
  167.    else
  168.       tptr = ent->command;        /* else use the one already there     */
  169.  
  170.    tptr->comm_del = 1;
  171.  
  172.    /* deallocate all of the memory that might have been used for things
  173.     * like renaming the file and for a text descriptor
  174.     */
  175.  
  176.    if(tptr->ren_name != NULL)        /* need to deallocate rename name?    */
  177.    {
  178.  
  179.       free(tptr->ren_name);
  180.       tptr->comm_ren = 0;        /* make sure to shut of renaming      */
  181.       tptr->ren_name = NULL;        /* reset the rename name stuff          */
  182.       tptr->ren_len = 0;
  183.    }
  184.  
  185.    if(tptr->text != NULL)        /* need to deallocate text descrip?   */
  186.    {
  187.       free(tptr->text);
  188.       tptr->comm_text = 0;        /* make sure to shut off text descrip */
  189.       tptr->text = NULL;        /* reset the text descriptor stuff    */
  190.       tptr->text_len = 0;
  191.    }
  192.  
  193.    return(SUCCESS);            /* no problem.....              */
  194.  
  195. }    /*** mark_delete ***/
  196.  
  197. /*******************************************************************************
  198. ********************************************************************************
  199.  
  200.   Function:      mark_copy_ren
  201.  
  202.   Purpose:      The selected file is to be copied or renamed; allocate the
  203.         memory for the command structure (if necessary), link it to
  204.         the file entry,    and set the command in the command structure.
  205.  
  206.   Global variables:
  207.                           
  208.     Name            Examine/Modify/Use/Read/Write
  209.     ----            -----------------------------
  210.     none
  211.  
  212.   Return Codes:
  213.  
  214.     Code            Reason
  215.     ----            ------
  216.       0            completed successfully
  217.      -1            problems allocating memory
  218.  
  219.   Termination Codes:
  220.  
  221.     Code            Reason
  222.     ----            ------
  223.     SUCCESS
  224.     CANT_ALLOCATE        cannot allocate necessary memory
  225.  
  226. ********************************************************************************
  227. *******************************************************************************/
  228.    
  229. int mark_copy_ren(window,ent,command,prev_str,repeat)
  230.                     /*******   FORMAL  PARAMETERS   *******/
  231.      WINDOW      *window;        /* where to read/write              */
  232. register ENT_DEF  *ent;            /* entry for file to be deleted          */
  233.      u_short  command;        /* either RENAME or COPY          */
  234.      char      *prev_str;        /* string to use from mark_repeat()   */
  235.      u_short  repeat;        /* set if called from mark_repeat()   */
  236.             
  237. {    /*** mark_copy_ren ***/
  238.                     /********   LOCAL  VARIABLES   ********/
  239. register COM_DEF  *tptr;        /* temporary command structure ptr    */
  240.      char      *dest_ptr;        /* temporary character pointer          */
  241.      int      length;        /* length of string read in          */
  242.      char      buf[FULL_SPEC_MAX+1],    /* array for new filename          */
  243.           prompt[PROMPT_MAX+1];    /* prompt array                  */
  244.  
  245.  
  246.    if(!repeat)
  247.    {
  248.       buf[0] = '\0';            /* reset the buffer              */
  249.  
  250.       /* set up the prompt for the filename */
  251.  
  252.       if(command == COPY)
  253.      strcpy(prompt,"Copy to: ");
  254.       else
  255.      strcpy(prompt,"Rename to: ");
  256.  
  257.       /* read in the file spec */
  258.  
  259.       prompt_getstr(window,prompt,buf,main_rows,FULL_SPEC_MAX);
  260.  
  261.       /* was anything specified for the filename? */
  262.  
  263.       if(*buf == '\0')
  264.      return(SUCCESS);
  265.    }
  266.    else
  267.       strcpy(buf,prev_str);        /* use string from mark_repeat()      */
  268.  
  269.    length = strlen(buf);
  270.  
  271.    /* ok, we have a filename; now determine if we need to allocate a command
  272.     * structure for this file or if one already exists from a previous command
  273.     */
  274.  
  275.    if(ent->command == NULL)
  276.    {
  277.       /* we need command structure; allocate it and link it to the file entry */
  278.             
  279.       tptr = new_comm();
  280.  
  281.       if(tptr == NULL)
  282.      exit(CANT_ALLOCATE);        /* problems allocating memory          */
  283.  
  284.       ent->command = tptr;        /* link it to the file entry          */
  285.    }
  286.    else
  287.    {
  288.       tptr = ent->command;        /* else use the one already there     */
  289.    }
  290.  
  291.    /* is there already enough room to put the new name in a memory pool? if
  292.     * there is, just reuse the memory we already have; otherwise, free up
  293.     * the memory (if there is any) and allocate some to hold the new name
  294.     */
  295.  
  296.    if(command == COPY)
  297.    {
  298.       if(length > tptr->copy_len)
  299.       {
  300.      /* nope, we need more memory; first free the old memory if there
  301.       * was any
  302.       */
  303.  
  304.      if(tptr->copy_len != 0)
  305.         free(tptr->copy_name);
  306.  
  307.      /* now allocate some new memory to hold the longer filename
  308.       * AND the nul character
  309.       */
  310.  
  311.      tptr->copy_name = (char *) malloc((u_int) (length + 1));
  312.  
  313.      if(tptr->copy_name == NULL)
  314.      {
  315.         exit(CANT_ALLOCATE);
  316.      }
  317.  
  318.      tptr->copy_len = length;    /* save the length of the memory      */
  319.       }
  320.  
  321.       dest_ptr = tptr->copy_name;    /* get where to copy the filename to  */
  322.       tptr->comm_copy = 1;        /* set the command in the structure   */
  323.    }
  324.    else
  325.    {
  326.       if(length > tptr->ren_len)
  327.       {
  328.      /* nope, we need more memory; first free the old memory if there
  329.       * was any
  330.       */
  331.  
  332.      if(tptr->ren_len != 0)
  333.         free(tptr->ren_name);
  334.  
  335.      /* now allocate some new memory to hold the longer filename
  336.       * AND the nul character
  337.       */
  338.  
  339.      tptr->ren_name = (char *) malloc((u_int) (length + 1));
  340.  
  341.      if(tptr->ren_name == NULL)
  342.         exit(CANT_ALLOCATE);
  343.  
  344.      tptr->ren_len = length;    /* save the length of the memory      */
  345.       }
  346.  
  347.       dest_ptr = tptr->ren_name;    /* get where to copy the filename to  */
  348.       tptr->comm_ren = TRUE;        /* set the command in the structure   */
  349.       tptr->comm_del = FALSE;        /* rename implies no delete          */
  350.    }
  351.  
  352.    strcpy(dest_ptr,buf);        /* copy it to the right place          */
  353.  
  354.    return(SUCCESS);
  355.  
  356. }    /*** mark_copy_ren ***/
  357.  
  358. /*******************************************************************************
  359. ********************************************************************************
  360.  
  361.   Function:      mark_text
  362.  
  363.   Purpose:      The selected file is to get a text descriptor; allocate the
  364.         memory for the command structure (if necessary), link it to
  365.         the file entry,    and set the command in the command structure.
  366.  
  367.   Global variables:
  368.                           
  369.     Name            Examine/Modify/Use/Read/Write
  370.     ----            -----------------------------
  371.     none
  372.  
  373.   Return Codes:
  374.  
  375.     Code            Reason
  376.     ----            ------
  377.     SUCCESS
  378.     FAILURE
  379.  
  380.   Termination Codes:
  381.  
  382.     Code            Reason
  383.     ----            ------
  384.     SUCCESS
  385.     FAILURE
  386.  
  387. ********************************************************************************
  388. *******************************************************************************/
  389.    
  390. int mark_text(window,ent,text,repeat)
  391.                     /*******   FORMAL  PARAMETERS   *******/
  392.      WINDOW      *window;        /* where to read/write              */
  393. register ENT_DEF  *ent;            /* entry for file to be deleted          */
  394.      char      *text;        /* from mark_repeat              */
  395.      u_short  repeat;        /* set if called by mark_repeat()     */
  396.  
  397. {    /*** mark_text ***/
  398.                     /********   LOCAL  VARIABLES   ********/
  399. register COM_DEF  *tptr;        /* temporary command structure ptr    */
  400.      int      length;        /* length of string read in          */
  401.      char      buf[TEXT_MAX+1];    /* array for text descriptor          */
  402.  
  403.  
  404.    buf[0] = '\0';            /* reset the buffer              */
  405.  
  406.    /* first put the character that marks the maximum number of characters
  407.     * that can be specified for the text descriptor
  408.     */
  409.  
  410.    if(!repeat)
  411.       prompt_getstr(window,"Text descriptor: ",buf,main_rows,TEXT_MAX);
  412.    else
  413.       strcpy(buf,text);            /* use text descrip from mark_repeat  */
  414.  
  415.    length = strlen(buf);        /* make sure it's not too long          */
  416.  
  417.    /* ok, we have the text descriptor; determine if we need to allocate a
  418.     * command structure for this file or if one already exists from a
  419.     * previous command
  420.     */
  421.  
  422.    if(ent->command == NULL)
  423.    {
  424.       /* we need command structure; allocate it and link it to the file entry */
  425.  
  426.       tptr = new_comm();
  427.  
  428.       if(tptr == NULL)
  429.      return(FAILURE);        /* problems allocating memory          */
  430.  
  431.       ent->command = tptr;        /* link it to the file entry          */
  432.    }
  433.    else
  434.       tptr = ent->command;        /* else use the one already there     */
  435.  
  436.    /* is there already enough room to store the text descriptor?
  437.     * if there is, just reuse the memory we already have; otherwise,
  438.     * allocate some new memory
  439.     */
  440.  
  441.    if(length > tptr->text_len)
  442.    {
  443.       /* we need more memory; first free up any old memory if there was any */
  444.  
  445.       if(tptr->text_len != 0)
  446.      free(tptr->text);
  447.  
  448.       /* allocate some memory to hold the text descriptor AND the null char */
  449.  
  450.       tptr->text = (char *) malloc((u_int) (length + 1));
  451.  
  452.       if(tptr->text == NULL)
  453.      exit(CANT_ALLOCATE);
  454.  
  455.       tptr->text_len = length;        /* we have a new length              */
  456.    }
  457.  
  458.    if(length)
  459.       strcpy(tptr->text,buf);        /* copy it to its resting place          */
  460.    else
  461.       tptr->text = NULL;
  462.  
  463.    /* set the command in the command structure */
  464.  
  465.    tptr->comm_text = TRUE;
  466.    tptr->comm_del = FALSE;        /* text descriptor implies no delete  */
  467.  
  468.    return(SUCCESS);
  469.  
  470. }    /*** mark_text ***/
  471.  
  472. /*******************************************************************************
  473. ********************************************************************************
  474.  
  475.   Function:      mark_protect
  476.  
  477.   Purpose:      The selected file is to be reprotected; allocate the memory
  478.         for the command structure (if necessary), link it to the file
  479.         entry,    and set the command in the command structure.
  480.  
  481.   Global variables:
  482.                           
  483.     Name            Examine/Modify/Use/Read/Write
  484.     ----            -----------------------------
  485.     main_rows                X
  486.  
  487.   Return Codes:
  488.  
  489.     Code            Reason
  490.     ----            ------
  491.     SUCCESS
  492.     FAILURE
  493.  
  494. ********************************************************************************
  495. *******************************************************************************/
  496.  
  497. int mark_protect(window,ent,prot,repeat)
  498.                     /*******   FORMAL  PARAMETERS   *******/
  499.      WINDOW      *window;        /* where to read/write              */
  500. register ENT_DEF  *ent;            /* entry for file to be deleted          */
  501.      u_short  prot,            /* from mark_repeat()              */
  502.           repeat;        /* set if called from mark_repeat()   */
  503.  
  504. {    /*** mark_protect ***/
  505.                     /********   LOCAL  VARIABLES   ********/
  506. register COM_DEF  *tptr;        /* temporary command structure ptr    */
  507.      u_short  prot_val;        /* temporary protection value          */
  508.      char      buf[PROT_INP_MAX+1];    /* array for protection string          */
  509.  
  510.  
  511.    if(!repeat)
  512.    {
  513.       buf[0] = '\0';            /* initialize input buffer          */
  514.  
  515.       /* prompt for and read in the protection string */
  516.  
  517.       prompt_getstr(window,"Protection: ",buf,main_rows,PROT_INP_MAX);
  518.  
  519.       /* if nothing was specified for the protection string, just return from
  520.        * right here
  521.        */
  522.  
  523.       if(*buf == '\0')
  524.      return(SUCCESS);
  525.  
  526.       squeeze_str(buf);            /* squeeze the blanks out          */
  527.  
  528.       /* now determine if the protection string specified is valid */
  529.  
  530.       if(prot_str_to_val(buf,&prot_val) == FAILURE)
  531.       {
  532.      /* maybe it's an absolute number; try to convert it */
  533.  
  534.      if(prot_abs_to_val(buf,&prot_val) == FAILURE)
  535.         return(FAILURE);        /* invalid protection string          */
  536.       }
  537.    }
  538.    else
  539.       prot_val = prot;            /* use value from mark_repeat()          */
  540.  
  541.    /* at this point, the protection string has been edited and is considered
  542.     * valid; get the integer value for the protection string and store it in
  543.     * in the command structure; first, do we need a command structure or does
  544.     * the file have one from a previous command?
  545.     */
  546.  
  547.    if(ent->command == NULL)
  548.    {
  549.       /* we need command structure; allocate it and link it to the file entry */
  550.  
  551.       tptr = new_comm();
  552.  
  553.       if(tptr == NULL)
  554.      return(-1);            /* problems allocating memory          */
  555.  
  556.       ent->command = tptr;        /* link it to the file entry          */
  557.    }
  558.    else
  559.       tptr = ent->command;        /* else use the one already there     */
  560.  
  561.    tptr->comm_prot = 1;            /* set the command in the structure   */
  562.    tptr->prot = add_filetype(ent->type,prot_val);
  563.    tptr->comm_del = 0;            /* protection implies no delete          */
  564.  
  565.    return(SUCCESS);            /* fine.........              */
  566.  
  567. }    /*** mark_protect ***/
  568.  
  569. /*******************************************************************************
  570. ********************************************************************************
  571.  
  572.   Function:      mark_cancel
  573.  
  574.   Purpose:      Cancel all commands for the specified file entry and deallocate
  575.         the command structure for the file.
  576.  
  577.   Global variables:
  578.                           
  579.     Name            Examine/Modify/Use/Read/Write
  580.     ----            -----------------------------
  581.     none
  582.  
  583.   Return Codes:
  584.  
  585.     Code            Reason
  586.     ----            ------
  587.       0            completed successfully
  588.      -1            problems allocating memory
  589.  
  590. ********************************************************************************
  591. *******************************************************************************/
  592.  
  593. void mark_cancel(ent)
  594.                     /*******   FORMAL  PARAMETERS   *******/
  595.      ENT_DEF  *ent;            /* file entry pointer              */
  596.  
  597. {    /*** mark_cancel ***/
  598.  
  599.  
  600.    if(ent->command != NULL)
  601.    {
  602.       /* first free up any memory that might be  holding character strings */
  603.  
  604.       free_comstr(ent->command);
  605.  
  606.       ent->command = NULL;         /* no more structure for file entry   */
  607.    }
  608.  
  609.    return;
  610.  
  611. }    /*** mark_cancel ***/
  612.  
  613. /*******************************************************************************
  614. ********************************************************************************
  615.  
  616.   Function:      mark_repeat
  617.  
  618.   Purpose:      Repeat the last command on the current file.
  619.  
  620.   Global variables:
  621.                           
  622.     Name            Examine/Modify/Use/Read/Write
  623.     ----            -----------------------------
  624.     none
  625.  
  626.   Return Codes:
  627.  
  628.     Code            Reason
  629.     ----            ------
  630.     SUCCESS
  631.     FAILURE
  632.  
  633. ********************************************************************************
  634. *******************************************************************************/
  635.  
  636. int mark_repeat(window,ent,prev_ptr,command)
  637.                     /*******   FORMAL  PARAMETERS   *******/
  638.      WINDOW      *window;        /* needed to pass along              */
  639.      ENT_DEF  *ent,            /* what is to be marked              */
  640.           *prev_ptr;        /* where to find previous mark          */
  641.      u_short  command;        /* command to be used              */
  642.  
  643. {    /*** mark_repeat ***/
  644.                     /********   LOCAL  VARIABLES   ********/
  645.      COM_DEF  *comm_ptr;        /* previous entry's commands          */
  646.      int      retval;        /* return value                  */
  647.  
  648.  
  649.    comm_ptr = prev_ptr->command;
  650.  
  651.    switch(command)
  652.    {
  653.       case(DELETE):
  654.  
  655.      retval = mark_delete(ent);
  656.      break;
  657.  
  658.       case(PROTECT):
  659.  
  660.      retval = mark_protect(window,ent,comm_ptr->prot,TRUE);
  661.      break;
  662.  
  663.       case(RENAME):
  664.  
  665.      retval = mark_copy_ren(window,ent,RENAME,comm_ptr->ren_name,TRUE);
  666.      break;
  667.  
  668.       case(COPY):
  669.  
  670.      retval = mark_copy_ren(window,ent,COPY,comm_ptr->copy_name,TRUE);
  671.      break;
  672.  
  673.       case(OWNER):
  674.  
  675.      retval = mark_owner(window,ent,comm_ptr->owner,TRUE);
  676.      break;
  677.  
  678.       case(GROUP):
  679.  
  680.      retval = mark_group(window,ent,comm_ptr->group,TRUE);
  681.      break;
  682.  
  683.       case(TEXT):
  684.  
  685.      retval = mark_text(window,ent,comm_ptr->text,TRUE);
  686.      break;
  687.  
  688.       default:
  689.      break;
  690.    }
  691.  
  692.    return(retval);
  693.  
  694. }    /*** mark_repeat ***/
  695.  
  696. /*******************************************************************************
  697. ********************************************************************************
  698.  
  699.   Function:      mark_group
  700.  
  701.   Purpose:      Prompt for the new group of the file and look it up in the
  702.         group file.  If it doesn't exist, just use the numeric version.
  703.  
  704.   Global variables:
  705.                           
  706.     Name            Examine/Modify/Use/Read/Write
  707.     ----            -----------------------------
  708.     main_rows                X
  709.  
  710.   Return Codes:
  711.  
  712.     Code            Reason
  713.     ----            ------
  714.     SUCCESS
  715.     FAILURE
  716.     BAD_GROUP        invalid group specified
  717.  
  718. ********************************************************************************
  719. *******************************************************************************/
  720.  
  721. int mark_group(window,ent,group,repeat)
  722.                     /*******   FORMAL  PARAMETERS   *******/
  723.      WINDOW      *window;        /* where to read/write              */
  724.      ENT_DEF  *ent;            /* file entry pointer              */
  725.      gid_t      group;        /* from mark_repeat()              */
  726.      u_short  repeat;        /* set if called by mark_repeat()     */
  727.  
  728. {    /*** mark_group ***/
  729.                     /********   LOCAL  VARIABLES   ********/
  730. struct     group      *gid_ptr;        /* from getgrnam()              */
  731.      COM_DEF  *tptr;        /* temporary pointer              */
  732.      char      *tptr2;        /* for checking for digit string      */
  733.      gid_t      gid;            /* temporary group id holder          */
  734.      char      buf[ID_STR_MAX+1];    /* for getting group string          */
  735.  
  736.  
  737.    if(!repeat)
  738.    {
  739.       prompt_getstr(window,"Change group to: ",buf,main_rows,ID_STR_MAX);
  740.  
  741.       if(*buf == '\0')
  742.      return(SUCCESS);
  743.  
  744.       /* see if the group is valid */
  745.  
  746.       gid_ptr = getgrnam(buf);
  747.  
  748.       if(gid_ptr == NULL)
  749.       {
  750.      /* not found, try to use numeric value */
  751.  
  752.      tptr2 = buf;
  753.  
  754.      /* skip leading blanks first */
  755.  
  756.      while(isspace(*tptr2))
  757.         ++tptr2;
  758.  
  759.      while(*tptr2 && isdigit(*tptr2))
  760.         ++tptr2;
  761.  
  762.      if(*tptr2 != '\0')
  763.         return(BAD_GROUP);
  764.  
  765.      /* it's ok; change it to a integer and store it */
  766.  
  767.      gid = (gid_t) atoi(buf);
  768.       }
  769.       else
  770.      gid = gid_ptr->gr_gid;        /* found; use it              */
  771.    }
  772.    else
  773.       gid = group;            /* use group from mark_repeat()          */
  774.  
  775.    if(ent->command == NULL)
  776.    {
  777.       /* we need command structure; allocate it and link it to the file entry */
  778.  
  779.       tptr = new_comm();
  780.  
  781.       if(tptr == NULL)
  782.      return(FAILURE);        /* problems allocating memory          */
  783.  
  784.       ent->command = tptr;        /* link it to the file entry          */
  785.    }
  786.    else
  787.       tptr = ent->command;        /* else use the one already there     */
  788.  
  789.    tptr->comm_grp = 1; 
  790.    tptr->group = gid;
  791.    tptr->comm_del = 0;            /* Group implies !Delete          */
  792.  
  793.    return(SUCCESS);
  794.  
  795. }    /*** mark_group ***/
  796.  
  797. /*******************************************************************************
  798. ********************************************************************************
  799.  
  800.   Function:      mark_owner
  801.  
  802.   Purpose:      Prompt for the new owner of the file and look it up in the
  803.         passwd file.  If it doesn't exist, just use the numeric version.
  804.  
  805.   Global variables:
  806.                           
  807.     Name            Examine/Modify/Use/Read/Write
  808.     ----            -----------------------------
  809.     main_rows                X
  810.  
  811.   Return Codes:
  812.  
  813.     Code            Reason
  814.     ----            ------
  815.     SUCCESS
  816.     FAILURE
  817.     BAD_OWNER        invalid owner specified
  818.  
  819. ********************************************************************************
  820. *******************************************************************************/
  821.  
  822. int mark_owner(window,ent,owner,repeat)
  823.                     /*******   FORMAL  PARAMETERS   *******/
  824.      WINDOW      *window;        /* where to read/write              */
  825.      ENT_DEF *ent;            /* file entry pointer              */
  826.      uid_t      owner;        /* from mark_repeat()              */
  827.      u_short  repeat;        /* set if called by mark_repeat()     */
  828.  
  829. {    /*** mark_owner ***/
  830.                     /********   LOCAL  VARIABLES   ********/
  831. struct     passwd      *uid_ptr;        /* from getpwnam()              */
  832.      COM_DEF  *tptr;        /* temporary pointer              */
  833.      char      *tptr2;        /* for checking for digit string      */
  834.      uid_t      uid;            /* temporary group id holder          */
  835.      char      buf[ID_STR_MAX+1];    /* for getting group string          */
  836.  
  837.  
  838.    if(!repeat)
  839.    {
  840.       prompt_getstr(window,"Change owner to: ",buf,main_rows,ID_STR_MAX);
  841.  
  842.       if(*buf == '\0')
  843.      return(SUCCESS);
  844.  
  845.       /* see if the owner is valid */
  846.  
  847.       uid_ptr = getpwnam(buf);
  848.  
  849.       if(uid_ptr == NULL)
  850.       {
  851.      /* not found, try to use numeric value */
  852.  
  853.      tptr2 = buf;
  854.  
  855.      /* skip leading blanks first */
  856.  
  857.      while(isspace(*tptr2))
  858.         ++tptr2;
  859.  
  860.      while(*tptr2 && isdigit(*tptr2))
  861.         ++tptr2;
  862.  
  863.      if(*tptr2 != '\0')
  864.         return(BAD_OWNER);
  865.  
  866.      /* it's ok; change it to a integer and store it */
  867.  
  868.      uid = (uid_t) atoi(buf);
  869.       }
  870.       else
  871.      uid = uid_ptr->pw_uid;        /* found; use it              */
  872.    }
  873.    else
  874.       uid = owner;            /* use owner from mark_repeat()          */
  875.  
  876.    if(ent->command == NULL)
  877.    {
  878.       /* we need command structure; allocate it and link it to the file entry */
  879.  
  880.       tptr = new_comm();
  881.  
  882.       if(tptr == NULL)
  883.      return(FAILURE);        /* problems allocating memory          */
  884.  
  885.       ent->command = tptr;        /* link it to the file entry          */
  886.    }
  887.    else
  888.       tptr = ent->command;        /* else use the one already there     */
  889.  
  890.    tptr->comm_own = 1; 
  891.    tptr->owner = uid;
  892.    tptr->comm_del = 0;
  893.  
  894.    return(SUCCESS);
  895.  
  896. }    /*** mark_owner ***/
  897.  
  898. /*******************************************************************************
  899. ********************************************************************************
  900.  
  901.   Function:      prot_abs_to_val
  902.  
  903.   Purpose:      See if a string is an absolute protection mode and calculate
  904.         the integer value if possible.
  905.  
  906.   Global variables:
  907.                           
  908.     Name            Examine/Modify/Use/Read/Write
  909.     ----            -----------------------------
  910.     none
  911.  
  912.   Return Codes:
  913.  
  914.     Code            Reason
  915.     ----            ------
  916.     SUCCESS
  917.     FAILURE
  918.  
  919. ********************************************************************************
  920. *******************************************************************************/
  921.  
  922. static short prot_abs_to_val(buffer,mode)
  923.                     /*******   FORMAL  PARAMETERS   *******/
  924. register char      *buffer;        /* mode string                  */
  925.      u_short  *mode;        /* where to put the mode value          */
  926.  
  927. {    /*** prot_abs_to_val ***/
  928.                     /********   LOCAL  VARIABLES   ********/
  929. register int      temp;            /* temporary mode holder          */
  930.  
  931.  
  932.    temp = 0;
  933.  
  934.    while(*buffer >= '0' && *buffer <= '7')
  935.    {
  936.       temp = (temp << 3) + (*buffer - '0');
  937.       ++buffer;
  938.    }
  939.  
  940.    while(isspace(*buffer))        /* skip any trailing whitespace          */
  941.       ++buffer;
  942.  
  943.    if(*buffer != '\0')
  944.       return(FAILURE);
  945.  
  946.    *mode = temp;
  947.    return(SUCCESS);
  948.  
  949. }    /*** prot_abs_to_val ***/
  950.