/******************************************************************************
  *
  * Function Name: read_line
  *
  * Description: get one line from /etc/passwd file.  If there is a line contains
  *              more than LINE_MAX characters, it will ignore it and read the
  *              next line.  It also handles continuation character '\'. It always
  *              leaves (or inserts) \n\0 at the end of the line.
  *              
  * Parameters:
  *     FILE *f:       file ptr points to /etc/passwd file
  *     char *buffer:  char array
  *     size_t bufeln: length of buffer
  *
  * Return Value:
  *     int : It returns the length of the line read, excluding the \n\0.
  *
  ******************************************************************************/
 static int read_line(
     FILE        *f,
     char        *buffer,
     size_t      buflen)
 {
         int                     linelen = 0;
         char                    c;
         int curlen = 0;
         char *ret, *tempbuf;
         tempbuf = buffer;
         while (1) {
                 tempbuf += (unsigned)curlen;
                 /* buffer over flow, skip this long line */
                 if (tempbuf >= (buffer + buflen - 1))
                 {
                           do {
                                   c = getc(f);
                                   if (feof(f)) {
                                           return (-1);
                                   }
                           } while (c != '\n');
                           linelen = 0;
                           tempbuf = buffer;
                           curlen = 0;
                 }
                 ret = fgets(tempbuf, linelen == 0 ?
                         buflen : buflen - (unsigned)linelen, f);
                 curlen = strlen(ret);
                 linelen += curlen;
                 switch (ret == NULL ? EOF : ret[curlen - 1]) {
                 case EOF:
                          if (linelen == 0 ) {
                          /* The file was empty */
                                 linelen = -1;
                          } else if (buffer[linelen] == '\\') {
                          /* We expected another line to append to previous
                             line as indicated by a trailing backslash, but the
                             file ended */
                                 linelen = -1;
                           } else {
                           /* The file contained one line, and all is well */
                                 buffer[linelen     ] = '\n';
                                 buffer[linelen + 1 ] = '\0';
                           }
                           return (linelen);
                 case '\n':
                           if (curlen > 1 &&
                                 ret[curlen - 2] == '\\') {
                                 curlen -= 2;
                                 linelen -= 2;
                           } else {
                                 ret[curlen - 1] = '\n';
                                 ret[curlen    ] = '\0';
                                 return (linelen - 1);
                           }
                           break;
                 default:
                           break;
                 } /* case */
         }
         /*NOTREACHED*/
 }
 /******************************************************************************
  *
  * Function Name: gettok
  *
  * Description: parse one line read from /etc/passwd file, return pointer to the
  *              next passwd entry field
  * Parameters:
  *     char **line_addr:  address of the pointer that point to an array
  *
  * Return Value:
  *     char *p : pointer to an array
  *
  *****************************************************************************/
 static char *gettok (char **line_addr)
 {
     char    *q = *line_addr;
     char    *p = q;
     while (*p && *p != ':' && *p != '\n')
         p++;
     if (*p == '\n')
       *p = '\0';
     else if (*p != '\0')
       *p++ = '\0';
     *line_addr = p;
     return (q);
 }
 /******************************************************************************
  *
  * Function Name: rm_leading_and_trailing_blank
  *
  * Description:  Removes all the leading and trialing blanks in a string token.
  *               A string "  This is a test   " will be formatted to
  *               "This is a test"
  *
  *               Cases like empty character string and character string with
  *               just a space or spaces are also covered. A string "       "
  *               will be reduced to ""
  *
  * Parameters:
  *    target_string:     string token.
  *
  * Return Value:         None
  *
  *****************************************************************************/
 static void rm_leading_and_trailing_blank(char *target_string)
 {
     char * mover   = target_string;
     char * current = target_string;
     while (*mover != '\0' && (*mover == ' ' || *mover == '\t'))
            mover++;
     while(*mover)
         {
               *current = *mover;
               current++, mover++;
         }
     *current = '\0';
     current--;
     while ( current >= target_string &&
              (*current == ' ' || *current == '\t' || *current == '\n'))
         {
           *current='\0';
           current--;
         }
 }