/* SYNCREG.C - Source code for SyncRegistry 1.0.
	 Taken from SyncChat - that's why some code may seem weird, I didn't change
	 the variables around or anything, I just left it the way it was.
	 Created: 4-24-96 by Prophet (AKA Garry Dolley)

	 Ok, this is PUBLIC DOMAIN.  You can change it any way you want and
   distribute it.  You can sell it for all I care ;)  It'd be nice although
   if you gave me (Prophet) some credit for making the original version.

	 If you make something really cool out of this, let me know, I may add
	 support for it in SyncChat :)
	 Reach me on Dragonspear Castle BBS (818-240-9102 or 818-240-0318)

   BTW, I have compiled this with XSDK 2.41 without any problems.

   -Prophet
*/

#include "xsdk.h"

struct registry_struct {
uint  user_num;
char  name[31],
			sex,
			age[3],
			city_state[31],
			fav_movie[31],
			music[41],
			fav_tvshows[41],
			fav_foods[31],
			instruments[21],
			fav_sports[41],
			hobbies[51],
			general_info[5][71],
			comment[41];
};

struct registry_struct reg, r_temp, r_temp_2;

 char *l64, *l65, *l66, *l67, *l68, *l69, *l70, *l71, *l72, *l73, *l74,
						*l75, *l76, *l77, *l78, *l79, *l80, *l81, *l82, *l83, *l84, *l85,
						*l86, *l87, *l88, *l89, *l90, *l91, *l92, *l93, *l94, *l95, *l96,
						*l97, *l98, *l99, *l100, *l101, *l102, *l103, *l104, *l105,
						*l106;
/* Yeah yeah.. I know these should have been arrays of 'l', but it's a long
	 story... ;) */

void extended_info(void);
void flush_vars(struct registry_struct *reg);

