Logo Search packages:      
Sourcecode: casu version File versions  Download package

fileio.c

/*
 *  CaSU - communications & status utilities.
 *  Copyright (C) 1992, 1993, 1994 Luke Mewburn <lm@rmit.edu.au>
 *    incorporating:
 *       flon - lists your friends who are logged on.
 *       to - send a short message to a friend
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include "casu.h"

/*
 *    compare_utmp
 */

int
compare_utmp(entry1, entry2)
    const void *entry1, *entry2;
{
    /*
     * first, weight the null umtp entries so that they get
     * moved to the higher end of the list.
     */

    if (   NULL_UTMP_ENTRY((utmp_s *) entry1)
      && NULL_UTMP_ENTRY((utmp_s *) entry2))
      return 0;
    if (NULL_UTMP_ENTRY((utmp_s *) entry1))
      return 1;
    if (NULL_UTMP_ENTRY((utmp_s *) entry2))
      return -1;
      /* otherwise, just return with normal comparison values. */
    return(strncmp(( (utmp_s *) entry1)->ut_name,
                ((utmp_s *) entry2)->ut_name, UT_NAMESIZE));
} /* compare_utmp */


/*
 *    compare_friends
 */

int
compare_friends(entry1, entry2)
    const void *entry1, *entry2;
{
      /* just compare the name fields of the friends entry. */
    return (strcmp(((frend *) entry1)->name, ((frend *) entry2)->name));
} /* compare_friends */


/*
 *    compare_users
 */

int
compare_users(entry1, entry2)
    const void *entry1, *entry2;
{
      /* just compare the username fields */
    return (strcmp(((upwd *) entry1)->username, ((upwd *) entry2)->username));
} /* compare_users */


/*
 *    get_utmp
 */

void
get_utmp(sort_required)
    int sort_required;
{
    struct stat   statbuf;
    int           utmp_fd;
    long    filesiz;

      /* prepare to read file into large chunk of memory */
    if ((utmp_fd = open(utmp_file, O_RDONLY, 0)) == -1)
      errexit(strerror(errno), utmp_file);
    if (fstat(utmp_fd, &statbuf)== -1)
      errexit(strerror(errno), utmp_file);
    filesiz=(long) statbuf.st_size;
    if ((utmp_list = (utmp_s *) malloc(filesiz+1)) == NULL)
      errexit(strerror(errno), NULL);

      /* read in the utmp file in one chunk */
    if ((filesiz=read(utmp_fd, (char *) utmp_list, statbuf.st_size))==-1)
      errexit(strerror(errno), utmp_file);

      /* terminate the list, and close the file. */
    ((char *) utmp_list)[filesiz]='\0';
    if (close(utmp_fd) == -1)
      errexit(strerror(errno), utmp_file);

      /* sort the file, and set utmp_count to the # of valid entries */
    filesiz /= sizeof(utmp_s);      /* num entries in list */
    if (sort_required)
    {
      nqsort(utmp_list, filesiz, sizeof(utmp_s), compare_utmp);
      for (utmp_count=0;
           !(NULL_UTMP_ENTRY(&utmp_list[utmp_count]));
           utmp_count++)
          if (utmp_count >= filesiz)
            break;
    }
    else
      utmp_count = filesiz;
} /* get_utmp */



/*
 *    get_friends
 */

void
get_friends(frfile)
    char *frfile;
{
    char    *tfb, *ffbufr, f_path[MAXPATHLEN], *envhome;
    struct stat   stbufr;
    int           loop, ffd;
    long    filesiz;

    f_path[0]='\0';
    /*
     * If frfile is not null, assume this is a user specified
     * friends file, otherwise, get $HOME/.friends
     */
    if (frfile == NULL)
    {
            /* XXX: maybe this could use pwent->pw_dir, not $HOME */
      if ((envhome=getenv(STRhome)) == NULL)
          errexit("Undefined variable", "HOME");
      strcat(f_path, envhome);
      strcat(f_path, "/");
      frfile = STRdotfriends;
    }

      /* dump out if the resultant path will be too long. */
    if ((int)strlen(f_path) + (int)strlen(frfile) >= MAXPATHLEN)
      errexit("Path too long", frfile);
    strcat(f_path, frfile);

    /*
     * open and fstat the file, and malloc ram for the entire
     * thing. Note, I use the open()/fstat() combination instead of
     * the stat()/open() one, because once I have a file descriptor
     * to the file, it can't be unlinked on me
     */
    if ((ffd = open(f_path, O_RDONLY, 0)) == -1)
      if (errno == ENOENT)
      {
          friends_list=NULL;
          flags |= ALL_ON;
          return;
      }
      else
          errexit(strerror(errno), f_path);
    if (fstat(ffd, &stbufr)== -1)
      errexit(strerror(errno), f_path);
    filesiz=(long) stbufr.st_size;
    ffbufr = (char *) malloc(sizeof(char) * (filesiz+1));
    if (ffbufr == NULL)
      errexit(strerror(errno), NULL);
    if ((filesiz=read(ffd, ffbufr, stbufr.st_size))==-1)
      errexit(strerror(errno), f_path);

      /* nul terminate and close the file. */
    (ffbufr)[filesiz]='\0';
    if (close(ffd) == -1)
      errexit(strerror(errno), f_path);

    friends_count = 0;
    tfb=ffbufr;

    /*
     * break up the friends file into alternating
     * nul terminated names and pseudonyms.
     */
    while (1)
    {
      /* find the start of the name (skipping CR and spaces) */
      tfb += strspn(tfb, STRsep);
      if ( tfb >= &ffbufr[filesiz] )
          break;        /* exit if off end of buffer */
    /*  for now, ignore NULs in friends file
      if (!(*tfb))
          break;
    */
      tfb += strcspn(tfb, STRsep);
      /* got end of name. If no trailing pseudo, error occurs */
      if ( !( *tfb ) || ( tfb >= &ffbufr[filesiz] ) )
          errexit("Invalid format of friends file", NULL);
      *tfb++ = '\0';          /* ok, got name.... */

      /* find start of pseudonym, skipping all white space */
      tfb += strspn(tfb, STRsep);
      if ( !( *tfb ) || ( tfb > &ffbufr[filesiz] ) )
          errexit("Invalid format of friends file", NULL);
      /*
       * get \n terminated pseudonym (spaces are allowed in
       * pseudonyms...), and nul terminate it. increment
       * friends counter.
       */
      tfb += strcspn(tfb, STReoln);
      if (!(*tfb))
          break;
      *tfb++ = '\0';                /* got pseudo */
      friends_count++;
    }

    /*
     * return memory if the friends file has no friends in it.
     * (they could have a 5K file of whitespaces ... :-)
     */
    if (!friends_count)
    {
      free(ffbufr);
      return;
    }

      /* create the list of frend entries, and assign all the pointers */
    friends_list = (frend *) malloc (friends_count * sizeof(frend));
    if (friends_list == NULL)
      errexit(strerror(errno), NULL);

    tfb=ffbufr;
    for (loop=0; loop <friends_count; loop++)
    {
      tfb += strspn(tfb, STRsep);
      if (!(*tfb))
          break;
      strnc0py(friends_list[loop].name, tfb, UT_NAMESIZE);
      while ( *tfb )
          tfb++;
      tfb++;

      tfb += strspn(tfb, STRsep);
      friends_list[loop].pseudo = tfb;
      while ( *tfb )
          tfb++;
      tfb++;
    }
      /* sort the friends list, and return. */
    nqsort(friends_list, friends_count, sizeof(frend), compare_friends);
} /* get_friends() */


