home *** CD-ROM | disk | FTP | other *** search
- /* ╔════════════════════════════════════════════════════╗
- * ║ ┌─────┐ ║
- * ║ │ │┌────┐┌───┐┌──┐ ║
- * ║ │ ││ │├───┘│ │ ║
- * ║ └─────┘├────┘└─── │ ├────┐ ║
- * ║ │ │ │┌───┐┌───┐┌─── ┌── ║
- * ║ │ ││ ││ ││ └──┐ ║
- * ║ └────┘└───┘└───┘│ ──┘ ║
- * ║ ──────────── ║
- * ║ Version 3.40 DEMO DOOR ║
- * ╚════════════════════════════════════════════════════╝
- * (C) Copyright 1992, Brian Pirie. All Rights Reserved.
- *
- * ┌──────────┐
- * │ RAVOTE.C │
- * └──────────┘
- * RAVote is a sample door written in OpenDoors. This is arelatively
- * simple door that allows BBS users to vote anonymously on various topics,
- * entered by other users. Users are able to view the results of any of the
- * topics, only if they have already voted, and may only vote on each topic
- * once. The door automatically uses ANSI graphics if available, and should
- * work with any BBS system that produces a DORINFO1.DEF file. On the command-
- * line you can specify a path to this file if it is not in the current
- * directory. The Sysop (automatically detected by comparing user name to sysop
- * name) also has the option of deleting existing questions.
- *
- * RAVote, of course, also provides all the features available in
- * any OpenDoors door (whithout any extra effort on the part of the
- * programmer), such as sysop chatting & paging, full status line, shell to
- * dos, time adjusting, hangup & lockout, and other function keys. It does,
- * of course, properly monitor carrier detect & user inactivity and user time
- * left. Ravote also runs very quickly and reliably & uses BIOS screen
- * updating for maximum compatibility with DesqView & other such environments.
- * RAVote will also function perfectly normally in local mode, except that
- * if you wish to use Hangup features, you must check the errorlevel returned
- * by the door. Hangup still functions normally in remote mode.
- *
- * RaVote will exit with one of the following errorlevels:
- * 0 - Critical Door error (no fossil, etc.)
- * 1 - Carrier lost, user off-line
- * 2 - Sysop terminated call, user off-line
- * 3 - User time used up, user STILL ON-LINE
- * 4 - Keyboard inactivity timeout, user off-line
- * 5 - Sysop dropped user back to BBS, user ON-LINE
- * 10 - User chose to return to BBS
- * 11 - User chose to logoff, user off-line
- * 12 - Critical RAVote error
- *
- * RaVote may be recompiled or changed as you wish, under the conditions
- * of the OpenDoors licence (ie, if you haven't registered, you can not
- * distribute any doors compiled in OpenDoors, and may only use OpenDoors for
- * a three-week period). If you wish to compile RaVote, as with any OpenDoors
- * door, all you have to do is make sure OPENDOOR.H is present in the default
- * directory, and that Turbo C is configured to compile in the OpenDoors
- * library file. For more information, please see the accompanying
- * documentation.
- */
-
-
- #include <conio.h>
- #include <io.h>
- #include <fcntl.h>
- #include <sys\stat.h>
-
- #include"opendoor.h" /* Must be included in all doors */
-
-
- #define MENU_COLOR 0x0b /* Definitions for ANSI colors, if used */
- #define INPUT_COLOR 0x0e
- #define TITLE_COLOR 0x0c
- #define LIST_COLOR 0x0a
-
-
- int main(int argc,char *argv[]); /* Function prototype declarations */
- void choose_topic(int mode); /* Allows user to choose a question */
- void display_results(void); /* Displays the results of a question */
- void vote(void); /* Places the user's vote */
- int add_answer(void); /* Adds a new answer to the question */
- void save_file(void); /* Saves the RAVOTE.BBS file */
- void delete_question(void); /* Removes a question from the file */
- void main_menu(void); /* Displays the RAVote main menu */
-
-
- struct /* RAVOTE.BBS file format */
- {
- int num_questions; /* Number of questions in the file */
- char quest_title[20][60], /* The "Title" of each question */
- quest_by[20][36], /* Who wrote each question */
- quest_text[20][60]; /* The actual question itself */
- int quest_num_ans[20]; /* The number of answers to each quest. */
- char quest_answers[20][20][60]; /* The possible answers for each quest. */
- int total_votes[20], /* # of times quest. has been voted on */
- votes[20][20], /* # of votes each chioce has recieved */
- num_users; /* Number of users who have used door */
- char user[200][36], /* Each user's name */
- voted[200][20]; /* Has the user voted on each question? */
- } file;
-
- /* Variables used by the door */
- int handle, counter, usernum, topic, choice, key, sysop;
- char string[80];
-
-
- int main(int argc,char *argv[])
- {
- /* Tell OpenDoors your name, */
- /* registration key & your door's */
- /* name at the beginning of any */
- /* program */
- strcpy(od_registered_to,"[Unregistered]");
- od_registration_key=000000000000;
- strcpy(od_program_name,"RAVote 3.40");
-
-
- /* get path to door files from command */
- /* line, if any */
- if(argc>1) strncpy(od_control.info_path,argv[1],59);
-
- /* display copyright notice */
- /* note that since this is the first */
- /* call to any OpenDoors function, the */
- /* initialization is also done at this */
- /* time (such as reading door files, */
- /* opening fossil, seting up od_control, */
- /* and so on). If you wish to have */
- /* access to or to change any of these */
- /* values, make sure that you call */
- /* od_init() before you do anything */
- /* else in your program */
- od_disp_str("[RAVote 3.40 - (C) Copyright 1992, Brian Pirie - All rights Reserved]\n\r");
-
-
- /* Cause OpenDoors to call the */
- /* save_file() function before exiting, */
- /* under any circumstances. This way, */
- /* the data file will be saved, even */
- /* if the user looses connection. */
- od_control.od_before_exit=save_file;
-
- /* Open the RAVOTE.BBS data file */
- if((handle=open("ravote.bbs",O_RDONLY|O_BINARY))==-1)
- { /* Create the file if it does not exist */
- handle=open("ravote.bbs",O_RDWR|O_BINARY|O_CREAT,S_IWRITE|S_IREAD);
- file.num_questions=0; /* Blank file to zero questions, and */
- file.num_users=0; /* Zero users */
- write(handle,&file,sizeof(file));
- }
- else
- read(handle,&file,sizeof(file));/* Read data from file if it exists */
- close(handle); /* Close the file again */
-
- /* Search for user in RAVOTE.BBS */
- for(usernum=0;usernum<file.num_users;++usernum)
- if(strcmp(file.user[usernum],od_control.user_name)==0) break;
-
- if(usernum==file.num_users) /* If user hasn't used RAVote before */
- { /* Add him to the file */
- if(++file.num_users>200) od_exit(12,FALSE);
- strcpy(file.user[usernum],od_control.user_name);
- for(counter=0;counter<20;++counter)
- file.voted[usernum][counter]=FALSE;
- }
- /* Check if the user is the sysop */
- sysop=strcmp(od_control.user_name,od_control.sysop_name)==0;
-
- do
- {
- main_menu(); /* Display the main menu */
-
- od_set_attrib(INPUT_COLOR); /* Display prompt with time left to user */
- od_printf("Select Command (%d mins)\n\r",od_control.caller_timelimit);
- od_set_attrib(MENU_COLOR);
-
- switch(key=od_get_key(TRUE)) /* Get user's choice */
- {
- case 'v': case 'V': /* If user hit V key (upper or lower */
- do /* case) */
- {
- choose_topic(FALSE); /* Allow user to choose question from */
- /* those he hasn't voted on yet */
-
- /* If valid topic # entered */
- if(topic>=0 && topic<=19)
- { /* Display the question to the user */
- od_set_attrib(TITLE_COLOR);
- od_disp_str("\n\r\n\r");od_clr_scr();
- od_disp_str(file.quest_text[topic]);
- od_disp_str("\n\r");
- od_set_attrib(LIST_COLOR);
-
- /* Display possible answers to user */
- for(counter=0;counter<file.quest_num_ans[topic];++counter)
- {
- od_printf(" %2d.) %s\n\r",counter+1,file.quest_answers[topic][counter]);
- }
- /* Get user's choice */
- od_set_attrib(MENU_COLOR);
- od_disp_str("\n\rSelect answer, [O] for other, or [Enter] to pass: ");
-
- /* Allow user to input choice of up to */
- /* two characters */
- od_set_attrib(INPUT_COLOR);
- od_input_str(string,2,32,127);
- od_set_attrib(MENU_COLOR);
- choice=atoi(string)-1;
-
- /* If user chose "Other" option */
- if(string[0]=='o' || string[0]=='O')
- { /* If room to add another answer */
- if(file.quest_num_ans[topic]<20)
- { /* Allow user to add his answer to quest */
- od_disp_str("\n\r\n\rWhat is your \"Other\" answer?\n\r");
- if(add_answer())
- { /* If user actually added answer */
- choice=file.quest_num_ans[topic]-1;
- vote(); /* record his vote */
- }
- }
- else /* If there is no room for more answers */
- { /* Let the user know */
- od_disp_str("\n\r\n\rThis question already has 20 answers!\n\r");
- od_disp_str("Press any key to continue...\n\r");
- od_get_key(TRUE);
- }
- }
-
- else /* If user voted for an existing */
- { /* choice */
- if(choice>=0 && choice<=file.quest_num_ans[topic])
- {
- vote(); /* record their vote */
- }
- }
- }
-
- } while(topic!=-1); /* Loop until user is finished voting */
- break;
-
-
- case 'r': case 'R': /* If user wants to display results */
- for(;;)
- {
- choose_topic(TRUE); /* Allow user to choose a topic */
- if(topic==-1) break; /* Exit loop if abort result display */
- display_results(); /* Display results of question */
- }
- break;
-
-
- case 'a': case 'A': /* If adding a new question */
- od_clr_scr(); /* Clear the screen (if mode turned on) */
- if(file.num_questions<20) /* If there is room for another quest. */
- { /* Store user's name as author of quest. */
- strcpy(file.quest_by[file.num_questions],od_control.user_name);
- file.total_votes[file.num_questions]=0;
- /* Get question title from user */
- od_disp_str("\n\r\n\rWhat is the title of your question?\n\r > ");
- od_set_attrib(INPUT_COLOR);
- od_input_str(string,59,32,127);
- od_set_attrib(MENU_COLOR);
- strcpy(file.quest_title[file.num_questions],string);
-
- if(strlen(string)!=0) /* If user didn't abort */
- { /* Get the question itself from user */
- od_disp_str("\n\rWhat is your question?\n\r > ");
- od_set_attrib(INPUT_COLOR);
- od_input_str(string,59,32,127);
- od_set_attrib(MENU_COLOR);
- strcpy(file.quest_text[file.num_questions],string);
- /* If user didn't abort */
- if(strlen(string)!=0)
- { /* Get the user's answers */
- od_disp_str("\n\rNow, enter the possible answers to your question:\n\r");
- topic=file.num_questions;
- file.quest_num_ans[topic]=0;
- while(add_answer());
-
- /* confirm question creation */
- od_set_attrib(MENU_COLOR);
- od_disp_str("Do you wish to save this question? (Y/N) ");
-
- /* get yes or no from user */
- do choice=od_get_key(TRUE); while(choice!='Y' && choice!='N' && choice!='y' && choice!='n');
-
- if(choice=='y' || choice=='Y')
- file.num_questions++;
- }
- }
- }
- else /* If no room for a new question, */
- { /* let the user know */
- od_disp_str("Sorry, RAVote has a limit of 20 questions.\n\r");
- od_disp_str("Press any key to continue...\n\r\n\r");
- od_get_key(TRUE);
- }
-
- break;
-
-
- case 'p': case 'P': /* If user wants to page the sysop */
- od_page(); /* OpenDoors takes care of the rest */
- break;
-
- case 'd': case 'D': /* If user chose delete key */
- if(sysop) /* If it is the sysop */
- {
- od_clr_scr(); /* Clear the screen */
- /* ask which question to delete */
- od_disp_str("Please enter question number to delete: ");
- od_set_attrib(INPUT_COLOR);
- od_input_str(string,2,'0','9');
- topic=atoi(string)-1;
- od_set_attrib(MENU_COLOR);
- /* If valid choice */
- if(topic>=0 && topic<file.num_questions)
- { /* Confirm question deletion */
- od_printf("\n\r\n\r Delete: %s\n\r\n\r",file.quest_title[topic]);
- od_set_attrib(TITLE_COLOR);
- od_disp_str("Are You Sure? (Y/N)\n\r");
- od_set_attrib(MENU_COLOR);
-
- do choice=od_get_key(TRUE); while(choice!='Y' && choice!='N' && choice!='y' && choice!='n');
-
- if(choice=='y' || choice=='Y')
- { /* If sysop agrees, it's gone! */
- delete_question();
- }
- }
- }
- } /* Loop until quit to BBS or logoff */
- } while(key!='Q' && key!='q' && key!='G' && key!='g');
-
- if(key=='G' || key=='g') /* If user wishsed to log off */
- { /* Say goodbye */
- od_printf("\n\rGoodbye from %s...\n\r",od_control.system_name);
- od_exit(11,TRUE); /* Let OpenDoors take care of the rest */
- }
- else
- { /* Acknoledge return to BBS */
- od_printf("\n\rReturning you to %s...\n\r",od_control.system_name);
- od_exit(10,FALSE); /* Again OpenDoors does the rest */
- }
-
- return(0);
- }
-
-
- void save_file(void) /* Function to save RAVOTE.BBS file */
- { /* (called before door termination) */
- handle=open("ravote.bbs",O_WRONLY|O_BINARY);
- write(handle,&file,sizeof(file));
- close(handle);
- }
-
-
- int add_answer(void) /* Function to add answer to file */
- { /* Check for room to add answer */
- if(file.quest_num_ans[topic]>=20) return(FALSE);
-
- od_set_attrib(MENU_COLOR); /* Get user's answer */
- od_printf(" %2d> ",file.quest_num_ans[topic]+1);
- od_set_attrib(INPUT_COLOR);
- od_input_str(string,59,32,127);
- if(strlen(string)==0) return(FALSE);
- /* If no abort, add to question */
- file.votes[topic][file.quest_num_ans[topic]]=0;
- strcpy(file.quest_answers[topic][file.quest_num_ans[topic]++],string);
- return(TRUE);
- }
-
-
-
- void choose_topic(int mode) /* function to let user to choose quest */
- {
- register char displayed=FALSE;
-
- for(;;)
- {
- od_set_attrib(TITLE_COLOR);
- od_clr_scr(); /* Clear the screen */
- od_disp_str("Choose A Topic:\n\r");
- od_set_attrib(LIST_COLOR);
- /* display questions */
- for(counter=0;counter<file.num_questions;++counter)
- { /* if question should be displayed */
- if(file.voted[usernum][counter]==mode)
- {
- displayed=TRUE; /* spit 'er out! */
- od_printf(" %d.) %s\n\r",counter+1,file.quest_title[counter]);
- }
- }
- /* if no topics were displayed... */
- if(!displayed) od_disp_str("\n\r No Topics to choose from.\n\r\n\r");
-
- od_set_attrib(MENU_COLOR);
-
- od_disp_str("Select topic, or [Enter] to return to main menu: ");
-
- od_set_attrib(INPUT_COLOR);
-
- od_input_str(string,2,'0','9'); /* Get user's choice */
-
- topic=atoi(string)-1; /* Convert string to number */
-
- if(topic==-1) return; /* If user aborted, exit */
- /* if valid question, exit */
- if(topic<file.num_questions && topic>=0 && file.voted[usernum][topic]==mode) return;
- }
- }
-
-
-
- void display_results(void) /* function to display results of quest */
- {
- od_set_attrib(TITLE_COLOR); /* display the header */
- od_clr_scr();
- od_printf("%s\n\r(Created by: %s)\n\r",file.quest_title[topic],file.quest_by[topic]);
-
- od_set_attrib(LIST_COLOR);
- /* loop through each answer */
- for(counter=0;counter<file.quest_num_ans[topic];++counter)
- /* display answer with # & % of votes */
- od_printf(" %-3d %3d%% %s\n\r",file.votes[topic][counter],(file.votes[topic][counter]*100)/file.total_votes[topic],file.quest_answers[topic][counter]);
-
- od_set_attrib(MENU_COLOR);
- /* Wait for user to hit a key */
- od_disp_str("\n\rPress any key to continue...");
- od_get_key(TRUE);
- od_disp_str("\n\r\n\r");
- }
-
-
- void vote(void) /* function to record user's vote */
- {
- file.voted[usernum][topic]=TRUE; /* stop him from voting on it again */
- ++file.total_votes[topic]; /* increase total number of votes */
- ++file.votes[topic][choice]; /* add user's vote */
- display_results(); /* show user results of question to date */
- }
-
-
- void delete_question(void) /* function to delete a question */
- { /* decrement total # of questions */
- if(topic==--file.num_questions) return;
- /* shuffle all other questions up one */
- memcpy(file.quest_title[topic],file.quest_title[topic+1],60*(19-topic));
- memcpy(file.quest_by[topic],file.quest_by[topic+1],36*(19-topic));
- memcpy(file.quest_text[topic],file.quest_text[topic+1],60*(19-topic));
- memcpy(&file.quest_num_ans[topic],&file.quest_num_ans[topic+1],2*(19-topic));
- memcpy(file.quest_answers[topic],file.quest_answers[topic+1],1200*(19-topic));
- memcpy(&file.total_votes[topic],&file.total_votes[topic+1],2*(19-topic));
- memcpy(file.votes[topic],file.votes[topic+1],40*(19-topic));
- for(counter=0;counter<file.num_users;++counter)
- memcpy(&file.voted[counter][topic],&file.voted[counter][topic+1],19-topic);
- }
-
-
-
- void main_menu(void)
- {
- od_clear_keybuffer(); /* Clear any pending keys in buffer */
- od_clr_scr(); /* Clear screen */
-
- if(od_send_file("RAVOTE"))
- {
- return;
- }
-
- else if(od_control.caller_ansi) /* Display ANSI title if ANSI mode is on */
- {
- od_set_attrib(TITLE_COLOR);
- od_disp_str("\n\r┌───────────────────────────────────┐\n\r│ ");
- od_set_attrib(LIST_COLOR);
- od_disp_str("RAVote ■ OpenDoors 3.40 Demo Door ");
- od_set_attrib(TITLE_COLOR);
- od_disp_str("│\n\r└───────────────────────────────────┘\n\r");
- od_disp_str(" Copyright 1992, Brian Pirie\n\r");
- }
- else /* Display ASCII title if ANSI is off */
- {
- od_disp_str("\n\r+-----------------------------------+\n\r");
- od_disp_str("| RAVote - OpenDoors 3.40 Demo Door |\n\r");
- od_disp_str("+-----------------------------------+\n\r");
- od_disp_str(" Copyright 1992, Brian Pirie\n\r");
- }
-
- od_set_attrib(MENU_COLOR);
- /* Display main menu (note that the */
- /* delete booth option is only displayed */
- /* to the sysop) */
- od_disp_str("\n\r [V] Vote on a Topic\n\r");
- od_disp_str(" [R] View results\n\r");
- od_disp_str(" [A] Add a new question\n\r");
- od_disp_str(" [P] Page Sysop\n\r");
- if(sysop) od_disp_str(" [D] Delete Booth\n\r");
- od_disp_str(" [G] Goodbye (Logoff)\n\r");
- od_disp_str(" [Q] Return to BBS\n\r\n\r");
-
- }
-