void main(void)
{
  char s[256], str[256], reg_file[256], *p;
	short done = 0, i = 0, n = 0, edit_only = 0, num, feof = 0,
        recs_on_screen = 0, total_recs = 0, cur_rec = 0, match = 0;
	int fp;
	long offset;
	struct registry_struct r_tmp;

	/* Start up code ... */
	p=getenv("SBBSNODE");
		if(p)
			strcpy(node_dir,p);
		else {
			printf("\nSBBSNODE environment variable must be set\n");
			exit(0); }

	if(node_dir[strlen(node_dir)-1]!='\\')
		strcat(node_dir,"\\");
	initdata();

	/* Load up all the strings */
	l64 = (char *) MALLOC(256);
	l65 = (char *) MALLOC(256);
	l66 = (char *) MALLOC(256);
	l67 = (char *) MALLOC(256);
	l68 = (char *) MALLOC(256);
	l69 = (char *) MALLOC(256);
	l70 = (char *) MALLOC(256);
	l71 = (char *) MALLOC(256);
	l72 = (char *) MALLOC(256);
	l73 = (char *) MALLOC(256);
	l74 = (char *) MALLOC(256);
	l75 = (char *) MALLOC(256);
	l76 = (char *) MALLOC(256);
	l77 = (char *) MALLOC(256);
	l78 = (char *) MALLOC(256);
	l79 = (char *) MALLOC(256);
	l80 = (char *) MALLOC(256);
	l81 = (char *) MALLOC(256);
	l82 = (char *) MALLOC(256);
	l83 = (char *) MALLOC(256);
	l84 = (char *) MALLOC(256);
	l85 = (char *) MALLOC(256);
	l86 = (char *) MALLOC(256);
	l87 = (char *) MALLOC(256);
	l88 = (char *) MALLOC(256);
	l89 = (char *) MALLOC(256);
	l90 = (char *) MALLOC(256);
	l91 = (char *) MALLOC(256);
	l92 = (char *) MALLOC(256);
	l93 = (char *) MALLOC(256);
	l94 = (char *) MALLOC(256);
	l95 = (char *) MALLOC(256);
	l96 = (char *) MALLOC(256);
	l97 = (char *) MALLOC(256);
	l98 = (char *) MALLOC(256);
	l99 = (char *) MALLOC(256);
	l100 = (char *) MALLOC(256);
  l101 = (char *) MALLOC(256);
  l102 = (char *) MALLOC(256);
  l103 = (char *) MALLOC(256);
	l104 = (char *) MALLOC(256);
	l105 = (char *) MALLOC(256);
	l106 = (char *) MALLOC(256);

	strcpy(l64, "\1n\1gSelection: \1h\1w");
	strcpy(l65, "\1nNo profiles exist yet!  Why not add yours?\r\n");
	strcpy(l66, "\1h\1w### Name                          Comment\r\n");
	strcpy(l67, "\1h\1b-------------------------------------------------------------------------------\r\n");
	strcpy(l68, "\1h\1c%-3s \1n\1g%-29s \1h\1y%s\r\n");
	strcpy(l69, "\1h\1cEnter \1h\1wQ \1h\1cTo Quit, \1h\1wENTER \1cTo Continue, Or A \1wNumber \1cTo View: \1w");
	strcpy(l70, "\1h\1b[\1m%i \1cof \1m%i\1b]\r\n");
	strcpy(l71, "\1h\1cPress \1w[ \1cFor Previous Record, \1w] \1cFor Next Record, Or \1wQ \1cTo Quit: ");
	strcpy(l72, "\1n\1gProfile Information For \1h\1w%s\r\n");
	strcpy(l73, "\1h\1cEnter your handle or real name\r\n");
	strcpy(l74, "\1h\1cAge: ");
	strcpy(l75, "\1h\1cDescribe the type of music/bands you like\r\n");
	strcpy(l76, "\1h\1cWhat is your favorite movie?\r\n");
	strcpy(l77, "\1h\1cWhat is/are your favorite TV show(s)?\r\n");
	strcpy(l78, "\1h\1cWhat kinds of food do you like?\r\n");
	strcpy(l79, "Do you play any instruments");
	strcpy(l80, "\1h\1cWhich one(s)\r\n");
	strcpy(l81, "\1h\1cWhat are your favorite sports?\r\n");
	strcpy(l82, "\1h\1cWhat are your hobbies?\r\n");
	strcpy(l83, "\1h\1cYou now get 5 lines to write whatever you'd like\r\n");
	strcpy(l84, "\1h\1c(Describe yourself, babble, etc...)\r\n");
	strcpy(l85, "\1h\1cEnter a short comment to everyone.\r\n");
	strcpy(l86, "\1h\1cIt will be listed along with your name in short profile listings\r\n");
	strcpy(l87, "\1h\1bWriting profile...\r\n");
	strcpy(l88, "\1h\1cDone!\r\n");
	strcpy(l89, "\1h\1wThanks for taking the time to add your profile to the registry!\r\n");
	strcpy(l90, "\1h\1wOk, here's the info for \1n\1g%s\1h\1w...\r\n");
	strcpy(l91, "\1nHandle/Real Name: \1h\1c%-30s \1nSex: \1h\1c%c \1nAge: \1h\1c%s\r\n");
	strcpy(l92, "\1nCity/State: \1h\1c%s\r\n");
	strcpy(l93, "\1nFavorite Movie: \1h\1c%s\r\n");
	strcpy(l94, "\1nFavorite TV Show(s): \1h\1c%s\r\n");
	strcpy(l95, "\1nFavorite Music/Bands: \1h\1c%s\r\n");
	strcpy(l96, "\1nInstrument(s) Played: \1h\1c%s\r\n");
	strcpy(l97, "\1nFavorite Foods: \1h\1c%s\r\n");
	strcpy(l98, "\1nFavorite Sports: \1h\1c%s\r\n");
	strcpy(l99, "\1nHobbies: \1h\1c%s\r\n");
	strcpy(l100, "\1nGeneral Info (5 Lines):\1h\1c\r\n");
	strcpy(l101, "%s\r\n");
	strcpy(l102, "%s\r\n");
	strcpy(l103, "%s\r\n");
	strcpy(l104, "%s\r\n");
	strcpy(l105, "%s\r\n");
	strcpy(l106, "\1nComment: \1h\1c%s\r\n");

	do {
		if(fexist("REGISTRY.ASC"))
			{
			if(fexist("REGISTRY.ANS") && (user_misc&ANSI))
				printfile("REGISTRY.ANS");
			else
				printfile("REGISTRY.ASC");
			}
		else if(fexist("REGISTRY.ANS") && (user_misc&ANSI))
			printfile("REGISTRY.ANS");
		else {
			cls();
			bprintf("\1h\1ySyncRegistry v1.0 (\1n\1yXSDK v%s\1h\1y) \1nby Prophet - \1h\1wFREEWARE\r\n", xsdk_ver);
			CRLF;
			bprintf("\1h\1c[\1wL\1c] List Profiles (Short)\r\n");
			bprintf("\1h\1c[\1wE\1c] List Profiles (Long) \r\n");
			bprintf("\1h\1c[\1wA\1c] Add/Edit Your Profile\r\n");
      bprintf("\1h\1c[\1wS\1c] Look Up A Profile By Name\r\n");
			if(user_level >= 90)
				bprintf("\1n\1c[\1wD\1c] Delete A Profile (Ops Only)\r\n");
			bprintf("\1h\1c[\1wQ\1c] Quit\r\n");
			CRLF;
			}
		bputs(l64);
    switch(getkeys("LEASDQ\r", 0)) {
			case 'L':
				if(!fexist("REGISTRY.DAT"))
					{
					CRLF;
					bputs(l65); CRLF;
					pause();
					break;
					}
				n = 1;
				flush_vars(&reg);
				do
					{
					cls();
					bputs(l66);
					bputs(l67);
					fp = nopen("REGISTRY.DAT", O_RDONLY);
					if(fp == -1)
						{
						perror("Error [REGISTRY.DAT]");
						bprintf("\r\nError loading REGISTRY.DAT for read, please inform the SysOp!");
						break;
						}
          lseek(fp, sizeof(struct registry_struct) * (n - 1), SEEK_SET);
          recs_on_screen = 0;
					for(i = 0;
							((read(fp, &reg, sizeof(struct registry_struct)) != 0) &&
              i < 19); n++)
						{
						i++;
						itoa(n, s, 10);
            bprintf(l68, s, reg.name, reg.comment);
            recs_on_screen++;
						}
					feof = eof(fp);
					close(fp);
					CRLF;
					bputs(l69);
					num = getnum(n - 1);
          if(num == -1)
						{
						CRLF;
						break;
						}
					if(num == 0)
						{
            if(feof)
              {
              CRLF;
              break;
              }
						continue;
            }
					fp = nopen("REGISTRY.DAT", O_RDONLY);
					if(fp == -1)
						{
						perror("Error [REGISTRY.DAT]");
						bprintf("\r\nError opening REGISTRY.DAT for read, please inform the SysOp!");
						break;
						}
					offset = (num - 1) * sizeof(struct registry_struct);
					lseek(fp, offset, SEEK_SET);
					read(fp, &reg, sizeof(struct registry_struct));
					close(fp);
          extended_info();
					CRLF;
          pause();
          feof = 0;
          n = n - recs_on_screen;
          } while(!feof);
        break;
			case 'E':
				if(!fexist("REGISTRY.DAT"))
					{
					bprintf(l65);
          CRLF;
					pause();
					break;
					}
        n = 0; i = 0;
				do {
          fp = nopen("REGISTRY.DAT", O_RDONLY);
					if(fp == -1)
            {
            perror("Error [REGISTRY.DAT]");
						bprintf("\r\nError loading REGISTRY.DAT for read, please inform the SysOp!");
            break;
            }
          total_recs = filelength(fp) / ((long) sizeof(struct registry_struct));
          lseek(fp, sizeof(struct registry_struct) * n, SEEK_SET);
          cur_rec = tell(fp) / sizeof(struct registry_struct);
          read(fp, &reg, sizeof(struct registry_struct));
          close(fp);
          extended_info();
					CRLF;
          bprintf(l70, cur_rec + 1, total_recs, n);
					bputs(l71);
					switch(getkeys("][Q",0)) {
            case '[':
              n--;
							if(n < 0)
                n = 0;
							break;
            case ']':
              n++;
							if(n + 1> total_recs)
                n = total_recs - 1;
              break;
            case 'Q':
              i = 1;
              CRLF;
              break;
           }
         } while(!i);  
				break;
			case 'A':
				if(fexist("REGISTRY.DAT"))
					{
					fp = nopen("REGISTRY.DAT", O_RDONLY);
					for(i = 0; read(fp, &reg, sizeof(struct registry_struct)) != 0; i++)
						{
						if(reg.user_num == user_number)
							{
							edit_only = 1;
							offset = tell(fp);
							break;
							}
						else
              {
							edit_only = 0;
							flush_vars(&reg);
              }
						}
					close(fp);
					}
				else
					{
					edit_only = 0;
					flush_vars(&reg);
          }

				reg.user_num = user_number;
				strcpy(reg.city_state, user_location);
				reg.sex = user_sex;
				cls();
				bprintf(l72, user_name);
        CRLF;
        bputs(l73);
				getstr(reg.name, 30, K_LOWPRIO|K_EDIT|K_AUTODEL|K_LINE); CRLF;
        bputs(l74);
        getstr(reg.age, 2, K_LOWPRIO|K_EDIT|K_AUTODEL|K_LINE|K_NUMBER); CRLF;
        bputs(l75);
        getstr(reg.music, 40, K_LOWPRIO|K_EDIT|K_AUTODEL|K_LINE); CRLF;
        bputs(l76);
				getstr(reg.fav_movie, 30, K_LOWPRIO|K_EDIT|K_AUTODEL|K_LINE); CRLF;
        bputs(l77);
				getstr(reg.fav_tvshows, 40, K_LOWPRIO|K_EDIT|K_AUTODEL|K_LINE); CRLF;
				bputs(l78);
				getstr(reg.fav_foods, 30, K_LOWPRIO|K_EDIT|K_AUTODEL|K_LINE); CRLF;
        if(yesno(l79))
					{
					CRLF;
					bputs(l80);
					getstr(reg.instruments, 20, K_LOWPRIO|K_EDIT|K_AUTODEL|K_LINE);
					}
				else
					strcpy(reg.instruments, "None");
				CRLF;
        bputs(l81);
				getstr(reg.fav_sports, 40, K_LOWPRIO|K_EDIT|K_AUTODEL|K_LINE); CRLF;
        bputs(l82);
				getstr(reg.hobbies, 50, K_LOWPRIO|K_EDIT|K_AUTODEL|K_LINE); CRLF;
        bputs(l83);
        bputs(l84);
				getstr(reg.general_info[0], 70, K_LOWPRIO|K_EDIT|K_AUTODEL|K_LINE);
				getstr(reg.general_info[1], 70, K_LOWPRIO|K_EDIT|K_AUTODEL|K_LINE);
				getstr(reg.general_info[2], 70, K_LOWPRIO|K_EDIT|K_AUTODEL|K_LINE);
				getstr(reg.general_info[3], 70, K_LOWPRIO|K_EDIT|K_AUTODEL|K_LINE);
				getstr(reg.general_info[4], 70, K_LOWPRIO|K_EDIT|K_AUTODEL|K_LINE);
				CRLF;
				bputs(l85);
        bputs(l86);
				getstr(reg.comment, 40, K_LOWPRIO|K_EDIT|K_AUTODEL|K_LINE);

        if(edit_only)
					fp = nopen("REGISTRY.DAT", O_WRONLY|O_CREAT);
        if(!edit_only) /* Try to find an 'empty' space */
          {
          fp = nopen("REGISTRY.DAT", O_RDWR|O_CREAT);
          while(!eof(fp)) {
            read(fp, &r_tmp, sizeof(struct registry_struct));
            if(r_tmp.name[0] == 0) /* Found Empty spot */
              {
              offset = tell(fp);
							offset = offset - sizeof(struct registry_struct);
              lseek(fp, offset, SEEK_SET);
							break;
							}
            }
          }
				if(fp == -1)
					{
					perror("Error [REGISTRY.DAT]");
					bprintf("\r\nError opening REGISTRY.DAT for writing, please inform the SysOp!");
					break;
					}
				if(edit_only)
					{
					offset = offset - sizeof(struct registry_struct);
					lseek(fp, offset, SEEK_SET);
					}
				write(fp, &reg, sizeof(struct registry_struct));
				close(fp);
				CRLF;
				bputs(l87);
        bputs(l88);
				CRLF;
				if(!edit_only)
					{
          bputs(l89); CRLF;
					}
				pause();
				break;
      case 'S':
        CRLF;
        bputs("\1h\1cEnter Name To Look Up: ");
        if(!getstr(str, 45, K_LOWPRIO|K_LINE|K_UPRLWR))
          break;
        if(!fexist("REGISTRY.DAT"))
          {
          bputs("\r\n\1nNo Profiles Exist To Look Up!\r\n\r\n");
          pause();
          break;
          }
        fp = nopen("REGISTRY.DAT", O_RDONLY);
        if(fp == -1)
          {
          perror("Error [REGISTRY.DAT]");
          CRLF;
          pause();
          break;
          }
        do {
          read(fp, &reg, sizeof(struct registry_struct));
          if(strcmpi(reg.name, str) == 0) /* Match */
            {
            match = 1;
            break;
            }
          else
            match = 0;
          } while(!eof(fp));
        close(fp);
        if(match)
          {
          extended_info();
          CRLF;
          pause();
          }
        else
          {
          bprintf("\r\n\1nProfile Not Found.\r\n\r\n");
          pause();
          }
        break;
			case 'D':
				if(user_level < 90)
					break;
				if(!fexist("REGISTRY.DAT"))
					{
          CRLF;
          bputs(l65);
          CRLF;
					pause();
					return;
					}
					n = 1;
					do
						{
						cls();
            bprintf(l66);
            bprintf(l67);
						fp = nopen("REGISTRY.DAT", O_RDONLY);
						if(fp == -1)
							{
							perror("Error [REGISTRY.DAT]");
							CRLF;
							pause();
              break;
							}
						lseek(fp, sizeof(struct registry_struct) * (n - 1), SEEK_SET);
						recs_on_screen = 0;
						for(i = 0;
							 ((read(fp, &r_temp, sizeof(struct registry_struct)) != 0) &&
							 i < 20); n++)
							 {
							 i++;
							 itoa(n, s, 10);
							 bprintf("\1h\1c%-3s \1n\1g%-29s \1h\1y%s\r\n", s, r_temp.name, r_temp.comment);
							 recs_on_screen++;
							 }
						feof = eof(fp);
						close(fp);
						CRLF;
						bprintf("\1h\1cEnter \1h\1wQ \1h\1cTo Quit, \1h\1wENTER \1cTo Continue, Or A \1wNumber \1cTo Delete: \1w");
						num = getnum(n - 1);
						if(num == -1)
							{
							CRLF;
							break;
							}
						if(num == 0)
							{
							if(feof)
								{
								CRLF;
								break;
								}
							continue;
							}
						fp = nopen("REGISTRY.DAT", O_RDWR);
						if(fp == -1)
							{
							perror("Error [REGISTRY.DAT]");
							bprintf("\r\nError opening REGISTRY.DAT for read, please inform the SysOp!");
							break;
							}
						offset = (num - 1) * sizeof(struct registry_struct);
						lseek(fp, offset, SEEK_SET);
						flush_vars(&r_temp); /* Blank out and write */
						write(fp, &r_temp, sizeof(struct registry_struct));
						/* Pack REGISTRY.DAT... */
						while(!eof(fp)) {
							offset = tell(fp);
							read(fp, &r_temp, sizeof(struct registry_struct));
							lseek(fp, (offset - sizeof(struct registry_struct)), SEEK_SET);
							write(fp, &r_temp, sizeof(struct registry_struct));
							read(fp, &r_temp, sizeof(struct registry_struct));
							/* ^^ value not used, function called just to seek */
							}
						/* Clip end of file */
						if(chsize(fp, (filelength(fp) - sizeof(struct registry_struct))) != 0)
							{
							perror("Error");
							CRLF;
							pause();
							}
						close(fp);
						feof = 1;
						n = n - recs_on_screen;
					} while(!feof);
				break;
			case 'Q':
				done = 1;
				break;
			case '\r':
				done = 1;
				break;
			}
		lncntr = 0; /* Reset pause */
		} while(!done);
}

