/* 
#  This is version 0.3 of absent
#
#               Copyright (c) 1999 by AT&T.
#  Permission to use, copy, and modify this software without fee is
#  hereby granted, provided that this entire notice is included in all
#  copies of any software which is or includes a copy or modification
#  of this software and in all copies of the supporting documentation
#  for such software.
#
#  SOME PARTS OF ABSENT MAY BE RESTRICTED UNDER UNITED STATES EXPORT
#  REGULATIONS.
#
#  THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
#  IMPLIED WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE
#  ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
#  MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
#  PURPOSE.
*/
#include "user_table.h"
#include <malloc.h>

/* This routine write a user's entry to a file by the
   same name as the user. On failure, return -1. */

int write_user(name, entry) 
char *name;
user_entry *entry;

{
  int user_file;
  int nbytes;
  struct flock lock;
  char *path_file;
  int length;
  int result;
  
  if(strchr(name, '.') || strchr(name, '/'))
    return -1;
 
  lock.l_type = F_WRLCK;
  lock.l_start = 0;
  lock.l_whence = 0;
  lock.l_len = 0;
  
  if(strchr(name, '.') || strchr(name, '/'))
     return -1;
  if(!(path_file=(char *)malloc(strlen(USER_DIR)+strlen(name)+2)))
    return -1;
  sprintf(path_file, "%s/%s", USER_DIR, name);
 
   user_file = open(path_file , O_WRONLY | O_CREAT,S_IRWXU );
   if (user_file == -1) {
      result = creat(path_file, 0660 );
      if (result == -1) {
         printf("Could not open nor create %s\n",path_file);
	 free(path_file);
         return(-1);
      }

      user_file = open(path_file , O_WRONLY,S_IRWXU );
      if (user_file == -1) {
         printf("Could not open nor create %s\n",path_file);
	 free(path_file);
         return(-1);
      }
   }
   free(path_file);
   fcntl(user_file, F_SETLK, &lock);

   /* Write out the whole entry, and then the fields that are
      done with pointers */

   nbytes = write(user_file, entry, sizeof(user_entry));

   length = strlen(entry->opie_entry.opie_principal);
   nbytes += write(user_file, &length, sizeof(int));
   nbytes += write(user_file, entry->opie_entry.opie_principal, length);

   length = strlen(entry->opie_entry.opie_seed);
   nbytes += write(user_file, &length, sizeof(int));
   nbytes += write(user_file, entry->opie_entry.opie_seed, length);

   length = strlen(entry->opie_entry.opie_val);
   nbytes += write(user_file, &length, sizeof(int));
   nbytes += write(user_file, entry->opie_entry.opie_val, length);

   lock.l_type = F_UNLCK;
   fcntl(user_file, F_SETLK, &lock);
   close(user_file);

   return(nbytes);
}




/* Pass in a name and an entry (allocated), and populates it
   with the entry from the file.

   Anyone who calls this should free up that memory  */

int read_user_entry(name, entry) 
char *name;
user_entry *entry;

{
int user_file;
int nbytes;
struct flock lock;
char *path_file;
int length;
char *principal;
char *seed;
char *val;

   lock.l_type = F_RDLCK;
   lock.l_start = 0;
   lock.l_whence = 0;
   lock.l_len = 0;

   if(strchr(name, '.') || strchr(name, '/'))
     return -1;
   
   if(!(path_file=(char *)malloc(strlen(USER_DIR)+strlen(name)+2)))
     return -1;
   sprintf(path_file, "%s/%s", USER_DIR, name);
   user_file = open(path_file, O_RDONLY);
   free(path_file);

   if (user_file == -1) {
      return(-1);
   }

   fcntl(user_file, F_SETLK, &lock);

   nbytes = read(user_file, entry, sizeof(user_entry));

   nbytes += read(user_file, &length, sizeof(int));
   principal = (char *) malloc(length+1);
   nbytes += read(user_file, principal, length);
   principal[length] = 0;
   entry->opie_entry.opie_principal = principal;

   nbytes += read(user_file, &length, sizeof(int));
   seed = (char *) malloc(length+1);
   nbytes += read(user_file, seed, length);
   seed[length] = 0;
   entry->opie_entry.opie_seed = seed;

   nbytes += read(user_file, &length, sizeof(int));
   val = (char *) malloc(length+1);
   nbytes += read(user_file, val, length);
   val[length] = 0;
   entry->opie_entry.opie_val = val;


   lock.l_type = F_UNLCK;
   fcntl(user_file, F_SETLK, &lock);
   close(user_file);

   return(nbytes);

}


