/*
	VECTOR FILE SYSTEM V1.1
		  _
	by Guru Gnosis Sahib <gnosis@brahman.nullnet.fi>

	Written in SAS/C 6.5
	Assumes 32-bit ints and no prototyping
	Caveat emptor: Most of the code is old and yucky, and it shows.

	Version history:
	V1.0  13-Jun-94  First fully functional version, limited release
    V1.1  05-Nov-94  Validate improved; Quick Validate added; some bugs in
                     ratio system fixed; considerable optimizing;
                     de-kludging of some parts of the source
*/

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <libraries/dos.h>
#include <dos/dostags.h>
#include <dos/var.h>

#define USER_MAX	250		/* Maximum users with Vector records */
#define ULTYPE_MAX	10		/* Maximum upload categories */
#define TYPE_MAX	20		/* Maximum file types */
#define TYPE_UL		1
#define TYPE_DL		2
#define MOD_HARD	1		/* Immediate, single modification to data */
#define MOD_SOFT	2		/* Modify data in memory only */
#define ERROR		-1

#define LEAVE_DESC	1
#define KILL_DESC	2
#define DEF_RATIO	1
#define MAN_RATIO	2

#define VERSION		"1.1"

struct UserData
{
	char User[20];
	int DLByte;
	int ULByte;
	int Creds;
};

struct UploadType
{
	char Name[40];
	char Path[80];
	int Level;
};

struct FileType
{
	char Name[40];
	char Path[80];
	int Ratio;
};

struct UserData ud[USER_MAX];
struct UploadType ut[ULTYPE_MAX];
struct FileType ft[TYPE_MAX];

typedef enum { L_VISITOR, L_GUEST, L_NORMAL, L_QUALIFIED, L_FRIEND,
	L_TRUSTED, L_PRIVILEGED, L_ASSISTANT, L_SUPERUSER, L_WIZARD,
	L_SYSTEM, L_DAEMON, L_UNKNOWN } lvl_id;

char *lvl_name[] = { "visitor", "guest", "normal", "qualified",	"friend",
	"trusted", "privileged", "assistant", "superuser", "wizard",
	"system", "daemon" };

int initbyte = 1000000;

/* The program */

