#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

static char saltchars[64] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";

static void
usage()
{
	fprintf(stderr, "pwencrypt [-s <salt>] <password>\n");
}

int
main(int argc, char *argv[])
{
	extern int opterr;
	extern int optopt;
	extern int optind;
	extern char *optarg;
	char *optstring = "s:";
	char option;
	char* salt = '\0';
	char* encrypted = '\0';
	char* em;
	int i;
	struct stat sb;
	char random_salt[3];

	opterr = 0;

	while ( (option = getopt(argc, argv, optstring)) != EOF)
	{
		switch (option)
		{
			case 's':
				salt = optarg;
				break;
			case '?':
				if (strchr(optstring, optopt) == '\0')
					fprintf(stderr, "option %c not recognized\n", optopt);
				else
					fprintf(stderr, "option %c requires an argument\n", optopt);

				exit(1);
			default:
				exit(1);
		}
	}

	if (optind >= argc)
	{
		fprintf(stderr, "missing password argument\n");
		usage();
		exit(1);
	}
	
	if (salt == '\0')
	{
		if (stat(argv[0], &sb) == -1)
		{
			em = strerror(errno);
			fprintf(stderr, "stat(%s) failed : %s\n", argv[0], (em) ? em : "");
			exit(1);
		}

		srand(time('\0') + sb.st_ino);

		for (i = 0; i < 2; ++i)
		{
			random_salt[i] = saltchars[rand() % 64];
		}

		random_salt[2] = '\0';
		salt = random_salt;
	}

	encrypted = crypt(argv[optind], salt);

	if (encrypted == '\0')
	{
		em = strerror(errno);
		fprintf(stderr, "crypt() failed : %s\n", (em) ? em : "");
		exit(1);
	}

	printf("%s\n", encrypted);

	return 0;
}