#if !USE_GETPWENT
/*
 *    get_passwd
 */

void
get_passwd(pwfile)
    char *pwfile;
{
    char    *pwbufr, *tfb;
    int           pwfd, loop;
    long    filesiz;
    struct stat stbufr;

    /*
     * open and fstat the file, and malloc ram for the entire
     * thing. Note, I use the open()/fstat() combination instead of
     * the stat()/open() one, because once I have a file descriptor
     * to the file, it can't be unlinked on me
     */
    if ((pwfd = open(pwfile, O_RDONLY, 0)) == -1)
      errexit(strerror(errno), pwfile);
    if (fstat(pwfd, &stbufr)== -1)
      errexit(strerror(errno), pwfile);
    filesiz=(long) stbufr.st_size;
    if ((pwbufr = (char *) malloc(filesiz+1)) == NULL)
      errexit(strerror(errno), pwfile);
    if ((filesiz=read(pwfd, pwbufr, stbufr.st_size))==-1)
      errexit(strerror(errno), pwfile);

    (pwbufr)[filesiz]='\0';
    if (close(pwfd) == -1)
      errexit(strerror(errno), pwfile);

    tfb=pwbufr;
    pw_count = 0;

    /*
     * break up the passwd file into alternating
     * nul terminated usernames, uid's, and realnames
     */

    while (1)
    {
            /* find end of username */
      tfb += strcspn(tfb, PWsep);
      *tfb = '\0';      /* ok, got name.... */
      if ( ++tfb > &pwbufr[filesiz])
          break;

            /* skip password */
      tfb += strcspn(tfb, PWsep) + 1;

            /* find end of uid */
      tfb += strcspn(tfb, PWsep);
      *tfb = '\0';      /* ok, got uid.... */
      if ( ++tfb > &pwbufr[filesiz])
          break;

            /* skip gid */
      tfb += strcspn(tfb, PWsep) + 1;

            /* find end of 1st part of GCOS (i.e, real name) */
      tfb += strcspn(tfb, PWGCOSsep);
      *tfb = '\0';      /* ok, got name.... */
      if ( ++tfb > &pwbufr[filesiz])
          break;

      tfb += strcspn(tfb, PWeoln);
      *tfb = '\0';      /* ok, got end of line */
      if ( ++tfb > &pwbufr[filesiz] )
          break;
      pw_count++;
    }

      /* create the list of upwd entries, and assign all the pointers */
    pw_list = (upwd *) malloc (pw_count * sizeof(upwd));
    if (pw_list == NULL)
      errexit(strerror(errno), NULL);

    tfb=pwbufr;
    for (loop=0; loop <pw_count; loop++)
    {
      pw_list[loop].username=tfb;   /* get start of username */
      while ( *tfb )
          tfb++;
      tfb++;                        /* at password */

      tfb += strcspn(tfb, PWsep) + 1;     /* at uid */

      pw_list[loop].uid = (uid_t) atoi(tfb);    /* get uid */
      while ( *tfb )
          tfb++;
      tfb++;                        /* at gid */

      tfb += strcspn(tfb, PWsep) + 1;     /* at gcos */

                              /* get real name */
      pw_list[loop].gcos = tfb;
      while ( *tfb )
          tfb++;
      tfb++;                        /* at end of realname */

      while ( *tfb )
          tfb++;
      tfb++;                        /* at end of line */
    }

      /* sort the password file on username */
    nqsort(pw_list, pw_count, sizeof(upwd), compare_users);
} /* get_passwd() */

#endif /* USE_GETPWENT */

Generated by  Doxygen 1.6.0   Back to index