main(int argc, char *argv[])
{
	FILE *input, *input2, *output;
	BPTR lock;

	char vectorpath[80], descpath[80], ulpath[80], user[80], file[80],
		newfile[80], lastuser[80], editor[80], temp[256], foo[80];
	char *ptr, c;
	struct tm *tp;
 	time_t t;
	int ud_max = 1, ut_max = 0, ft_max = 0, def_ratio = 5, junk = 0;
	int access, lastdate, lastbyte, date, type, flag, byte, i, j,
		desc_type, ratio_type;

	if(!stricmp(argv[1], "?") || !stricmp(argv[1], "-h") ||
		!stricmp(argv[1], "-?")) help();

/* Get env variables */

	GetVar("user", user, 80, GVF_LOCAL_ONLY);
	GetVar("accesslevel", temp, 80, GVF_LOCAL_ONLY);
	GetVar("visual", editor, 80, GVF_LOCAL_ONLY);
	access = get_level(temp);

/* Initialize */
	
	strcpy(vectorpath, "AXsh:etc/vector/");
	strcpy(descpath, "AXsh:etc/ffe/");
	strcpy(ulpath, "Storage:Temp/");
	if(!strcmp(editor, "")) strcpy(editor, "editor");

/* Parse rc.vector */

	if(!(input = fopen("AXsh:etc/rc.vector", "r")))
		std_error("AXsh:etc/rc.wrap not found!");
	while(!feof(input))
	{
		fgets(temp, 80, input);
		if(temp[0] == '%')
		{
			if(!(strnicmp(temp, "%vectorpath:", 12)))
			{
				fgets(vectorpath, 80, input);
				vectorpath[strlen(vectorpath) - 1] = 0;
			}
			if(!(strnicmp(temp, "%uploadpath:", 12)))
			{
				fgets(ulpath, 80, input);
				ulpath[strlen(ulpath) - 1] = 0;
			}
			if(!(strnicmp(temp, "%initbyte:", 10)))
			{
				fscanf(input, "%d", &initbyte);
			}
			if(!(strnicmp(temp, "%uploadtype:", 12)))
			{
				flag = TRUE;
				while(flag == TRUE)
				{
					fgets(temp, 80, input);
					if(strlen(temp) < 3 || feof(input)) flag = FALSE;
					else
					{
						sscanf(temp, "%s %s %s", ut[ut_max].Name,
							ut[ut_max].Path, foo);
						i = get_level(foo);
						if(access >= i)
						{
							ut[ut_max].Level = i;
							ut_max++;
						}
					}
				}
			}
			if(!(strnicmp(temp, "%filetype:", 10)))
			{
				flag = TRUE;
				while(flag == TRUE)
				{
					fgets(temp, 80, input);
					if(strlen(temp) < 3 || feof(input)) flag = FALSE;
					else
					{
						sscanf(temp, "%s %s %d", ft[ft_max].Name,
							ft[ft_max].Path, &ft[ft_max].Ratio);
						ft_max++;
					}
				}
			}
		}
	}
	fclose(input);

/* Parse arguments: User commands */

	if(!stricmp(argv[1], "stat"))
	{
		if(argc > 2)
		{
			if(access < L_ASSISTANT)
				puts("Extra arguments ignored.");
			else
			{
				strcpy(user, argv[2]);
				printf("User %s - ", user);
			}
		}		

		byte = get_ratio(vectorpath, user);
		if(byte == 0)
		{
			puts("No files uploaded or downloaded.");
			exit(0);
		}
		printf("File credits: %d bytes (%d kilobytes)\n", byte, byte / 1024);
		exit(0);
	}

	if(!stricmp(argv[1], "check"))
	{
		byte = get_ratio(vectorpath, user);
		if(byte >= 0) exit(0);
		exit(5);
	}

	if(!stricmp(argv[1], "dl"))
	{
		sprintf(temp, "%s.lastcheck", vectorpath);
		if(!(input = fopen(temp, "r")))
			std_error("Could not open .lastcheck file!");
		fscanf(input, "%d\n%d\n%s\n", &lastdate, &lastbyte, lastuser);
		fclose(input);

		ud_max = read_data(vectorpath);
		if(ud_max == ERROR)
			std_error("Could not open .ratio file!");
		t = time(NULL);
		tp = localtime(&t);

		if(!(input = fopen("AXsh:etc/adm/xpr.log", "r")))
			std_error("Could not open xpr.log!");
		fgets(temp, 80, input);		/* Header */
		fgets(temp, 80, input);		/* Empty line */
		fscanf(input, "%d %d %d %s %s", &date, &byte, &junk, user, temp);
		fgets(temp, 80, input);		/* Rest of line */
		flag = FALSE;
		while(1)
		{
			if(date == lastdate && byte == lastbyte && !strcmp(user, lastuser))
				break;
			fscanf(input, "%d %d %d %s %s", &date, &byte, &junk, user, temp);
			fgets(temp, 80, input);		/* Rest of line */
			if(feof(input))
			{
				fclose(input);
				strftime(temp, sizeof(temp)-1, "%d%m%y %H%M: Corrupted xpr.log!  Regenerating .lastcheck.", tp);
				puts(temp);
				write_check(vectorpath, date, byte, user);
				exit(0);
			}
		}
		flag = FALSE;
		while(!feof(input))
		{
			fscanf(input, "%d %d %d %s %s", &date, &byte, &junk, user, temp);
			if(!strcmp(temp, "Send"))		/* Download */
			{
				flag = TRUE;
				fscanf(input, "%s %[^\n]\n", temp, file);
				ptr = strrchr(file, '/'); /* Chop off path in need */
				if(ptr != NULL)	strcpy(file, ptr + 1);
				strftime(temp, sizeof(temp)-1, "%H%M", tp);
				printf("%06d %s: DL '%s' (%d bytes) by %s\n", date, temp, file, byte, user);
				ud_max = mod_ratio(vectorpath, user, (long) -byte, ud_max, MOD_SOFT);
					/* Substract! */
			}
			if(!strcmp(temp, "Rcvd"))		/* Upload */
			{
				flag = TRUE;
				fscanf(input, "%s %[^\n]\n", temp, file);
				ptr = strrchr(file, '/'); /* Chop off path in need */
				if(ptr != NULL)	strcpy(file, ptr + 1);
				strftime(temp, sizeof(temp)-1, "%H%M", tp);
				printf("%06d %s: UL '%s' (%d bytes) by %s\n", date, temp, file, byte, user);
			}
		}
		if(flag == FALSE)
		{
			strftime(temp, sizeof(temp)-1, "%d%m%y %H%M: No new file transfers.", tp);
			puts(temp);
		}
		fclose(input);
		if(write_data(vectorpath, ud_max) == ERROR)
			std_error("Could not modify .ratio file!");
		write_check(vectorpath, date, byte, user);
		exit(0);
	}

	puts("\nVector File System v"VERSION" by Guru Gnosis Sahib");

	if(!stricmp(argv[1], "ul"))
	{
		if(System("List >T:Vector.tmp Storage:Temp QUICK NOHEAD", TAG_END) != 0)
			std_error("Could not get file listing, aborting.");
		if(!(input = fopen("T:Vector.tmp", "r")))
			std_error("New file listing not found, aborting.");
		fgets(file, 80, input);
		sprintf(temp, "%s.newul", vectorpath);
		if(!(output = fopen(temp, "a")))
			std_error("Could not open .newul, aborting.");
		while(!feof(input))
		{
			file[strlen(file) - 1] = 0;
			printf("\nFile %s located.\n", file);
			puts("Select a category:");
			for(i = 0; i < ut_max; i++)
			{
				printf("%d) %-20s\n", i + 1, ut[i].Name,
				ft[i].Ratio);
			}
			fgets(temp, 80, stdin);
			type = (int) strtol(temp, foo, 10) - 1;
			if(type >= ut_max || type < 0)
			{
				puts("Illegal category, defaulting to 1.");
				type = 0;
			}
			sprintf(temp, "AddDesc \"%s\"", file);
			if(System(temp, TAG_END) != 0)
				std_error("AddDesc utility not found, aborting.");
			puts("Moving file...");
			sprintf(temp, "%s%s", ulpath, file);
			byte = get_size(temp);
			sprintf(temp, "Move \"%s%s\" \"%s%s\"", ulpath, file, ut[type].Path, file);
			if(System(temp, TAG_END) != 0)
				std_error("Error during file move, aborting.");
			fprintf(output, "%s %d %s%s\n", user, byte, ut[type].Path, file);
			fgets(file, 80, input);
		}
		fclose(input);
		fclose(output);
		remove("T:Vector.tmp");
		puts("\nUploads scanned.\n");
		exit(0);
	}

/* Parse arguments: Superuser commands */

	if(access < L_ASSISTANT)
	{
		puts("Access denied.");
		help();
	}

	if(!stricmp(argv[1], "award"))
	{
		if(argc < 3) help();
		strcpy(user, argv[2]);
		byte = get_ratio(vectorpath, user);
		if(byte == 0)
			puts("No files uploaded or downloaded.");
		else
			printf("File credits: %d bytes (%d kilobytes)\n", byte, byte / 1024);
		puts("Award how many credits?  Use a negative value to take away.");
		scanf("%d", &junk);
		ud_max = mod_ratio(vectorpath, user, junk, ud_max, MOD_HARD);
		if(ud_max == ERROR)
			std_error("Could not modify credits.");
		printf("Done, user now has %d bytes of credits.\n\n", byte + junk);
		exit(0);
	}
		
	if(!stricmp(argv[1], "init"))
	{
		puts("This will erase all previous records!  Are you sure? (y/N)");
		fgets(temp, 80, stdin);
		if(strnicmp(temp, "y", 1)) std_error("Aborted.");
		puts("Enter a default ratio as an integer (x bytes for each byte UL'd):");
		scanf("%d", &def_ratio);
		if(!(input = fopen("AXsh:etc/adm/xpr.log", "r")))
			std_error("Could not open xpr.log!");
		fgets(temp, 80, input);		/* Header */
		fgets(temp, 80, input);		/* Empty line */
		fscanf(input, "%d %d %d %s %s", &lastdate, &byte, &junk, user, temp);
		if(!strcmp(temp, "Rcvd"))
			type = TYPE_UL;
		else
			type = TYPE_DL;
		fgets(temp, 80, input);		/* Rest of line */
		while(!feof(input))
		{
			flag = -1;
			for(i = 0; i < ud_max; i++)
			{
				if(!strcmp(user, ud[i].User))
				{
					flag = i;
					break;
				}
			}
			if(flag == -1)
			{
				strcpy(ud[ud_max].User, user);
				if(type == TYPE_DL)
				{
					ud[ud_max].DLByte = byte;
					ud[ud_max].ULByte = 0;
				}
				else
				{
					ud[ud_max].ULByte = byte;
					ud[ud_max].DLByte = 0;
				}
				ud_max++;
			}
			else
			{
				if(type == TYPE_DL)
					ud[flag].DLByte += byte;
				else
					ud[flag].ULByte += byte;
			}				
			fscanf(input, "%d %d %d %s %s", &lastdate, &byte, &junk, user, temp);
			if(!strcmp(temp, "Rcvd"))
				type = TYPE_UL;
			else
				type = TYPE_DL;
			fgets(temp, 80, input);		/* Rest of line */
		}
		fclose(input);
		puts("\nVector xpr.log scan results:\n");
		for(i = 1; i < ud_max; i++)
		{
			ud[i].Creds = ud[i].ULByte * def_ratio - ud[i].DLByte + initbyte;
			printf("%-12s: %10d b UL %10d b DL %10d b creds\n",
				ud[i].User, ud[i].ULByte, ud[i].DLByte, ud[i].Creds);
		}
		puts("\nSaving ratios...");
		if(write_data(vectorpath, ud_max) == ERROR)
			std_error("Could not create .ratio file!");

		puts("Saving other data...");
		if(write_check(vectorpath, lastdate, byte, user) == FALSE)
			std_error("Could not update .lastcheck!");

		puts("Done!\n");
		exit(0);
	}

	if(!stricmp(argv[1], "new"))
	{
		sprintf(temp, "%s.newul", vectorpath);
		if(!(input = fopen(temp, "r")))
			std_error("No new uploads.\n");
		puts("New uploads:");
		fscanf(input, "%s %d %[^\n]", user, &byte, foo);
		while(!feof(input))
		{
			printf("\nUploaded by %s: \"%s\", %d bytes\n", user, foo, byte);
			puts("Description:");
			ptr = strrchr(foo, '/'); /* Chop off path in need */
			if(ptr != NULL)	strcpy(file, ptr + 1);
			sprintf(temp, "%s%s.dsc", descpath, file);
			if(!(input2 = fopen(temp, "r")))
				puts("None found");
			else
			{
				fgets(temp, 80, input2);
				while(!feof(input2))
				{
					if(strlen(temp) > 1) printf("%s", temp);
					fgets(temp, 80, input2);
				}
				fclose(input2);
			}
			fscanf(input, "%s %d %[^\n]", user, &byte, foo);
		}
		exit(0);
	}

	if(!stricmp(argv[1], "scan"))
	{
		sprintf(temp, "%s.newul", vectorpath);
		if(!(input = fopen(temp, "r")))
			std_error("No new uploads.\n");
		puts("Scanning for new uploads...");
		fscanf(input, "%s %d %[^\n]", user, &byte, foo);
		while(!feof(input))
		{
			ptr = strrchr(foo, '/'); /* Chop off path */
			strcpy(file, ptr + 1);
			printf("\nUploaded by %s: \"%s\", %d bytes\n", user, file, byte);
			if((lock = Lock(foo, ACCESS_READ)) == 0)
				puts("File not found!  Skipping to next one...");
			else
			{
				UnLock(lock);
				puts("Description:");
				sprintf(temp, "%s%s.dsc", descpath, file);
				if(!(input2 = fopen(temp, "r")))
					puts("None found");
				else
				{
					fgets(temp, 80, input2);
					while(!feof(input2))
					{
						if(strlen(temp) > 1) printf("%s", temp);
						fgets(temp, 80, input2);
					}
					fclose(input2);
				}
				puts("(V)alidate, (Q)uick Validate, (D)elete, (I)gnore, or (A)bort?");
				fgets(temp, 80, stdin);
				switch(tolower(temp[0]))
				{
				case 'a':
					puts("Aborting, no changes made to new uploads list.");
					fclose(input);
					exit(0);

				case 'i':
					puts("Ignored: no credits awarded, file not affected.");
					break;

				case 'd':				
					puts("Deleting file and description...\n");
					if(remove(foo) != 0)
						std_warn("Could not delete file");
					sprintf(temp, "%s%s.dsc", descpath, file);
					if(remove(temp) != 0)
						std_warn("Could not delete description");
					break;

				case 'v':
					puts("Modify description? (y/N)");
					fgets(temp, 80, stdin);
					if(!strnicmp(temp, "y", 1))
					{
						sprintf(temp, "%s \"%s%s.dsc\"", editor, descpath, file);
						if(System(temp, TAG_END) != 0)
							std_error("Could not edit description");
					}

					puts("Rename file? (y/N)");
					fgets(temp, 80, stdin);
					if(!strnicmp(temp, "y", 1))
					{
						puts("Enter a new filename:");
						fgets(newfile, 80, stdin);
						newfile[strlen(newfile) - 1] = 0;
						sprintf(temp, "Move \"%s%s.dsc\" \"%s%s.dsc\"", descpath, file, descpath, newfile);
						if(System(temp, TAG_END) != 0)
							std_error("Could not rename file description");
						strcpy(file, newfile);
					}

					/* FALL THRU */

				case 'q':
					strcpy(newfile, file);
					puts("\n\
A) Move to any directory, leave desc, default ratio\n\
B) Move to any directory, leave desc, manual ratio\n\
C) Move to any directory, delete desc, default ratio\n\
D) Move to any directory, delete desc, manual ratio\
					");

					for(i = 0; i < ft_max; i++)
					{
					printf("%d) Type %-20s (ratio %2d:1)\n", i + 1, ft[i].Name,
							ft[i].Ratio);
					}
					puts("\nSelect a category:");
					fgets(temp, 80, stdin);
					c = toupper(temp[0]);
					switch(c)
					{
					case 'A':
						ratio_type = DEF_RATIO;
						desc_type = LEAVE_DESC;
						break;

					case 'B':
						ratio_type = MAN_RATIO;
						desc_type = LEAVE_DESC;
						break;

					case 'C':
						ratio_type = DEF_RATIO;
						desc_type = KILL_DESC;
						break;

					case 'D':
						ratio_type = MAN_RATIO;
						desc_type = KILL_DESC;
						break;
					}
					j = (int) strtol(temp, lastuser, 10) - 1;
					i = j;
					if(i == -1)	/* ABCD */
					{
						i = TYPE_MAX - 1;
						puts("Enter full path for file: (include / or :)");
						fgets(temp, 80, stdin);
						temp[strlen(temp) - 1] = 0;
						strcpy(ft[i].Path, temp);
						if(ratio_type == MAN_RATIO)
						{
							puts("Enter ratio for file:");
							fgets(temp, 80, stdin);
							ft[i].Ratio = strtol(temp, temp, 10);
						}
						else ft[i].Ratio = def_ratio;

						if(desc_type == KILL_DESC)
						{
							sprintf(temp, "%s%s.dsc", descpath, newfile);
							if(remove(temp) != 0)
								std_warn("Could not delete description");
						}
					}
					puts("Adding credits...");
					sprintf(temp, "Move \"%s\" \"%s%s\"", foo, ft[i].Path, newfile);
					if(System(temp, TAG_END) != 0)
						std_error("Could not move file");
					ud_max = mod_ratio(vectorpath, user, byte * ft[i].Ratio, ud_max, MOD_HARD);
					if(ud_max == ERROR)
						std_error("Could not update ratio");
					printf("%d bytes awarded.\n", byte * ft[i].Ratio);
					break;

				default:
					junk = -1;
				}
			}
			if(junk == 0)
				fscanf(input, "%s %d %[^\n]", user, &byte, foo);
			else
				junk = 0;
		}
		fclose(input);
		puts("Scan complete.");
		sprintf(temp, "%s.newul", vectorpath);
		remove(temp);
		exit(0);
	}
	puts("Invalid arguments!");
	help();
}

