home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume26 / maint / part03 / text.c < prev    next >
C/C++ Source or Header  |  1992-05-13  |  20KB  |  652 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 dealing with text descriptors.
  13.  
  14.    Arguments:    See individual routines
  15.  
  16.    External variables:    See individual routines
  17.  
  18.    External functions:
  19.  
  20.           Defined:    create_text, put_text, read_text_des, text_match,
  21.             text_search
  22.  
  23.           Called:    clear_mess, get_name, get_pool_mem, prompt_getstr,
  24.             put_pool, strindex
  25.  
  26.    Files accessed:
  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. #include <stdio.h>
  46. #ifdef ultrix
  47. #include <cursesX.h>
  48. #else
  49. #include <curses.h>
  50. #endif
  51. #include <string.h>
  52. #include "maint.h"
  53.  
  54. /******************************************************************************/
  55. /*                                                                            */
  56. /*                             # D E F I N E S                                */
  57. /*                                                                            */
  58. /******************************************************************************/
  59.  
  60. /******************************************************************************/
  61. /*                                                                            */
  62. /*          S T R U C T U R E S ,   U N I O N S ,   T Y P E D E F S           */
  63. /*                                                                            */
  64. /******************************************************************************/
  65.  
  66. /******************************************************************************/
  67. /*                                                                            */
  68. /*   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    */
  69. /*                                                                            */
  70. /******************************************************************************/
  71.  
  72. extern     int      main_rows;
  73.  
  74. extern     char      *get_pool_mem();
  75.  
  76. extern     int      strindex();
  77.  
  78. extern     void      put_pool(),
  79.           prompt_getstr(),
  80.           clear_mess(),
  81.           *get_name();
  82.  
  83.      char      *text_search(),
  84.           *text_match();
  85.  
  86.      int      read_text_des(),
  87.           create_text();
  88.  
  89.      void      put_text();
  90.  
  91. /******************************************************************************/
  92. /*                                                                            */
  93. /*     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      */
  94. /*                                                                            */
  95. /******************************************************************************/
  96.  
  97. /*******************************************************************************
  98. ********************************************************************************
  99.  
  100.   Function:    read_text_des
  101.  
  102.   Purpose:    Attempt to read in the text descriptors from the text des-
  103.         criptor file for the current directory.
  104.  
  105.   Global variables:
  106.  
  107.     Name            Examine/Modify/Use/Read/Write
  108.     ----            -----------------------------
  109.     none
  110.  
  111.   Return Codes:
  112.  
  113.     Code            Reason
  114.     ----            ------
  115.     NO_FILE            file does not exist
  116.     CANT_OPEN        cannot open MAINT.TDF file
  117.     BAD_FILE        bad text descriptor file
  118.      0            text descriptor file successfully read
  119.  
  120.   Termination Codes:
  121.  
  122.     Code            Reason
  123.     ----            ------
  124.      none
  125.  
  126. ********************************************************************************
  127. *******************************************************************************/
  128.  
  129. int read_text_des(dirptr,curr_pool,dir_text,pool_length,num_file)
  130.                     /*******   FORMAL  PARAMETERS   *******/
  131. register ENT_DEF  *dirptr;        /* pointer to directory entries          */
  132.      POOL_DEF **curr_pool;        /* pointer to pointer to current pool */
  133.      char      **dir_text;        /* directory text descriptor array    */
  134.      size_t      pool_length;        /* length of pool to allocate          */
  135.      short      num_file;        /* number of files in directory          */
  136.  
  137. {    /*** read_text_des ***/
  138.                     /********   LOCAL  VARIABLES   ********/
  139.      FILE      *fptr;        /* text file pointer              */
  140.      ENT_DEF  *currptr;        /* current entry for searching          */
  141.      int      length;        /* length of string              */
  142.      char      *tptr,        /* temporary character pointer          */
  143.            *status,        /* return code status holder          */
  144.           *temp,
  145.           text_buf[TEXT_REC_MAX+10];
  146.  
  147.  
  148.    /* open the text descriptor file */
  149.  
  150.    fptr = fopen(TEXT_FILE,"r");
  151.  
  152.    if(fptr == NULL)
  153.       return(NO_FILE);            /* no problem; just no file          */
  154.  
  155.    /* get the first record; this is the text descriptor for the directory;
  156.     * the format for this record is
  157.     *    >>><text descriptor for directory>
  158.     */
  159.  
  160.    status = fgets(text_buf,TEXT_REC_MAX+1,fptr);
  161.  
  162.    if(status == NULL)
  163.    {
  164.       *dir_text = NULL;
  165.       fclose(fptr);
  166.       return(CANT_OPEN);
  167.    }
  168.  
  169.    /* make sure this record is in the right form */
  170.  
  171.    if(strindex(text_buf,">>>") != 0)
  172.    {
  173.       /* close the text descriptor file */
  174.  
  175.       fclose(fptr);
  176.       return(BAD_FILE);
  177.    }
  178.  
  179.    /* store this in the memory pools and set the dir_text pointer to point
  180.     * to it
  181.     */
  182.  
  183.    length = strlen(text_buf);
  184.    text_buf[length - 1] = '\0';        /* lop off the \n              */
  185.  
  186.    put_pool(dir_text,curr_pool,&text_buf[3],strlen(&text_buf[3]),pool_length);
  187.  
  188.    /* skip the comment lines in the text descriptor file */
  189.  
  190.    status = fgets(text_buf,TEXT_REC_MAX+1,fptr);
  191.  
  192.    while(status != NULL && text_buf[0] == '>')
  193.       status = fgets(text_buf,TEXT_REC_MAX+1,fptr);
  194.  
  195.    if(status == NULL)
  196.    {
  197.       fclose(fptr);
  198.       return(SUCCESS);            /* end-of-file here....              */
  199.    }
  200.  
  201.    /* now get each text descriptor record and match it up with a filename */
  202.  
  203.    /* set the current file entry pointer to actually pointer to one entry
  204.     * BEFORE the current entry; it will be updated inside text_search to
  205.     * point to the correct entry; this is done so that text_search can be
  206.     * more general
  207.     */
  208.  
  209.    currptr = dirptr - 1;             /* set where we start to look          */
  210.  
  211.    while(status != NULL)
  212.    {                         
  213.       /* search for a match with the filename in the text descriptor record */
  214.  
  215.       length = strlen(text_buf);
  216.       text_buf[length - 1] = '\0';
  217.  
  218.       if((tptr = text_search(dirptr,&currptr,text_buf,num_file)) != NULL)
  219.       {
  220.      /* match; store the text descriptor in a memory pool */
  221.  
  222. /*     put_pool(&(currptr->text),curr_pool,tptr,(size_t) strlen(tptr),
  223.           pool_length);*/
  224.      put_pool(&temp,curr_pool,tptr,(size_t) strlen(tptr),
  225.           pool_length);
  226.      currptr->text = temp;
  227.       }
  228.  
  229.       status = fgets(text_buf,TEXT_REC_MAX+1,fptr);
  230.    }
  231.  
  232.    fclose(fptr);
  233.    return(SUCCESS);            /* everything done              */
  234.  
  235. }    /*** read_text_des ***/
  236.  
  237. /*******************************************************************************
  238. ********************************************************************************
  239.  
  240.   Function:    text_search
  241.  
  242.   Purpose:    Search the directory entries for a match with the current
  243.         text descriptor record.  If one is found, return a pointer
  244.         to the actual text of the text descriptor and update the
  245.         current directory entry pointer to point to the NEXT entry
  246.         to check for a text descriptor match.
  247.  
  248.   Global variables:
  249.  
  250.     Name            Examine/Modify/Use/Read/Write
  251.     ----            -----------------------------
  252.     none
  253.  
  254.   Return Codes:
  255.  
  256.     Code            Reason
  257.     ----            ------
  258.     retval            pointer to actual text of text descriptor
  259.     NULL            no match for text descriptor
  260.  
  261.   Termination Codes:
  262.  
  263.     Code            Reason
  264.     ----            ------
  265.      none
  266.  
  267. ********************************************************************************
  268. *******************************************************************************/
  269.  
  270. char *text_search(dirptr,currptr,text_rec,num_file)
  271.                     /*******   FORMAL  PARAMETERS   *******/
  272.      ENT_DEF  *dirptr,        /* pointer to all directory entries   */
  273.            **currptr;        /* pointer to current directory entry */
  274.      char      *text_rec;        /* current text descriptor record     */
  275.      short      num_file;        /* number of files in directory          */
  276.  
  277. {    /*** text_search ***/
  278.                     /********   LOCAL  VARIABLES   ********/
  279. register ENT_DEF  *ptr;            /* current file entry pointer          */
  280.      ENT_DEF  *origptr;        /* original directory pointer          */
  281.      char      *retval;        /* return value                  */
  282.      u_long      curr_index;        /* index value for setting pointer    */
  283.  
  284.  
  285.    /* get pointer to directory that we need; this is the one following
  286.     * (modulo the number of files in the directory) the entry that we
  287.     * were on the last time through
  288.     */
  289.  
  290.    curr_index = *currptr - dirptr;    /* get current entry index          */
  291.    curr_index = (curr_index + 1L) % (u_long) num_file;
  292.  
  293.    ptr = dirptr + curr_index;        /* get pointer to the NEW entry          */
  294.  
  295.    /* first check to see if we have a match with the current entry */
  296.  
  297.    if((retval = text_match(ptr->filename,text_rec)) != NULL)
  298.    {
  299.       /* we have a match; return the pointer to the beginning of the
  300.        * actual text of the text descriptor AND update the currptr
  301.        * return value to point to the next entry so that the next time
  302.        * this routine is called, we can start up one after where we
  303.        * left off here
  304.        */
  305.  
  306.       *currptr = ptr;            /* return pointer to current entry    */
  307.       return(retval);            /* match....                  */
  308.    }
  309.  
  310.    /* no match with the current entry; search the entries until 1) we find a
  311.     * a match, or until we have examined all of the entries
  312.     */
  313.  
  314.    origptr = ptr;            /* save where we are right now          */
  315.    curr_index = (curr_index + 1L) % (u_long) num_file;
  316.    ptr = dirptr + curr_index;
  317.  
  318.    while(ptr != origptr)        /* until we are back where we started */
  319.    {
  320.       /* check for a match */
  321.  
  322.       if((retval = text_match(ptr->filename,text_rec)) != NULL)
  323.       {
  324.      /* we have a match; return the pointer to the beginning of the
  325.       * actual text of the text descriptor AND update the currptr
  326.       * return value to point to the current directory entry so that
  327.       * we know where we left off last time through
  328.       */
  329.  
  330.      *currptr = ptr;
  331.      return(retval);
  332.       }
  333.  
  334.       /* update the current entry pointer to point to the next entry */
  335.  
  336.       curr_index = (curr_index + 1L) % (u_long) num_file;
  337.       ptr = dirptr + curr_index;
  338.    }
  339.  
  340.    return(NULL);            /* no match for this text descriptor  */
  341.  
  342. }    /*** text_search ***/
  343.  
  344. /*******************************************************************************
  345. ********************************************************************************
  346.  
  347.   Function:    text_match
  348.  
  349.   Purpose:    Determine if a text descriptor record is the correct one
  350.         for a file entry.
  351.  
  352.   Global variables:
  353.  
  354.     Name            Examine/Modify/Use/Read/Write
  355.     ----            -----------------------------
  356.     none
  357.  
  358.   Return Codes:
  359.  
  360.     Code            Reason
  361.     ----            ------
  362.  
  363.     NULL            no match for text descriptor record
  364.     text_rec + 1L        pointer to beginning of text descriptor part
  365.                 of the record
  366.  
  367.   Termination Codes:
  368.  
  369.     Code            Reason
  370.     ----            ------
  371.      none
  372.  
  373. ********************************************************************************
  374. *******************************************************************************/
  375.  
  376. char *text_match(filename,text_rec)
  377.                     /*******   FORMAL  PARAMETERS   *******/
  378. register char      *filename,        /* filename to look for              */
  379.           *text_rec;        /* current text descriptor record     */
  380.  
  381. {    /*** text_match ***/
  382.  
  383.  
  384.    while((*filename == *text_rec) && (*filename != '\0'))
  385.    {
  386.       filename++;
  387.       text_rec++;
  388.    }
  389.  
  390.    /* now check to see if we had a match */
  391.  
  392.    if(*text_rec == ' ')
  393.    {
  394.       /* return a pointer to the beginning of the text descriptor */
  395.  
  396.       return(text_rec + 1L);
  397.    }
  398.  
  399.    return(NULL);            /* not correct record for file          */
  400.  
  401. }    /*** text_match ***/
  402.  
  403. /*******************************************************************************
  404. ********************************************************************************
  405.  
  406.   Function:    put_text
  407.  
  408.   Purpose:    Put the text descriptor for the directory on the screen.
  409.  
  410.   Global variables:
  411.  
  412.     Name            Examine/Modify/Use/Read/Write
  413.     ----            -----------------------------
  414.     COLS                    X
  415.  
  416.   Return Codes:
  417.  
  418.     Code            Reason
  419.     ----            ------
  420.     SUCCESS            Everything fine
  421.     FAILURE            Error parsing new filename
  422.  
  423. ********************************************************************************
  424. *******************************************************************************/
  425.  
  426. void put_text(window,text_desc)
  427.                           /*******   FORMAL  PARAMETERS   *******/
  428.      WINDOW      *window;        /* where to write              */
  429.      char      *text_desc;         /* text descriptor buffer          */
  430.  
  431. {    /*** put_text ***/
  432.                     /********   LOCAL  VARIABLES   ********/
  433.      size_t      length;        /* string length holder              */
  434. static     char      buf[MAX_SCREEN_COLS+5], /* formatting buffer              */
  435.           spaces[] =        /* spaces array for centering stuff   */
  436. "                                                                    ";
  437.  
  438.  
  439.    if(text_desc != NULL)        /* is there anything to write?          */
  440.    {
  441.       length = (COLS - strlen(text_desc))/2;
  442.       spaces[length] = '\0';          /* make spaces for centering          */
  443.       cat(5,buf,spaces,text_desc,spaces," ");
  444.       buf[COLS] = '\0';            /* make sure we have the right length */
  445.       spaces[length] = ' ';        /* reset spaces array for next time   */
  446.  
  447.       /* write directory text descriptor in reverse video at top of screen */
  448.  
  449.       mvwaddstr(window,SPEC_WINDOW_ROWS-1,0,buf);
  450.    }
  451.    else
  452.    {
  453.       /* erase the one that might be on the screen, since this directory
  454.        * doesn't have a text descriptor
  455.        */
  456.  
  457.       wmove(window,SPEC_WINDOW_ROWS-1,0);
  458.       wclrtoeol(window);
  459.    }
  460.  
  461.    wrefresh(window);
  462.    return;
  463.  
  464. }    /*** put_text ***/
  465.  
  466. /*******************************************************************************
  467. ********************************************************************************
  468.  
  469.   Function:    create_text
  470.  
  471.   Purpose:    Attempt to create the text descriptor file if the user wants
  472.         to.  The user is prompted for the text descriptor for the
  473.         directory and the file is written with the entry for the
  474.         text descriptor file itself.
  475.  
  476.   Global variables:
  477.  
  478.     Name            Examine/Modify/Use/Read/Write
  479.     ----            -----------------------------
  480.     none
  481.  
  482.   Return Codes:
  483.  
  484.     Code            Reason
  485.     ----            ------
  486.     DONT_CREATE        user does not want text descriptor file created
  487.     CANT_OPEN        error opening/writing text descriptor file
  488.     NEW_FILE        new text descriptor file created
  489.  
  490. ********************************************************************************
  491. *******************************************************************************/
  492.  
  493. int create_text(window)
  494.                     /*******   FORMAL  PARAMETERS   *******/
  495.      WINDOW      *window;        /* where to read/write              */
  496.  
  497. {    /*** create_text ***/
  498.                     /********   LOCAL  VARIABLES   ********/
  499.      FILE      *fptr;        /* text file pointer              */
  500.      char      term_code,         /* keystroke read in              */
  501.           buf[MAX_SCREEN_COLS+1], /* for all kinds of output stuff    */
  502.           text_buf[DIR_TEXT_MAX+1]; /* buffer for reading from screen */
  503.  
  504.  
  505.    sprintf(buf,"Text descriptor file %s does not exist.  Create it? [y] ",
  506.        TEXT_FILE);
  507.  
  508.    /* prompt the user to see if they want to create the text descriptor file */
  509.  
  510.    info_mess(buf);
  511.    term_code = wgetch(window);        /* get their response              */
  512.    clear_mess(window);            /* clear the prompt from the screen   */
  513.  
  514.    /* now see what key was pressed */
  515.  
  516.    if(term_code == 'N' || term_code == 'n')
  517.       return(DONT_CREATE);        /* don't create the file here, either */
  518.  
  519.    /* ok, we need to create the file; open it for writing */
  520.  
  521.    fptr = fopen(TEXT_FILE,"w");
  522.  
  523.    if(fptr == NULL)
  524.       return(CANT_OPEN);
  525.  
  526.    /* the file has been opened ok; get the descriptor for the directory,
  527.     * format it, and write it to the text descriptor file
  528.     */
  529.  
  530.    /* prompt for and read in the text descriptor for the directory itself */
  531.  
  532.    prompt_getstr(window,"Text descriptor for directory: ",text_buf,main_rows,
  533.          DIR_TEXT_MAX);
  534.  
  535.    text_buf[DIR_TEXT_MAX] = '\0';    /* make sure it's not too long          */
  536.    cat(4,buf,">>>",text_buf,"\n");    /* format it correctly              */
  537.  
  538.    /* now write the directory text descriptor record to the file */
  539.  
  540.    fputs(buf,fptr);
  541.    fputs(">\n",fptr);            /* write a spacing record          */
  542.  
  543.    /* now write the text descriptor entry for the text descriptor file
  544.     * itself; this is so the user knows what the file is when they bring
  545.     * the text descriptors in
  546.     */
  547.  
  548.    cat(3,buf,TEXT_FILE," text descriptor file\n"); 
  549.    fputs(buf,fptr);
  550.  
  551.    fclose(fptr);
  552.    return(NEW_FILE);
  553.  
  554. }    /*** create_text ***/
  555.  
  556. /*******************************************************************************
  557. ********************************************************************************
  558.  
  559.   Function:    get_text
  560.  
  561.   Purpose:    Set up and get the text descriptors for the current
  562.         directory.  Being able to update slot_width is essential
  563.         for proc_dir() and is one of the reasons this routine
  564.         exists.  slot_width is set in set_args() but set_args()
  565.         is only called from main().
  566.  
  567.   Global variables:
  568.  
  569.     Name            Examine/Modify/Use/Read/Write
  570.     ----            -----------------------------
  571.     args.text           X        X
  572.     args.text_startup       X
  573.  
  574.   Return Codes:
  575.  
  576.     Code            Reason
  577.     ----            ------
  578.     none
  579.  
  580. ********************************************************************************
  581. *******************************************************************************/
  582.  
  583. void get_text(args,dirptr,curr_pool,dir_text,mess_flag,slot_width,text_flag,
  584.           pool_length,num_file)
  585.  
  586.                     /*******   FORMAL  PARAMETERS   *******/
  587.      ARG_DEF  *args;        /* run-time arguments              */
  588.      ENT_DEF  *dirptr;        /* pointer to directory information   */
  589.      POOL_DEF **curr_pool;        /* pointer to current memory pool     */
  590.      char      **dir_text,        /* pointer to directory text descrip  */
  591.           *mess_flag;        /* set if information mess on screen  */
  592.      short      *slot_width,        /* slot width for current directory   */
  593.           *text_flag;        /* set if descrip file was processed  */
  594.      size_t      pool_length;        /* length for allocating new pools    */
  595.      short      num_file;        /* number of files in directory          */
  596.  
  597. {    /*** get_text ***/
  598.                     /********   LOCAL  VARIABLES   ********/
  599.      short      status;        /* return status from read_text_des() */
  600.  
  601.  
  602.    *text_flag = 0;
  603.  
  604.    if(args->text)
  605.    {
  606.       /* yes, read in the text descriptors */
  607.  
  608.       *text_flag = args->text;        /* set descrip flag for this direct.  */
  609.  
  610.       if(args->text == DISPLAY_TEXT && !args->text_startup)
  611.      *slot_width += TEXT_MAX + 1;    /* assume we will get text descrips   */
  612.  
  613.       status = read_text_des(dirptr,curr_pool,dir_text,pool_length,num_file);
  614.  
  615.       /* check to see if there were any problems getting the text descriptors */
  616.  
  617.       if(status == BAD_FILE)
  618.       {
  619.      info_mess("Invalid format for text descriptor file");
  620.      *mess_flag = 1;
  621.      *text_flag = 0;        /* no text descrips for directory     */
  622.  
  623.      if(args->text == DISPLAY_TEXT)    /* only update slot_width if needed   */
  624.         *slot_width = *slot_width - (TEXT_MAX + 1);
  625.  
  626.      sleep(1);
  627.       }
  628.       else if(status == CANT_OPEN)
  629.       {
  630.      info_mess("Cannot open text descriptor file");
  631.      *mess_flag = 1;
  632.      *text_flag = 0;        /* no text descrips for directory     */
  633.  
  634.      if(args->text == DISPLAY_TEXT)    /* only update slot_width if needed   */
  635.         *slot_width = *slot_width - (TEXT_MAX + 1);
  636.  
  637.      sleep(1);
  638.       }
  639.       else if(status == NO_FILE)
  640.       {
  641.      *text_flag = 0;        /* no text descrips for directory     */
  642.  
  643.      if(args->text == DISPLAY_TEXT)    /* update slot_width if it needs it   */
  644.        *slot_width = *slot_width - (TEXT_MAX + 1);
  645.       }
  646.    }
  647.  
  648.  
  649.    return;
  650.  
  651. }    /*** get_text ***/
  652.