void extended_info(void)
{
  cls();
  bprintf(l90, reg.name);
	CRLF;
  bprintf(l91,
          reg.name, reg.sex, reg.age);
	bprintf(l92, reg.city_state);
	bprintf(l93, reg.fav_movie);
	bprintf(l94, reg.fav_tvshows);
	bprintf(l95, reg.music);
	bprintf(l96, reg.instruments);
	bprintf(l97, reg.fav_foods);
	bprintf(l98, reg.fav_sports);
	bprintf(l99, reg.hobbies);
	bprintf(l100);
	bprintf(l101, reg.general_info[0]);
	bprintf(l102, reg.general_info[1]);
	bprintf(l103, reg.general_info[2]);
	bprintf(l104, reg.general_info[3]);
	bprintf(l105, reg.general_info[4]);
	bprintf(l106, reg.comment);
}

void flush_vars(struct registry_struct *reg)
{
	memset(reg->name, 0, 31);
	memset(reg->age, 0, 3);
  memset(reg->city_state, 0, 31);
  memset(reg->fav_movie, 0, 31);
  memset(reg->music, 0, 41);
  memset(reg->fav_tvshows, 0, 41);
  memset(reg->fav_foods, 0, 31);
  memset(reg->instruments, 0, 21);
  memset(reg->fav_sports, 0, 41);
  memset(reg->hobbies, 0, 51);
	memset(reg->general_info[0], 0, 71);
  memset(reg->general_info[1], 0, 71);
  memset(reg->general_info[2], 0, 71);
  memset(reg->general_info[3], 0, 71);
  memset(reg->general_info[4], 0, 71);
  memset(reg->comment, 0, 41);
  reg->sex = ' ';
  reg->user_num = 0;
}