/* Subprograms for access to ratio file, either in memory (MOD_SOFT) or
   on disk (MOD_HARD) */

get_ratio(char path[80], char user[80])
{
	FILE *input;
	char temp[80];
	long creds = 0, flag = FALSE;

	sprintf(temp, "%s.ratio", path);
	input = fopen(temp, "r");
	if(input)
	{
		while(!feof(input))
		{
			fscanf(input, "%s %d", temp, &creds);
			if(!stricmp(temp, user))
			{
				flag = TRUE;
				break;
			}
		}
		fclose(input);
	}
	if(flag == FALSE) return(0);
	return(creds);
}

make_ratio(char path[80], char user[80], long cred, int ud_max, int type)
{
	FILE *output;
	char temp[80];

	if(type == MOD_HARD)
	{
		sprintf(temp, "%s.ratio", path);
		if(!(output = fopen(temp, "a")))
			return(FALSE);
		fprintf(output, "%s %d\n", user, cred + initbyte);
		fclose(output);
	}
	else
	{
		strcpy(ud[ud_max].User, user);
		ud[ud_max].Creds = cred + initbyte;
		ud_max++;
	}
	return(ud_max);
}

mod_ratio(char path[80], char user[80], long newcred, int ud_max, int type)
{
	FILE *input, *output;
	char temp[80];
	long cred = 0, flag = FALSE, i;

	if(type == MOD_HARD)
	{
		sprintf(temp, "%s.ratio", path);
		if(!(input = fopen(temp, "r")))
		{
			puts("Error: Could not open ratio data file");
			return(ERROR);
		}
		if(!(output = fopen("PIPE:Vector.TMP", "w")))
		{
			fclose(input);
			puts("Error: Could not open temporary file");
			return(ERROR);
		}		
		while(!feof(input))
		{
			fscanf(input, "%s %d", temp, &cred);
			if(!feof(input))
			{
				if(!stricmp(temp, user))
				{
					fprintf(output, "%s %d\n", temp, cred + newcred);
					flag = TRUE;
				}
				else
					fprintf(output, "%s %d\n", temp, cred);
			}
		}
		fclose(input);
		fclose(output);
		if(flag == FALSE)
		{
			ud_max = make_ratio(path, user, newcred, ud_max, MOD_HARD);
			if(ud_max == FALSE)
				std_error("Could not create new record");
		}
		else
		{
			sprintf(temp, "Copy PIPE:Vector.TMP %s.ratio", path);
			System(temp, TAG_END);
		}
	}
	else
	{
		flag = ERROR;
		for(i = 0; i < ud_max; i++)
		{
			if(!strcmp(user, ud[i].User))
			{
				flag = i;
				break;
			}
		}
		if(flag == ERROR)
		{
			ud_max = make_ratio(path, user, newcred, ud_max, MOD_SOFT);
			if(ud_max == FALSE)
				std_error("Could not create new user record");
		}
		else
			ud[flag].Creds += newcred;
	}
	return(ud_max);
}

