/* adduser : add a new user account          */
/* Craig Hagan                               */
/*                                           */
/* pardon the kludge..written during         */
/* commercials of star trek tng              */
/*                                           */
/* to compile, you need crypt.o from poe-IGL */
/* gcc -O -o adduser adduser.c crypt.o       */



#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/time.h>
#include <time.h>

#define PASSWD_FILE "/etc/passwd"
#define DEBUG

char *crypt();

main()
{
  char foo[32];			

  /* a user read in from /etc/passwd this */
  /* to see if the username is in use     */				

  char uname[32];

  /* the username that is being added */

  char person[32];

  /* the personal name of the user being added */

  char passwd[32];

  /* the password of the user being added */

  char dir[255];

  /* the directory of the person being added */

  char shell[255];

  /* the new user's shell */

  char line[255];

  /* a line from the /etc/passwd file */

  unsigned int group,uid;

  /* the group and uid of the new user */

  int bad=0,done=0,correct=0,gets_warning=0;

  /* flags, in order: */
  /* bad to see if the username is in /etc/passwd, or if strange stuff has */
  /*     been typed if the user might be put in group 0 */
  /* done allows the program to exit when a user has been added */
  /* correct loops until a password is found that isn't in /etc/passwd */
  /* gets_warning allows the fflush to be skipped for the first gets */
  /*     so that output is still legible */

  char	salt[2];
  
  /* the salt (part of the password encryption */

  time_t tm;

  /* another part of the pw encryption */

  FILE *passwd_file;

/*************************************************************************/

  while(!correct)		/* loop until a "good" uname is chosen */
    {				/* good = not in /etc/passwd */
      while(!done)
	{
	  printf("\nUsername to add: ");

	  if(gets_warning)	/* if the warning was already shown */
	    fflush(stdout);	/* fflush stdout, otherwise set the flag */
	  else
	    gets_warning=1;

	  gets(uname);
	  printf("[%s]\n",uname);

	  passwd_file=fopen(PASSWD_FILE,"r");
	  while(!feof(passwd_file) && !bad)  /* here I check the /etc/passwd */
	    {			 
	      fgets(line,100,passwd_file);
	      strcpy(foo,strtok(line,":"));

	      /* see if the chosen username matches the one on the */
	      /* current line                                      */

	      bad=!strcmp(foo,uname);

	      /* next, bitch if the dummy line is still around */

	      if(!strcmp(foo,"---------------------dummy line\n"))
		 {
		   printf("please remove the dummy line in /etc/passwd\n");
		   exit(-1);
		 }
	    }
	  fclose(passwd_file);
	  done=!bad;
	  
	  if(bad)		/* the uname is in /etc/passwd */
	    {
	      printf("That name is in use, choose another.\n");
	      bad=0;
	    }
	}

      /* all set, get the rest of the stuff */

      printf("\n%s's personal name : ",uname);
      fflush(stdout);
      gets(person);
      
      bad=1;			/* reset bad flag, more input may be needed */
      while(bad)
	{
	  printf("%s's group : ",uname);
	  fflush(stdout);
	  scanf("%d",&group);
	  gets(foo);

	  bad=group==0;
	  if (group==0)
	    {

	      /* if the user is in group 0, confirm it */

	      printf("\nGive %s superuser privs? [y|n] : ",uname);
	      fflush(stdout);
	      gets(foo);

	      bad=((foo[0]!='Y')&&(foo[0]!='y'));
	    }	      
	}

      printf("\n%s's uid : ",uname);
      fflush(stdout);
      scanf("%d",&uid);
      gets(foo);

      printf("\n%s's home directory: [/usr/users/%s] : ",uname,uname);
      fflush(stdout);
      gets(dir);

      if (!strcmp(dir,""))
	sprintf(dir,"/usr/users/%s",uname);
      fflush(stdin);

      printf("Default dir is [%s] \n",dir);
      printf("\n%s's default shell : [/bin/sh] : ",uname);
      fflush(stdout);
      gets(shell);
      
      if (!strcmp(shell,""))
	sprintf(shell,"/bin/sh");
      printf("Default shell is [%s]\n",shell);
      
      printf("\n%s's defualt password : [%s] : ",uname,uname);
      fflush(stdout);
      gets(passwd);

      if (!strcmp(passwd,""))
	sprintf(passwd,"%s",uname);
      {
	time(&tm);
	salt[0] = (tm & 0x0f) +	'A';
	salt[1] = ((tm & 0xf0) >> 4) + 'a';
      }
  
      printf("\n\nCreate user [%s]\n",uname);
      printf("In directory, [%s],\n",dir);
      printf("with [%s] as a default shell,\n",shell);
      printf("and [%s], for a password.\n",passwd);
      printf("\nIs this correct? [y|n] : ");
      fflush(stdout);
      gets(foo);

      done=bad=correct=(foo[0]=='Y'||foo[0]=='y');      
    }

  printf("Making directory, [%s].\n",dir);
  mkdir(dir,0700);

  passwd_file=fopen(PASSWD_FILE,"a");
  fprintf(passwd_file,"%s:%s:%d:%d:%s:%s:%s\n"
	  ,uname,crypt(passwd, salt),group,uid,person,dir,shell);

  /* make sure that they own their directory -- its kinda nice :) */

  chown(dir,uid,group);


}
  