read_data(char path[80])
{
	FILE *input;
	char temp[80];
	int ud_max = 0;

	sprintf(temp, "%s.ratio", path);
	if(!(input = fopen(temp, "r"))) return(ERROR);
	while(!feof(input))
	{
		fscanf(input, "%s %d\n", ud[ud_max].User, &ud[ud_max].Creds);
		ud_max++;
		if(ud_max == USER_MAX)
		{
			fclose(input);
			std_error("Too many users with records, consult documentation.");
		}	
	}
	fclose(input);
	return(ud_max);
}

write_data(char path[80], int ud_max)
{
	FILE *input;
	char temp[80];
	int i;

	sprintf(temp, "%s.ratio", path);
	if(!(input = fopen(temp, "w")))	return(ERROR);
	for(i = 0; i < ud_max; i++)
	{
		fprintf(input, "%s %d\n", ud[i].User, ud[i].Creds);
	}
	return(TRUE);
}

/* Other subprograms */

write_check(char path[80], int date, int byte, char user[80])
{
	FILE *output;
	char temp[80];

	sprintf(temp, "%s.lastcheck", path);
	if(!(output = fopen(temp, "w"))) return(ERROR);
	fprintf(output, "%d\n%d\n%s\n", date, byte, user);
	fclose(output);
	return(TRUE);
}

get_size(char file[80])
{
	int size, fd;
	
	fd = open(file, O_RDONLY);
	size = lseek(fd, 0L, 2);
	close(fd);
	return(size);
}

get_level(char *temp)
{
	int lvl;

	for(lvl = 0; lvl < L_UNKNOWN; lvl++)
	{
		if(!stricmp(temp, lvl_name[lvl])) break;
	}
	return(lvl);
}

help()
{
	puts("Syntax: (normal)    Vector [check | dl | stat | ul]");
	puts("        (superuser) Vector [award | init | new | scan]");
	puts("Consult documentation for more info.\n");
	exit(0);
}

std_warn(char *temp)
{
	printf("Warning: %s\n", temp);
}

std_error(char *temp)
{
	printf("Warning: %s\n", temp);
	exit(5);
}
