/* Include standard C header files required by FreeVote. */ #include <stdio.h> #include <stdlib.h> #include <time.h> #include <errno.h> #include <ctype.h> #include <string.h> /* Include the OpenDoors header file. This line must be done in any program */ /* using OpenDoors. */ #include "OpenDoor.h" #include <genwrap.h> #include <dirwrap.h> #include <filewrap.h> #include <xpendian.h> /* Manifest constants used by EZVote */ #define NO_QUESTION -1 #define NEW_ANSWER -1 #define SET_UN_ANSWERED -2 #define QUESTIONS_VOTED_ON 0x0001 #define QUESTIONS_NOT_VOTED_ON 0x0002 #define CURRENT_USER_ONLY 0x0004 #define QUESTIONS_FORCED 0x0008 #define CAN_ADD_ANSWERS 0x0001 #define MULTIPLE_ANSWERS 0x0002 #define QUESTION_DELETED 0x0004 #define ANONYMOUS_QUESTION 0x0008 #define BF_15_BY_1_MODE 0x0010 #define NEVER_DELETE_QUESTION 0x0020 #define MULTIPLE_ADDS_P_U 0x0040 #define FORCED_QUESTION 0x0080 #define MAX_QUESTIONS 400 #define MAX_USERS 32766 #define MAX_ANSWERS 15 #define MAX_ANSWERS2 7 #define QUESTION_STR_SIZE 71 #define ANSWER_STR_SIZE 31 #define USER_FILENAME "freevote.usr" #define QUESTION_FILENAME "freevote.qst" #define FILE_ACCESS_MAX_WAIT 20 #define QUESTION_PAGE_SIZE 17 #define COLOR_DEF 0 #define COLOR_TNW 1 struct time { unsigned char ti_min; unsigned char ti_hour; unsigned char ti_hund; unsigned char ti_sec; }; /* Structure of records stored in the EZVOTE.USR file */ typedef struct { char szUserName[36]; WORD bVotedOnQuestion[MAX_QUESTIONS]; } tUserRecord; tUserRecord CurrentUserRecord; int user_security=-1; int b_us; int AddSecurity=0; int nCurrentUserNumber; time_t maxtime=0; int sysop_sec=32767; int Forcevote=0; struct time tt; char allow_page=TRUE; int AllowIn=0; char view_own_results=TRUE; char multiple_answers=TRUE; char anonymous_posting=TRUE; char answer_adding=1; /*0 = no adding 1 = regular creator chooses 2 = forced*/ char more_adds_p_u=1; /*0 = never 1 = creator chooses 2 = forced*/ char no_same_answers=TRUE; char bAllowDelete=TRUE; char bAllowChange=TRUE; char bAllowUnvote=TRUE; char ColoredResults=TRUE; //int bAllowGoodbye=TRUE; char bHandles=FALSE; char maint_run=FALSE; char autodetect=TRUE; int answers[16]={0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200, 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000, 0x00008000}; /* Structure of records stored in the EZVOTE.QST file */ typedef struct { char szQuestion[QUESTION_STR_SIZE]; char aszAnswer[MAX_ANSWERS][ANSWER_STR_SIZE]; char nTotalAnswers; DWORD auVotesForAnswer[MAX_ANSWERS]; DWORD uTotalVotes; /* char bCanAddAnswers; char bMultipleAnswers; char b char bDeleted;*/ char bitflags; /*1st - Can Add Answers 2nd - Multiple Answers 3rd - Deleted 4th - Anonymous 5th - 15 x 1 line / 7 x 2 lines mode 6th - Never Delete this question if this is set 7th - Allow multiple adds. 8th - Forced Question. */ char szCreatorName[36]; time_t lCreationTime; } tQuestionRecord; /* Global variables. */ unsigned int nViewResultsFrom = QUESTIONS_VOTED_ON; char bAllowAdd = TRUE; int nQuestionsVotedOn = 0; char sz_user_name[36]; int colorsch=COLOR_DEF; /* Prototypes for functions that form EZVote */ void CustomConfigFunction(char *pszKeyword, char *pszOptions); void BeforeExitFunction(void); void CheckForBadUsers(char name[]); void VoteOnQuestion(int all); void ViewResults(int all); int FirstQuestion(unsigned int nFromWhichQuestions, int nFileQuestion); int GetQuestion(int nQuestion, tQuestionRecord *pQuestionRecord); void AddQuestion(void); void DeleteQuestion(void); void ChangeQuestion(void); void DeleteYourQuestion(void); int ChooseQuestion(unsigned int nFromWhichQuestions, char *pszTitle, int *nLocation); int DisplayQuestionResult(tQuestionRecord *pQuestionRecord,int all); int ReadOrAddCurrentUser(void); void WriteCurrentUser(void); FILE *ExculsiveFileOpen(char *pszFileName, char *pszMode); void WaitForEnter(void); int CountQuestions(void); int CountQuestionsF(void); void dump(void); void maint(void); void warp_line(char line1[], char line2[],char intro[]); void my_clr_scr(); void trim(char *numstr); void QuestionEditor(void); FILE *QRead(tQuestionRecord *QuestionRecord,int nQuestion); int QWrite(tQuestionRecord *QuestionRecord, FILE *fpFile,int nQuestion); #define USERRECORD_SIZE (sizeof(WORD)*MAX_QUESTIONS+36) #define QUESTIONRECORD_SIZE (QUESTION_STR_SIZE+(MAX_ANSWERS*ANSWER_STR_SIZE)+1+(sizeof(DWORD)*MAX_ANSWERS)+sizeof(DWORD)+1+36+8) int freadUserRecord(tUserRecord *urec, FILE *f) { int i; if(fread(urec->szUserName, sizeof(urec->szUserName), 1, f)!=1) return(0); for(i=0; i<MAX_QUESTIONS; i++) { if(fread(&urec->bVotedOnQuestion[i], sizeof(WORD), 1, f)!=1) return(0); urec->bVotedOnQuestion[i]=LE_SHORT(urec->bVotedOnQuestion[i]); } return(1); } int fwriteUserRecord(tUserRecord *urec, FILE *f) { int i; if(fwrite(urec->szUserName, sizeof(urec->szUserName), 1, f)!=1) return(0); for(i=0; i<MAX_QUESTIONS; i++) { urec->bVotedOnQuestion[i]=LE_SHORT(urec->bVotedOnQuestion[i]); if(fwrite(&urec->bVotedOnQuestion[i], sizeof(WORD), 1, f)!=1) return(0); urec->bVotedOnQuestion[i]=LE_SHORT(urec->bVotedOnQuestion[i]); } return(1); } int freadQuestionRecord(tQuestionRecord *q, FILE *f) { INT32 i; if(fread(q->szQuestion, sizeof(q->szQuestion), 1, f)!=1) return(0); for(i=0; i<MAX_ANSWERS; i++) { if(fread(q->aszAnswer[i], sizeof(q->aszAnswer[i]), 1, f)!=1) return(0); } if(fread(&q->nTotalAnswers, sizeof(q->nTotalAnswers), 1, f)!=1) return(0); for(i=0; i<MAX_ANSWERS; i++) { if(fread(&q->auVotesForAnswer[i], sizeof(q->auVotesForAnswer[i]), 1, f)!=1) return(0); q->auVotesForAnswer[i]=LE_SHORT(q->auVotesForAnswer[i]); } if(fread(&q->uTotalVotes, sizeof(q->uTotalVotes), 1, f)!=1) return(0); q->uTotalVotes=LE_SHORT(q->uTotalVotes); if(fread(&q->bitflags, sizeof(q->bitflags), 1, f)!=1) return(0); if(fread(q->szCreatorName, sizeof(q->szCreatorName), 1, f)!=1) return(0); switch(sizeof(time_t)) { case 4: if(fread(&q->lCreationTime, sizeof(q->lCreationTime), 1, f)!=1) return(0); q->lCreationTime=LE_LONG(q->lCreationTime); if(fread(&i, sizeof(i), 1, f)!=1) return(0); break; default: fprintf(stderr, "Unhandled time_t size (%d)\n", sizeof(time_t)); exit(1); } } int fwriteQuestionRecord(tQuestionRecord *q, FILE *f) { INT32 i; if(fwrite(q->szQuestion, sizeof(q->szQuestion), 1, f)!=1) return(0); for(i=0; i<MAX_ANSWERS; i++) { if(fwrite(q->aszAnswer[i], sizeof(q->aszAnswer[i]), 1, f)!=1) return(0); } if(fwrite(&q->nTotalAnswers, sizeof(q->nTotalAnswers), 1, f)!=1) return(0); for(i=0; i<MAX_ANSWERS; i++) { q->auVotesForAnswer[i]=LE_SHORT(q->auVotesForAnswer[i]); if(fwrite(&q->auVotesForAnswer[i], sizeof(q->auVotesForAnswer[i]), 1, f)!=1) { q->auVotesForAnswer[i]=LE_SHORT(q->auVotesForAnswer[i]); return(0); } q->auVotesForAnswer[i]=LE_SHORT(q->auVotesForAnswer[i]); } q->uTotalVotes=LE_SHORT(q->uTotalVotes); if(fwrite(&q->uTotalVotes, sizeof(q->uTotalVotes), 1, f)!=1) { q->uTotalVotes=LE_SHORT(q->uTotalVotes); return(0); } q->uTotalVotes=LE_SHORT(q->uTotalVotes); if(fwrite(&q->bitflags, sizeof(q->bitflags), 1, f)!=1) return(0); if(fwrite(q->szCreatorName, sizeof(q->szCreatorName), 1, f)!=1) return(0); switch(sizeof(time_t)) { case 4: q->lCreationTime=LE_LONG(q->lCreationTime); if(fwrite(&q->lCreationTime, sizeof(q->lCreationTime), 1, f)!=1) { q->lCreationTime=LE_LONG(q->lCreationTime); return(0); } q->lCreationTime=LE_LONG(q->lCreationTime); if(fwrite(&i, sizeof(i), 1, f)!=1) return(0); break; default: fprintf(stderr, "Unhandled time_t size (%d)\n", sizeof(time_t)); exit(1); } } void gettime(struct time *tim) { struct timeval ti; struct tm *t; gettimeofday(&ti,NULL); t=localtime((time_t *)&ti.tv_sec); tim->ti_min=t->tm_min; tim->ti_hour=t->tm_hour; tim->ti_hund=ti.tv_usec/10000; tim->ti_sec=t->tm_sec; } void CheckForBadUsers(char name[]) { FILE *badfile; char numstr[82]; char *key; badfile=ExculsiveFileOpen("badusers.txt","rt"); if(badfile==NULL) return; while(fgets(numstr,81,badfile)!=NULL) { key=strchr(numstr,'\n'); *key=0; trim(numstr); if(stricmp(numstr,name)==0) { od_printf("\n\r\n`bright`You have been locked out of FrEevOtE!\n\r\n"); WaitForEnter(); fclose(badfile); od_exit(10,TRUE); } } fclose(badfile); } void trim(char *numstr) { int x; for(x=strlen(numstr)-1;numstr[x]==' ' && x>=0;x--) od_kernal; numstr[x+1]=0; strrev(numstr); for(x=strlen(numstr)-1;numstr[x]==' ' && x>=0;x--) od_kernal; numstr[x+1]=0; strrev(numstr); } void my_clr_scr() { if(od_control.user_rip==TRUE) { /*od_control.user_rip=FALSE; od_disp_str("\n\r!|*|#|#|#\n\n\r"); od_clr_scr(); od_control.user_rip=TRUE;*/ od_clr_scr(); od_disp_str("|#|#|#\n\r"); od_control.user_rip=FALSE; od_clr_scr(); od_control.user_rip=TRUE; } else { od_printf("\n\n\r"); od_clr_scr(); } } void cap_names(char name[]) { int cnt=0; int cap=TRUE; while (name[cnt]!=0) { if (cap==TRUE) { if (name[cnt]>='a' && name[cnt]<='z') name[cnt]-=32; } else { if (name[cnt]>='A' && name[cnt]<='Z') name[cnt]+=32; } cnt++; if (name[cnt-1]==' ') cap=TRUE; else cap=FALSE; } } /*copy end chars beginning from beg to dest*/ /*podobny strncpy*/ void strzcpy(char dest[],const char src[], int beg,int end) { int cnt=0; do { dest[cnt]=src[beg]; beg++; cnt++; } while (cnt<=end && src[cnt]!=0); dest[cnt]=0; } void NoDropFile(void) { printf("\nFrEevOtE v3.2 - No dropfile found!\n"); printf("To start in Local mode type:\nFREEVOTE -L\n"); exit(10); } /* main() function - Program execution begins here. */ main(int argc, char *argv[]) { /* Variable to store user's choice from the menu */ char chMenuChoice; char chYesOrNo; int cnt,intval; char menufile[13]; /* Enable use of OpenDoors configuration file system. */ od_control.od_config_file = INCLUDE_CONFIG_FILE; od_control.od_config_filename = "freevote.cfg"; if(fexist("freevote.cfg")) od_control.od_config_file = INCLUDE_CONFIG_FILE; else od_control.od_config_file = NO_CONFIG_FILE; od_control.od_mps=INCLUDE_MPS; od_control.od_nocopyright=TRUE; /* Set function to process custom configuration file lines. */ od_control.od_config_function = CustomConfigFunction; //your reg number here strcpy(od_registered_to,"Your Name"); od_registration_key=0L; char key; char numstr[81]; cnt=1; od_control.od_logfile_disable=TRUE; od_control.od_no_file_func=NoDropFile; od_control.od_disable |= DIS_BPS_SETTING; od_control.od_disable |= DIS_NAME_PROMPT; if(argc>1) { do { if (strnicmp(argv[cnt],"-LOG",4)==0) { od_control.od_logfile = INCLUDE_LOGFILE; strcpy(od_control.od_logfile_name, "freevote.log"); od_control.od_logfile_disable=FALSE; } else if (strnicmp(argv[cnt],"-NAD",4)==0) { autodetect=FALSE; } else if (strnicmp(argv[cnt],"-RDBPS",6)==0) { od_control.od_disable &=~ DIS_BPS_SETTING; } else if (strnicmp(argv[cnt],"-L",2)==0) { od_control.od_force_local=TRUE; #ifndef ODPLAT_NIX clrscr(); textbackground(LIGHTCYAN); textcolor(BLUE); gotoxy(1,7); cprintf("�����������������������������������������������������������������������������ͻ"); gotoxy(1,8); cprintf("� FrEevOtE v3.2 �"); gotoxy(1,9); cprintf("� Starting in local mode input your name: ����������������������������������� �"); gotoxy(1,10); cprintf("�����������������������������������������������������������������������������ͼ"); gotoxy(43,9); // for(x=0;x<35;x++) // putch('�'); // cprintf(" �\b\b"); // for(x=0;x<35;x++) // putch('\b'); int cntv=0; intval=TRUE; do { if(cntv>=35) { cntv=34; putch('\b'); key=getch(); if(key=='\n' || key=='\r') cntv=35; } else { key=getch(); } if(key==27) { gotoxy(1,9); cprintf("� Starting in local mode input your name: � Canceled ... �������������������� �"); gotoxy(1,12); exit(10); } if(intval==TRUE) { if (key>='a' && key<='z') key-=32; intval=FALSE; } else if(intval==FALSE) { if (key>='A' && key<='Z') key+=32; } if(key==' ') { putch('�'); key=0; intval=TRUE; } else if(key=='\b') { if(cntv==0) { intval=TRUE; key=0; cntv--; } else { cntv-=2; if(cntv>=0 && od_control.user_name[cntv]==' ') intval=TRUE; if(cntv==32) cprintf("\b��\b\b"); else cprintf("\b�\b"); key=0; } } if(key!=0) { od_control.user_name[cntv]=key; putch(key); } cntv++; } while (key!='\n' && key!='\r'); od_control.user_name[cntv-1]=0; trim(od_control.user_name); /* strlwr(od_control.user_name); od_contro.user_name[0]-=32;*/ #endif } else if (strnicmp(argv[cnt],"-P",2)==0) { strzcpy(od_control.info_path,argv[cnt],2,59); } else if (strnicmp(argv[cnt],"-N",2)==0) { strzcpy(numstr,argv[cnt],2,59); sscanf(numstr,"%d",&od_control.od_node); } else if (strnicmp(argv[cnt],"-S",2)==0) { strzcpy(numstr,argv[cnt],2,59); sscanf(numstr,"%d",&user_security); } else if (strnicmp(argv[cnt],"-M",2)==0) { od_control.od_force_local=TRUE; maint_run=TRUE; } else if (strnicmp(argv[cnt],"-C",2)==0) { od_control.od_config_file = INCLUDE_CONFIG_FILE; strzcpy(od_control.od_config_filename,argv[cnt],2,59); } else if (strnicmp(argv[cnt],"-FC",3)==0) { Forcevote=5; } else if (strnicmp(argv[cnt],"-FNQ",4)==0) { Forcevote=2; } else if (strnicmp(argv[cnt],"-FA",3)==0) { Forcevote=3; } else if (strnicmp(argv[cnt],"-FQ",3)==0) { Forcevote=4; } else if (strnicmp(argv[cnt],"-F",2)==0) { Forcevote=1; } } while ((++cnt)<argc); } /* Include the OpenDoors multiple personality system, which allows */ /* the system operator to set the sysop statusline / function key set */ /* to mimic the BBS software of their choice. */ od_control.od_mps = INCLUDE_MPS; /* Set program's name, to be written to the OpenDoors log file */ strcpy(od_control.od_prog_name, "FrEevOtE"); if(maint_run==TRUE) { od_init(); maint(); od_exit(10,FALSE); } /* Set function to be called before program exits. */ // od_control.od_default_rip_win=TRUE; /* Initialize OpenDoors. This function call is optional, and can be used */ /* to force OpenDoors to read the door informtion file and begin door */ /* operations. If a call to od_init() is not included in your program, */ /* OpenDoors initialization will be performed at the time of your first */ /* call to any OpenDoors function. */ od_init(); b_us=od_control.user_security; if(user_security!=-1) od_control.user_security=user_security; od_control.od_update_status_now=TRUE; od_kernel(); // od_control.od_disable |= DIS_INFOFILE; if(autodetect==TRUE) od_autodetect(DETECT_NORMAL); od_control.od_help_text2=(char *)" FrEevOtE v3.2 by Franz ... (c)1995 George Lebl ... FREEWARE!!!!! "; if(od_control.user_rip==TRUE) od_control.user_ansi=TRUE; if(bHandles==TRUE) strcpy(sz_user_name,od_control.user_handle); else strcpy(sz_user_name,od_control.user_name); trim(sz_user_name); CheckForBadUsers(sz_user_name); if(AllowIn>od_control.user_security) { od_printf("\n\r\n`bright`Your security level is not high enough to let you into FrEevOtE!\n\r\n"); WaitForEnter(); od_exit(10,TRUE); } gettime(&tt); if((tt.ti_min +(tt.ti_hour * 60)) < od_control.od_pagestartmin || (tt.ti_min +(tt.ti_hour * 60)) >= od_control.od_pageendmin) { allow_page=FALSE; } if((sysop_sec<=od_control.user_security || strcmp(od_control.sysop_name, od_control.user_name) == 0)) { answer_adding=1; more_adds_p_u=1; no_same_answers=FALSE; anonymous_posting=TRUE; multiple_answers=TRUE; } else { if(AddSecurity>od_control.user_security) bAllowAdd=FALSE; } /*check and then pack questionfile and delete old questions*/ /* maint();*/ /* Call the EZVote function ReadOrAddCurrentUser() to read the current */ /* user's record from the EZVote user file, or to add the user to the */ /* file if this is the first time that they have used EZVote. */ if(!ReadOrAddCurrentUser()) { /* If unable to obtain a user record for the current user, then exit */ /* the door after displaying an error message. */ od_printf("Unable to access user file. File may be locked or full.\n\r"); WaitForEnter(); od_exit(1, FALSE); } od_control.od_before_exit = BeforeExitFunction; if(sysop_sec<=od_control.user_security || strcmp(od_control.sysop_name, od_control.user_name) == 0) { nViewResultsFrom = QUESTIONS_VOTED_ON | QUESTIONS_NOT_VOTED_ON; } else { if(CountQuestionsF() > 0) { // od_printf("\n\n\r"); my_clr_scr(); if(colorsch==COLOR_DEF) od_printf("`bright green`"); else od_printf("`bright`"); od_printf("FrEevOtE v3.2\n\r\n"); if(colorsch==COLOR_DEF) od_printf("`bright red`"); else od_printf("`bright black`"); od_printf("The Sysop has posted forced questions"); if(colorsch!=COLOR_DEF) od_printf("`white`"); od_printf(".\n\r"); if(colorsch!=COLOR_DEF) od_printf("`bright black`"); od_printf("You will have to answer them now"); if(colorsch!=COLOR_DEF) od_printf("`white`"); od_printf("!\n\r\n"); WaitForEnter(); Forcevote += 100; VoteOnQuestion(TRUE); Forcevote -= 100; } } /* Loop until the user choses to exit the door. For each iteration of */ /* this loop, we display the main menu, get the user's choice from the */ /* menu, and perform the appropriate action for their choice. */ if(Forcevote==1) { // od_printf("\n\n\r"); my_clr_scr(); if(colorsch==COLOR_DEF) od_printf("`bright green`"); else od_printf("`bright`"); od_printf("FrEevOtE v3.2\n\r\n"); WaitForEnter(); if(colorsch==COLOR_DEF) od_printf("`bright green`"); else od_printf("`bright`"); VoteOnQuestion(TRUE); if(colorsch==COLOR_DEF) od_printf("`bright red`\n\rEnter FrEevOtE? (Y/[N]):"); else od_printf("`bright black`\n\rEnter FrEevOtE`white`? (`bright black`Y`white`/[`bright black`N`white`]):"); chMenuChoice=od_get_answer("YN\n\r"); if(chMenuChoice!='Y') { od_printf(" No\n\r"); od_exit(10,FALSE); } od_printf(" Yes\n\r"); if(colorsch==COLOR_DEF) od_printf("`bright green`"); else od_printf("`bright`"); Forcevote=0; } if(Forcevote==2) { // od_printf("\n\n\r"); my_clr_scr(); if(colorsch==COLOR_DEF) od_printf("`bright green`"); else od_printf("`bright`"); od_printf("FrEevOtE v3.2\n\r\n"); WaitForEnter(); if(colorsch==COLOR_DEF) od_printf("`bright green`"); else od_printf("`bright`"); VoteOnQuestion(TRUE); od_exit(10,FALSE); } if(Forcevote==4) { // od_printf("\n\n\r"); my_clr_scr(); if(colorsch==COLOR_DEF) od_printf("`bright green`"); else od_printf("`bright`"); od_printf("`bright green`"); VoteOnQuestion(TRUE); od_exit(10,FALSE); } if(Forcevote==3) { // od_printf("\n\n\r"); my_clr_scr(); if(colorsch==COLOR_DEF) od_printf("`bright green`"); else od_printf("`bright`"); od_printf("FrEevOtE v3.2\n\r"); if(CountQuestions()>0) { if(colorsch==COLOR_DEF) od_printf("`bright red`\n\rGo Vote? ([Y]/N):"); else od_printf("`bright black`\n\rGo Vote`white`? ([`bright black`Y`white`]/`bright black`N`white`):"); chMenuChoice=od_get_answer("YN\n\r"); if(chMenuChoice=='N') { od_printf(" No\n\r"); od_exit(10,FALSE); } od_printf(" Yes\n\r"); if(colorsch==COLOR_DEF) od_printf("`bright green`"); else od_printf("`bright`"); VoteOnQuestion(TRUE); if(colorsch==COLOR_DEF) od_printf("`bright red`\n\rEnter FrEevOtE? (Y/[N]):"); else od_printf("`bright black`\n\rEnter FrEevOtE`white`? (`bright black`Y`white`/[`bright black`N`white`]):"); chMenuChoice=od_get_answer("YN\n\r"); if(chMenuChoice!='Y') { od_printf(" No\n\r"); od_exit(10,FALSE); } Forcevote=0; od_printf(" Yes\n\r"); if(colorsch==COLOR_DEF) od_printf("`bright green`"); else od_printf("`bright`"); } else { if(colorsch==COLOR_DEF) od_printf("`bright red`"); else od_printf("`bright black`"); if(colorsch==COLOR_DEF) od_printf("`bright red`\n\rEnter FrEevOtE Anywayz? (Y/[N]):"); else od_printf("`bright black`\n\rEnter FrEevOtE Anywayz`white`? (`bright black`Y`white`/[`bright black`N`white`]):"); chMenuChoice=od_get_answer("YN\n\r"); if(chMenuChoice!='Y') { od_printf(" No\n\r"); od_exit(10,FALSE); } Forcevote=0; od_printf(" Yes\n\r"); if(colorsch==COLOR_DEF) od_printf("`bright green`"); else od_printf("`bright`"); } } if(Forcevote==5) { // od_printf("\n\n\r"); my_clr_scr(); if(colorsch==COLOR_DEF) od_printf("`bright green`"); else od_printf("`bright`"); od_printf("FrEevOtE v3.2\n\r"); CountQuestions(); WaitForEnter(); od_exit(10,FALSE); } for(;;) { /* Clear the screen */ // od_printf("\n\n\r"); my_clr_scr(); /* Display main menu. */ sprintf(menufile,"MM%d",od_control.user_security); if(od_send_file(menufile)!=TRUE && od_send_file("MMENU")!=TRUE) { if(od_control.user_ansi || od_control.user_avatar) { if(colorsch==COLOR_DEF) { od_printf("`bright` ��� ��� ��� ��� � ��� `bright green`v3.2\n\r"); od_printf("`bright red`������������������������`bright blue`��`bright red`��`bright blue`���`bright red`�`bright blue`��`bright red`��`bright blue`�`bright red`�`bright blue`�`bright red`�`bright blue`�`bright red`�`bright blue`�`bright red`�`bright blue`�`bright red`�`bright blue`�`bright red`�`bright blue`���`bright red`�`bright blue`��`bright red`�������������������������\n\r"); od_printf("`blue` � � ��� ��� � ��� �� ��� `green`by `bright green`Franz\n\r"); } else { od_printf("`bright` ��� ��� ��� ��� � ��� `white`v`bright`3`white`.`bright`2\n\r"); od_printf("`bright black`������������������������`bright blue`��`bright black`��`bright blue`���`bright black`�`bright blue`��`bright black`��`bright blue`�`bright black`�`bright blue`�`bright black`�`bright blue`�`bright black`�`bright blue`�`bright black`�`bright blue`�`bright black`�`bright blue`�`bright black`�`bright blue`���`bright black`�`bright blue`��`bright black`�������������������������\n\r"); od_printf("`blue` � � ��� ��� � ��� �� ��� `bright black`by `white`Franz\n\r"); } } else { od_printf("------------------------< FREEVOTE v3.2 >---< by Franz >---------------------\n\r"); } /* od_printf("`bright red` v3.2\n\r"); // od_printf("`bright red` FrEevOTe\n\r"); od_printf("`green` Made by `bright green`Franz\n\r"); od_printf("`yellow` From EZVote\n\r"); od_printf("`red`");*/ /* if(od_control.user_ansi || od_control.user_avatar) { od_repeat((unsigned char)196, 79); } else { od_repeat('-', 79); }*/ od_printf("\n\r"); if(od_control.user_ansi || od_control.user_avatar) { if(colorsch==COLOR_DEF) od_printf("`bright red`"); else od_printf("`bright black`"); od_printf(" �������������������������������������\n\r"); if(colorsch==COLOR_DEF) od_printf("`red`"); else od_printf("`bright black`"); } else { od_printf(" -------------------------------------\n\r"); } if(colorsch==COLOR_DEF) { od_printf(" (`bright green`V`red`)`green` Vote on all new questions\n\r`red`"); od_printf(" (`bright green`I`red`)`green` Vote on an individual question\n\r`red`"); od_printf(" (`bright green`R`red`)`green` View the results of all questions\n\r`red`"); od_printf(" (`bright green`O`red`)`green` View the results of one question\n\r`red`"); } else { od_printf(" (`bright`V`bright black`) Vote on all new questions\n\r"); od_printf(" (`bright`I`bright black`) Vote on an individual question\n\r"); od_printf(" (`bright`R`bright black`) View the results of all questions\n\r"); od_printf(" (`bright`O`bright black`) View the results of one question\n\r"); } /* Display Add New Question option if adding questions is enabled, */ /* or if the system operator is using the door. */ if(bAllowAdd || sysop_sec<=od_control.user_security || strcmp(od_control.sysop_name, od_control.user_name) == 0) { if(colorsch==COLOR_DEF) od_printf(" (`bright green`A`red`)`green` Add a new question\n\r`red`"); else od_printf(" (`bright`A`bright black`) Add a new question\n\r"); } /* If current user is the system operator, add a D function to permit */ /* deletion of unwanted questions. and if users can delete their own! */ if(sysop_sec<=od_control.user_security || strcmp(od_control.sysop_name, od_control.user_name) == 0 || bAllowDelete) { if(colorsch==COLOR_DEF) od_printf(" (`bright green`D`red`)`green` Delete questions\n\r`red`"); else od_printf(" (`bright`D`bright black`) Delete questions\n\r"); } if(sysop_sec<=od_control.user_security || strcmp(od_control.sysop_name, od_control.user_name) == 0) { if(colorsch==COLOR_DEF) od_printf(" (`bright green`E`red`)`green` Edit questions\n\r`red`"); else od_printf(" (`bright`E`bright black`) Edit questions\n\r"); } if(sysop_sec<=od_control.user_security || strcmp(od_control.sysop_name, od_control.user_name) == 0 || bAllowChange) { if(colorsch==COLOR_DEF) od_printf(" (`bright green`C`red`)`green` Change your answers\n\r`red`"); else od_printf(" (`bright`C`bright black`) Change your answers\n\r"); } if(allow_page==TRUE) { if(colorsch==COLOR_DEF) od_printf(" (`bright green`P`red`)`green` Page system operator for chat\n\r`red`"); else od_printf(" (`bright`P`bright black`) Page system operator for chat\n\r"); } if(colorsch==COLOR_DEF) od_printf(" (`bright green`Q`red`)`green` Exit door and return to the BBS\n\r`red`"); else od_printf(" (`bright`Q`bright black`) Exit door and return to the BBS\n\r"); if(od_control.user_ansi || od_control.user_avatar) { if(colorsch==COLOR_DEF) od_printf("`bright red`"); od_printf(" �������������������������������������\n\r"); } else { od_printf(" -------------------------------------\n\r"); } if(colorsch==COLOR_DEF) od_printf(" `bright yellow`Time Left: %d mins\n\r",od_control.user_timelimit); else od_printf(" `bright black`Time Left`white`: `bright`%d `bright black`mins\n\r",od_control.user_timelimit); if(od_control.user_ansi || od_control.user_avatar) { if(colorsch==COLOR_DEF) od_printf("`bright red`"); od_printf(" �������������������������������������\n\r"); } else { od_printf(" -------------------------------------\n\r"); } if(colorsch==COLOR_DEF) od_printf(" `bright`Enter yer choice >`green`"); else od_printf(" `bright black`Enter yer choice `white`>`bright`"); } /* Get the user's choice from the main menu. This choice may only be */ /* V, R, A, D, P, E or H. */ chMenuChoice = od_get_answer("VIROADECPQ"); od_printf("%c\n\r",chMenuChoice); /* Perform the appropriate action based on the user's choice */ switch(chMenuChoice) { case 'V': /* Call EZVote's function to vote on new questions */ VoteOnQuestion(TRUE); break; case 'I': /* Call EZVote's function to vote on question */ VoteOnQuestion(FALSE); break; case 'R': /* Call EZVote's function to view the results of all voting */ ViewResults(TRUE); break; case 'O': /* Call EZVote's function to view the results of voting */ ViewResults(FALSE); break; case 'A': /* Call EZVote's function to add a new question if door is */ /* configured to allow the addition of question. */ if(bAllowAdd || sysop_sec<=od_control.user_security || strcmp(od_control.sysop_name, od_control.user_name) == 0) { AddQuestion(); } break; case 'E': if(sysop_sec<=od_control.user_security || strcmp(od_control.sysop_name, od_control.user_name) == 0) { QuestionEditor(); } break; case 'D': /* Call EZVote's funciton to delete an existing question */ DeleteQuestion(); break; case 'C': /* Call EZVote's function to add a new question if door is */ /* configured to allow the addition of question. */ if(bAllowChange || sysop_sec<=od_control.user_security || strcmp(od_control.sysop_name, od_control.user_name) == 0) { ChangeQuestion(); } break; case 'P': /* If the user pressed P, allow them page the system operator. */ if(allow_page==TRUE) od_page(); break; case 'Q': /* If the user pressed Q, exit door and return to BBS. */ od_exit(0, FALSE); break; } } // return(0); } void dump(void) { char key; do { scanf("%c",&key); } while (key!='\n'); } /* CustomConfigFunction() is called by OpenDoors to process custom */ /* configuration file keywords that EZVote uses. */ void CustomConfigFunction(char *pszKeyword, char *pszOptions) { int intval; if(stricmp(pszKeyword, "ViewUnanswered") == 0) { /* If keyword is ViewUnanswered, set local variable based on contents */ /* of options string. */ if(stricmp(pszOptions, "Yes") == 0) { nViewResultsFrom = QUESTIONS_VOTED_ON | QUESTIONS_NOT_VOTED_ON; } else if(stricmp(pszOptions, "No") == 0) { nViewResultsFrom = QUESTIONS_VOTED_ON; } } if(stricmp(pszKeyword, "ColorScheme") == 0) { /* If keyword is ViewUnanswered, set local variable based on contents */ /* of options string. */ if(stricmp(pszOptions, "DEF") == 0) { colorsch=COLOR_DEF; } else if(stricmp(pszOptions, "TNW") == 0) { colorsch=COLOR_TNW; } } if(stricmp(pszKeyword, "AnswerAdding") == 0) { if(stricmp(pszOptions, "Never") == 0) { answer_adding=0; } else if(stricmp(pszOptions, "Optional") == 0) { answer_adding=1; } else if(stricmp(pszOptions, "Forced") == 0) { answer_adding=2; } } if(stricmp(pszKeyword, "MultipleAdds") == 0) { if(stricmp(pszOptions, "Never") == 0) { more_adds_p_u=0; } else if(stricmp(pszOptions, "Optional") == 0) { more_adds_p_u=1; } else if(stricmp(pszOptions, "Forced") == 0) { more_adds_p_u=2; } } if(stricmp(pszKeyword, "NoSameAnswer") == 0) { /* If keyword is ViewUnanswered, set local variable based on contents */ /* of options string. */ if(stricmp(pszOptions, "Yes") == 0) { no_same_answers=TRUE; } else if(stricmp(pszOptions, "No") == 0) { no_same_answers=FALSE; } } if(stricmp(pszKeyword, "AllowAnonymous") == 0) { /* If keyword is ViewUnanswered, set local variable based on contents */ /* of options string. */ if(stricmp(pszOptions, "Yes") == 0) { anonymous_posting=TRUE; } else if(stricmp(pszOptions, "No") == 0) { anonymous_posting=FALSE; } } if(stricmp(pszKeyword, "MultipleAnswers") == 0) { /* If keyword is ViewUnanswered, set local variable based on contents */ /* of options string. */ if(stricmp(pszOptions, "Yes") == 0) { multiple_answers=TRUE; } else if(stricmp(pszOptions, "No") == 0) { multiple_answers=FALSE; } } if(stricmp(pszKeyword, "ViewOwnResults") == 0) { /* If keyword is ViewUnanswered, set local variable based on contents */ /* of options string. */ if(stricmp(pszOptions, "Yes") == 0) { view_own_results=TRUE; } else if(stricmp(pszOptions, "No") == 0) { view_own_results=FALSE; } } if(stricmp(pszKeyword, "AllowPage") == 0) { /* If keyword is ViewUnanswered, set local variable based on contents */ /* of options string. */ if(stricmp(pszOptions, "Yes") == 0) { allow_page=TRUE; } else if(stricmp(pszOptions, "No") == 0) { allow_page=FALSE; } } else if(stricmp(pszKeyword, "AllowAdd") == 0) { /* If keyword is ViewUnvoted, set local variable based on contents */ /* of options string. */ if(stricmp(pszOptions, "Yes") == 0) { bAllowAdd = TRUE; } else if(stricmp(pszOptions, "No") == 0) { bAllowAdd = FALSE; } } else if(stricmp(pszKeyword, "AddSecurity") == 0) { sscanf(pszOptions,"%d",&AddSecurity); if(AddSecurity<0) AddSecurity=0; } else if(stricmp(pszKeyword, "MinSecurity") == 0) { sscanf(pszOptions,"%d",&AllowIn); if(AllowIn<0) AllowIn=0; } else if(stricmp(pszKeyword, "ColoredResults") == 0) { /* If keyword is ViewUnvoted, set local variable based on contents */ /* of options string. */ if(stricmp(pszOptions, "Yes") == 0) { ColoredResults = TRUE; } else if(stricmp(pszOptions, "No") == 0) { ColoredResults = FALSE; } } else if(stricmp(pszKeyword, "AllowUnvote") == 0) { /* If keyword is ViewUnvoted, set local variable based on contents */ /* of options string. */ if(stricmp(pszOptions, "Yes") == 0) { bAllowUnvote = TRUE; } else if(stricmp(pszOptions, "No") == 0) { bAllowUnvote = FALSE; } } else if(stricmp(pszKeyword, "AllowChange") == 0) { /* If keyword is ViewUnvoted, set local variable based on contents */ /* of options string. */ if(stricmp(pszOptions, "Yes") == 0) { bAllowChange = TRUE; } else if(stricmp(pszOptions, "No") == 0) { bAllowChange = FALSE; } } else if(stricmp(pszKeyword, "AllowDelete") == 0) { /* If keyword is ViewUnvoted, set local variable based on contents */ /* of options string. */ if(stricmp(pszOptions, "Yes") == 0) { bAllowDelete = TRUE; } else if(stricmp(pszOptions, "No") == 0) { bAllowDelete = FALSE; } } else if(stricmp(pszKeyword, "DeleteAfter") == 0) { sscanf(pszOptions,"%d",&intval); maxtime= intval*24*60*60; } else if(stricmp(pszKeyword, "SysopSecurity") == 0) { sscanf(pszOptions,"%d",&sysop_sec); } else if(stricmp(pszKeyword, "UseHandles") == 0) { /* If keyword is ViewUnvoted, set local variable based on contents */ /* of options string. */ if(stricmp(pszOptions, "Yes") == 0) { bHandles = TRUE; } else if(stricmp(pszOptions, "No") == 0) { bHandles = FALSE; } } } void maint(void) { FILE *fpQuestionFile; FILE *fpPackFile; FILE *fpUserFile; time_t nowtime; tQuestionRecord QuestionRecord; tUserRecord UserRecord; int nFileQuestion=0; int deleted_n=0; char bQuestionDeleted[MAX_QUESTIONS]; int cnt,cnt2; int nFileUser=0; nowtime=time(NULL); /* Attempt to open question file. */ fpQuestionFile = ExculsiveFileOpen(QUESTION_FILENAME, "r+b"); /* If unable to open question file, assume that no questions have been */ /* created. */ if(fpQuestionFile == NULL) { return; } /* Loop for every question record in the file. */ while(freadQuestionRecord(&QuestionRecord, fpQuestionFile) == 1) { if(maxtime!=0 && (nowtime-QuestionRecord.lCreationTime)>maxtime && (QuestionRecord.bitflags & NEVER_DELETE_QUESTION)==FALSE) { fseek(fpQuestionFile,(long)nFileQuestion*QUESTIONRECORD_SIZE,SEEK_SET); QuestionRecord.bitflags|=QUESTION_DELETED; fwriteQuestionRecord(&QuestionRecord, fpQuestionFile); fseek(fpQuestionFile,(long)(1+nFileQuestion)*QUESTIONRECORD_SIZE,SEEK_SET); } if(QuestionRecord.bitflags & QUESTION_DELETED) { deleted_n++; bQuestionDeleted[nFileQuestion]=TRUE; } else { bQuestionDeleted[nFileQuestion]=FALSE; } /* Move to next question in file. */ ++nFileQuestion; } if(deleted_n>0) { fseek(fpQuestionFile,0,SEEK_SET); nFileQuestion=0; od_printf("\n\n\rThere are deleted questions!\n\n\rI will pack the question file NOW!\n\n\r"); fpPackFile=ExculsiveFileOpen("freevote.tmp","wb"); while(freadQuestionRecord(&QuestionRecord, fpQuestionFile) == 1) { if((QuestionRecord.bitflags & QUESTION_DELETED)==0) fwriteQuestionRecord(&QuestionRecord,fpPackFile); /* Move to next question in file. */ ++nFileQuestion; } fclose(fpQuestionFile); fclose(fpPackFile); remove("freevote.qst"); rename("freevote.tmp","freevote.qst"); od_printf("\n\rUserFile Packing"); fpUserFile=ExculsiveFileOpen(USER_FILENAME,"rb"); fpPackFile=ExculsiveFileOpen("freevote.tmp","wb"); nFileUser=0; while(freadUserRecord(&UserRecord, fpUserFile) == 1) { deleted_n=0; for(cnt=0;cnt<MAX_QUESTIONS;cnt++) { if(bQuestionDeleted[cnt]==TRUE) { for(cnt2=(cnt-deleted_n);cnt2<(MAX_QUESTIONS-1);cnt2++) { UserRecord.bVotedOnQuestion[cnt2]=UserRecord.bVotedOnQuestion[cnt2+1]; } deleted_n++; } } cnt2=0; for(cnt=0;cnt<nFileQuestion;cnt++) { if(UserRecord.bVotedOnQuestion[cnt]>0) cnt2++; } // od_printf("%s\n\r%d\n\r",UserRecord.szUserName,(int)UserRecord.szUserName[0]); if(UserRecord.szUserName[0]==0) cnt2=0; if(cnt2>0) { // od_printf("DEBUG:Wrote!\n\n\r"); fwriteUserRecord(&UserRecord,fpPackFile); } // WaitForEnter(); /* Move to next user in file. */ ++nFileUser; } fclose(fpUserFile); fclose(fpPackFile); remove("freevote.usr"); rename("freevote.tmp","freevote.usr"); od_printf("Done!!\n\r\n"); } else { fclose(fpQuestionFile); } /* Close question file to allow other nodes to access the file. */ } FILE *QRead(tQuestionRecord *QuestionRecord, int nQuestion) { FILE *fpFile; /* Open question file for exclusive access by this node. */ fpFile = ExculsiveFileOpen(QUESTION_FILENAME, "r+b"); if(fpFile == NULL) { /* If unable to access file, display error and return. */ od_printf("Unable to access the question file.\n\r"); WaitForEnter(); return(NULL); } /* Read the answer record from disk, because it may have been changed. */ /* by another node. */ fseek(fpFile, (long)nQuestion * QUESTIONRECORD_SIZE, SEEK_SET); if(freadQuestionRecord(QuestionRecord, fpFile) != 1) { /* If unable to access file, display error and return. */ fclose(fpFile); od_printf("\n\rUnable to read from question file.\n\r"); WaitForEnter(); return(NULL); } return(fpFile); } int QWrite(tQuestionRecord *QuestionRecord, FILE *fpFile, int nQuestion) { /* Write the question record back to the file. */ fseek(fpFile, (long)nQuestion * QUESTIONRECORD_SIZE, SEEK_SET); if(fwriteQuestionRecord(QuestionRecord, fpFile) != 1) { /* If unable to access file, display error and return. */ fclose(fpFile); od_printf("\n\rUnable to write question to file.\n\r"); WaitForEnter(); return(0); } /* Close the question file to allow access by other nodes. */ fclose(fpFile); return(1); } void QuestionEditor(void) { int nQuestion=-1; int nAnswer; unsigned int votedon; tQuestionRecord QuestionRecord; char szNewAnswer[ANSWER_STR_SIZE]; char szNewAnswer2[ANSWER_STR_SIZE]; char szQuestion[QUESTION_STR_SIZE]; char szUserInput[3]; char key,skey; FILE *fpUserFile; int nFileUser; tUserRecord UserRecord; FILE *fpFile; int nPageLocation = 0; int cnt,cnt2,x,alad; /* int aladd;*/ // char addcnt=TRUE; /* Loop until the user chooses to return to the main menu, or until */ /* there are no more questions to vote on. */ for(;;) { nextques: /* aladd=TRUE;*/ // addcnt=TRUE; nQuestion = ChooseQuestion(QUESTIONS_NOT_VOTED_ON | QUESTIONS_VOTED_ON, " Edit A Question\n\r", &nPageLocation); /* If the user did not choose a question, return to main menu. */ if(nQuestion == NO_QUESTION) { return; } /* Read the question chosen by the user. */ if(!GetQuestion(nQuestion, &QuestionRecord)) { /* If unable to access file, return to main menu. */ return; } /* Don't allow addition of new answers if maximum number of answers */ /* have already been added. */ alad=TRUE; if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { if(QuestionRecord.nTotalAnswers >= MAX_ANSWERS) { alad=FALSE; } } else { if(QuestionRecord.nTotalAnswers >= MAX_ANSWERS2) { alad=FALSE; } } /* Loop until user makes a valid respose. */ for(;;) { /* Display question to user. */ /* Clear the screen. */ // od_printf("\n\n\r"); my_clr_scr(); /* Display question itself. */ od_printf("`bright`Q) `bright red`%s\n\r", QuestionRecord.szQuestion); od_printf("`bright`N) `red`By: `bright red`%s",QuestionRecord.szCreatorName); od_printf(" `red`People that voted: `bright red`%u\n\n\r",QuestionRecord.uTotalVotes); od_printf("`bright`!) `red`Never delete: `bright red`"); if(QuestionRecord.bitflags & NEVER_DELETE_QUESTION) od_printf("ON "); else od_printf("OFF "); od_printf("`bright`@) `red`Can Add Answers: `bright red`"); if(QuestionRecord.bitflags & CAN_ADD_ANSWERS) od_printf("ON "); else od_printf("OFF "); od_printf("`bright`#) `red`Multiple Answer Question: `bright red`"); if(QuestionRecord.bitflags & MULTIPLE_ANSWERS) od_printf("ON\n\r"); else od_printf("OFF\n\r"); od_printf("`bright`$) `red`Anonymous: `bright red`"); if(QuestionRecord.bitflags & ANONYMOUS_QUESTION) od_printf("ON "); else od_printf("OFF "); od_printf(" `bright`*) `red`Forced Question: `bright red`"); if(QuestionRecord.bitflags & FORCED_QUESTION) od_printf("ON "); else od_printf("OFF "); od_printf("`bright`&) `red`Multiple Adds Per User: `bright red`"); if(QuestionRecord.bitflags & MULTIPLE_ADDS_P_U) od_printf("ON\n\n\r"); else od_printf("OFF\n\n\r"); /* Loop for each answer to the question. */ for(nAnswer = cnt = cnt2 = 0; nAnswer < QuestionRecord.nTotalAnswers; ++nAnswer) { /* Display answer number and answer. */ cnt2++; od_printf("`bright`%2d) `green`%s `red`Votes: `bright red`%u", nAnswer + 1, QuestionRecord.aszAnswer[cnt], QuestionRecord.auVotesForAnswer[nAnswer]); od_printf("\n\r"); if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { cnt++; } else { if(strlen(QuestionRecord.aszAnswer[cnt+1])>0) od_printf(" `green`%s\n\r",QuestionRecord.aszAnswer[cnt+1]); cnt+=2; } /* } else { if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { cnt++; } else { cnt+=2; } }*/ } /* Display prompt to user. */ od_printf("\n\r`bright`Enter what to change or [E]rase answer, "); if(alad) od_printf("[A]dd answer, "); od_printf("[R]eset votes, [D]one: `green`"); /* Get response from user. */ od_input_str(szUserInput, 2, ' ', 255); /* Add a blank line. */ od_printf("\n\r"); /* If user entered Q, return to main menu. */ if (szUserInput[0]=='D' || szUserInput[0]=='d') { goto nextques; } nAnswer = atoi(szUserInput) - 1; /* If user enetered A, and adding answers is premitted ... */ if ((szUserInput[0]=='A' || szUserInput[0]=='a') && alad==TRUE) { /* ... Prompt for answer from user. */ od_printf("`bright green`Please enter the new answer:\n\r"); od_printf("`green`[------------------------------]\n\r "); if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { /* Get string from user. */ od_input_str(szNewAnswer, ANSWER_STR_SIZE - 1, ' ', 255); } else { warp_line(szNewAnswer,szNewAnswer2," "); } /* If user entered a valid answer, then exit loop. */ if(strlen(szNewAnswer) > 0 || ((QuestionRecord.bitflags & BF_15_BY_1_MODE)&&strlen(szNewAnswer2) > 0)) { /* Check that there is still room for another answer. */ if(QuestionRecord.bitflags & BF_15_BY_1_MODE) cnt=MAX_ANSWERS; else cnt=MAX_ANSWERS2; if((fpFile=QRead(&QuestionRecord,nQuestion))==NULL) return; if(QuestionRecord.nTotalAnswers >= cnt) { fclose(fpFile); od_printf("Sorry, this question already has the maximum number of answers.\n\r"); WaitForEnter(); return; } nAnswer=QuestionRecord.nTotalAnswers; ++QuestionRecord.nTotalAnswers; /* Initialize new answer string and count. */ if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { strcpy(QuestionRecord.aszAnswer[nAnswer], szNewAnswer); } else { strcpy(QuestionRecord.aszAnswer[nAnswer*2], szNewAnswer); strcpy(QuestionRecord.aszAnswer[(nAnswer*2)+1], szNewAnswer2); } QuestionRecord.auVotesForAnswer[nAnswer] = 0; if(!QWrite(&QuestionRecord,fpFile,nQuestion)) return; } /* If user enetered E*/ } else if (szUserInput[0]=='E' || szUserInput[0]=='e') { /* ... Prompt for answer from user. */ od_printf("`bright`Which answer to erase or [Q]uit: `green`"); od_input_str(szUserInput, 2, ' ', 255); if(szUserInput[0]!='Q' && szUserInput[0]!='q') { nAnswer = atoi(szUserInput) - 1; if(nAnswer >= 0 && nAnswer < QuestionRecord.nTotalAnswers) { od_printf("\n\r`bright`Are you sure? (Y/N) `green`"); if(od_get_answer("YN")=='Y') { od_printf("Yes\n\r\n`red`Working ..."); if((fpFile=QRead(&QuestionRecord,nQuestion))==NULL) return; if(nAnswer<(QuestionRecord.nTotalAnswers-1)) { for(x=nAnswer;x<(QuestionRecord.nTotalAnswers-1);x++) { if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { strcpy(QuestionRecord.aszAnswer[x], QuestionRecord.aszAnswer[x+1]); } else { strcpy(QuestionRecord.aszAnswer[x*2], QuestionRecord.aszAnswer[((x+1)*2)]); strcpy(QuestionRecord.aszAnswer[(x*2)+1], QuestionRecord.aszAnswer[((x+1)*2)+1]); } QuestionRecord.auVotesForAnswer[x] = QuestionRecord.auVotesForAnswer[x+1]; } fpUserFile=ExculsiveFileOpen(USER_FILENAME,"r+b"); nFileUser=0; while(freadUserRecord(&UserRecord, fpUserFile) == 1) { votedon=UserRecord.bVotedOnQuestion[nQuestion]; UserRecord.bVotedOnQuestion[nQuestion]=0; if(votedon & answers[15]) UserRecord.bVotedOnQuestion[nQuestion] |= answers[15]; for(x=0;x<nAnswer;x++) { if(votedon & answers[x]) UserRecord.bVotedOnQuestion[nQuestion] |= answers[x]; } for(x=nAnswer;x<(QuestionRecord.nTotalAnswers-1);x++) { if(votedon & answers[x+1]) UserRecord.bVotedOnQuestion[nQuestion] |= answers[x]; } fseek(fpUserFile,(long)nFileUser * (long)USERRECORD_SIZE,SEEK_SET); fwriteUserRecord(&UserRecord, fpUserFile); ++nFileUser; fseek(fpUserFile,(long)nFileUser * (long)USERRECORD_SIZE,SEEK_SET); } fclose(fpUserFile); votedon=CurrentUserRecord.bVotedOnQuestion[nQuestion]; CurrentUserRecord.bVotedOnQuestion[nQuestion]=0; if(votedon & answers[15]) CurrentUserRecord.bVotedOnQuestion[nQuestion] |= answers[15]; for(x=0;x<nAnswer;x++) { if(votedon & answers[x]) CurrentUserRecord.bVotedOnQuestion[nQuestion] |= answers[x]; } for(x=nAnswer;x<(QuestionRecord.nTotalAnswers-1);x++) { if(votedon & answers[x+1]) CurrentUserRecord.bVotedOnQuestion[nQuestion] |= answers[x]; } WriteCurrentUser(); } else { fpUserFile=ExculsiveFileOpen(USER_FILENAME,"r+b"); nFileUser=0; while(freadUserRecord(&UserRecord, fpUserFile) == 1) { UserRecord.bVotedOnQuestion[nQuestion] &=~ answers[nAnswer]; fseek(fpUserFile,(long)nFileUser * (long)USERRECORD_SIZE,SEEK_SET); fwriteUserRecord(&UserRecord, fpUserFile); ++nFileUser; fseek(fpUserFile,(long)nFileUser * (long)USERRECORD_SIZE,SEEK_SET); } fclose(fpUserFile); CurrentUserRecord.bVotedOnQuestion[nQuestion] &=~ answers[nAnswer]; WriteCurrentUser(); } QuestionRecord.nTotalAnswers--; if(!QWrite(&QuestionRecord,fpFile,nQuestion)) return; } else { od_printf("No"); } } } } else if ((szUserInput[0]=='Q' || szUserInput[0]=='q')) { od_printf("`bright green`Enter The Question (blank line cancels)\n\r"); od_printf("`green`[----------------------------------------------------------------------]\n\r "); od_input_str(szQuestion, QUESTION_STR_SIZE - 1, ' ', 255); if(szQuestion[0]!=0) { if((fpFile=QRead(&QuestionRecord,nQuestion))==NULL) return; strcpy(QuestionRecord.szQuestion,szQuestion); if(!QWrite(&QuestionRecord,fpFile,nQuestion)) return; } } else if ((szUserInput[0]=='N' || szUserInput[0]=='n')) { od_printf("`bright green`Enter The Creator's Name\n\r"); od_printf("`green`[----------------------------------]\n\r "); od_input_str(szQuestion, 35, ' ', 255); if(szQuestion[0]!=0) { if((fpFile=QRead(&QuestionRecord,nQuestion))==NULL) return; strcpy(QuestionRecord.szCreatorName,szQuestion); if(!QWrite(&QuestionRecord,fpFile,nQuestion)) return; } } else if (szUserInput[0]=='R' || szUserInput[0]=='r') { od_printf("`bright red`Reset what?\n\n\r"); od_printf("`bright`1 - `bright red`Vote counts\n\r"); od_printf("`bright`2 - `bright red`Make All users vote on this question again\n\r"); od_printf("`bright`3 - `bright red`Do both ... recommended\n\r"); od_printf("`bright`Q - `bright red`Quit\n\n\r"); od_printf("`bright red`So what is it:"); key=od_get_answer("123Q"); if(key!='Q') { od_printf(" `bright green`%c\n\n\r",key); od_printf("`bright`Ya sure ya wanna do that? (Y/N)"); if(od_get_answer("YN")=='Y') { od_printf(" `bright green`Yes\n\n\r`red`Working..."); if((fpFile=QRead(&QuestionRecord,nQuestion))==NULL) return; if(key=='1' || key=='3') { for(x=0;x<15;x++) { QuestionRecord.auVotesForAnswer[x] = 0; } QuestionRecord.uTotalVotes=0; } if(key=='2' || key=='3') { fpUserFile=ExculsiveFileOpen(USER_FILENAME,"r+b"); nFileUser=0; while(freadUserRecord(&UserRecord, fpUserFile) == 1) { UserRecord.bVotedOnQuestion[nQuestion]=0; fseek(fpUserFile,(long)nFileUser * (long)USERRECORD_SIZE,SEEK_SET); fwriteUserRecord(&UserRecord, fpUserFile); ++nFileUser; fseek(fpUserFile,(long)nFileUser * (long)USERRECORD_SIZE,SEEK_SET); } fclose(fpUserFile); CurrentUserRecord.bVotedOnQuestion[nQuestion]=0; WriteCurrentUser(); } if(!QWrite(&QuestionRecord,fpFile,nQuestion)) return; } else { od_printf(" `bright green`No"); } } else { od_printf(" `bright green`Quit"); } } else if (szUserInput[0]=='!') { if((fpFile=QRead(&QuestionRecord,nQuestion))==NULL) return; QuestionRecord.bitflags ^= NEVER_DELETE_QUESTION; if(!QWrite(&QuestionRecord,fpFile,nQuestion)) return; } else if (szUserInput[0]=='@') { if((fpFile=QRead(&QuestionRecord,nQuestion))==NULL) return; QuestionRecord.bitflags ^= CAN_ADD_ANSWERS; if(!QWrite(&QuestionRecord,fpFile,nQuestion)) return; } else if (szUserInput[0]=='#') { if((fpFile=QRead(&QuestionRecord,nQuestion))==NULL) return; QuestionRecord.bitflags ^= MULTIPLE_ANSWERS; if(!QWrite(&QuestionRecord,fpFile,nQuestion)) return; } else if (szUserInput[0]=='$') { if((fpFile=QRead(&QuestionRecord,nQuestion))==NULL) return; QuestionRecord.bitflags ^= ANONYMOUS_QUESTION; if(!QWrite(&QuestionRecord,fpFile,nQuestion)) return; } else if (szUserInput[0]=='&') { if((fpFile=QRead(&QuestionRecord,nQuestion))==NULL) return; QuestionRecord.bitflags ^= MULTIPLE_ADDS_P_U; if(!QWrite(&QuestionRecord,fpFile,nQuestion)) return; } else if (szUserInput[0]=='*') { if((fpFile=QRead(&QuestionRecord,nQuestion))==NULL) return; QuestionRecord.bitflags ^= FORCED_QUESTION; if(!QWrite(&QuestionRecord,fpFile,nQuestion)) return; } else if(nAnswer < 0 || nAnswer >= QuestionRecord.nTotalAnswers) { /* Display message. */ od_printf("That is not a valid response.\n\r\n"); WaitForEnter(); } else { od_printf("`bright green`Please enter the new answer:\n\r"); od_printf("`green`[------------------------------]\n\r "); if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { /* Get string from user. */ od_input_str(szNewAnswer, ANSWER_STR_SIZE - 1, ' ', 255); } else { warp_line(szNewAnswer,szNewAnswer2," "); } if(strlen(szNewAnswer) > 0 || ((QuestionRecord.bitflags & BF_15_BY_1_MODE)&&strlen(szNewAnswer2) > 0)) { if((fpFile=QRead(&QuestionRecord,nQuestion))==NULL) return; /* Initialize new answer string and count. */ if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { strcpy(QuestionRecord.aszAnswer[nAnswer], szNewAnswer); } else { strcpy(QuestionRecord.aszAnswer[nAnswer*2], szNewAnswer); strcpy(QuestionRecord.aszAnswer[(nAnswer*2)+1], szNewAnswer2); } if(!QWrite(&QuestionRecord,fpFile,nQuestion)) return; } } } } } /* EZVote configures OpenDoors to call the BeforeExitFunction() before */ /* the door exists for any reason. You can use this function to close any */ /* files or perform any other operations that you wish to have peformed */ /* before OpenDoors exists for any reason. The od_control.od_before_exit */ /* variable sets the function to be called before program exit. */ void BeforeExitFunction(void) { char szLogMessage[80]; WriteCurrentUser(); /* Write number of messages voted on to log file. */ sprintf(szLogMessage, "User has voted on %d question(s)", nQuestionsVotedOn); od_log_write(szLogMessage); if(Forcevote!=4) { if(colorsch==COLOR_DEF) od_printf("\n\r\n`bright red`You have voted on %d question(s)\n\r\n", nQuestionsVotedOn); else od_printf("\n\r\n`bright black`You have voted on `bright`%d`bright black` question(s)\n\r\n", nQuestionsVotedOn); if(colorsch==COLOR_DEF) od_printf("`bright green`Returning ..."); else od_printf("`bright black`Returning ..."); } od_control.user_security=b_us; } /* EZVote calls the VoteOnQuestion() function when the user chooses the */ /* vote command from the main menu. This function displays a list of */ /* available topics, asks for the user's answer to the topic they select, */ /* and display's the results of voting on that topic. */ void VoteOnQuestion(int all) { int nQuestion=-1; int nAnswer; tQuestionRecord QuestionRecord; char szNewAnswer[ANSWER_STR_SIZE]; char szNewAnswer2[ANSWER_STR_SIZE]; char szUserInput[3]; FILE *fpFile; int nPageLocation = 0; int cnt,cnt2,x; /* int aladd;*/ // char addcnt=TRUE; /* Loop until the user chooses to return to the main menu, or until */ /* there are no more questions to vote on. */ for(;;) { skipques: /* aladd=TRUE;*/ // addcnt=TRUE; if (all==FALSE) { /* Allow the user to choose a question from the list of questions */ /* that they have not voted on. */ nQuestion = ChooseQuestion(QUESTIONS_NOT_VOTED_ON, " Vote On A Question\n\r", &nPageLocation); } else { if(Forcevote<100) { nQuestion = FirstQuestion(QUESTIONS_NOT_VOTED_ON,nQuestion+1); } else { nQuestion = FirstQuestion(QUESTIONS_NOT_VOTED_ON | QUESTIONS_FORCED,nQuestion+1); } } /* If the user did not choose a question, return to main menu. */ if(nQuestion == NO_QUESTION) { return; } /* Read the question chosen by the user. */ if(!GetQuestion(nQuestion, &QuestionRecord)) { /* If unable to access file, return to main menu. */ return; } moreanswers: /* Don't allow addition of new answers if maximum number of answers */ /* have already been added. */ if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { if(QuestionRecord.nTotalAnswers >= MAX_ANSWERS) { QuestionRecord.bitflags &=~ CAN_ADD_ANSWERS; } } else { if(QuestionRecord.nTotalAnswers >= MAX_ANSWERS2) { QuestionRecord.bitflags &=~ CAN_ADD_ANSWERS; } } /* Loop until user makes a valid respose. */ for(;;) { /* Display question to user. */ /* Clear the screen. */ // od_printf("\n\n\r"); my_clr_scr(); /* Display question itself. */ if(colorsch==COLOR_DEF) od_printf("`bright red`"); else od_printf("`bright`"); od_printf("%s\n\r", QuestionRecord.szQuestion); if(sysop_sec<=od_control.user_security || strcmp(od_control.sysop_name, od_control.user_name) == 0) { od_printf("`red`(%s)\n\r",QuestionRecord.szCreatorName); } else { od_printf("\n\r"); } /* Loop for each answer to the question. */ for(nAnswer = cnt = cnt2 = 0; nAnswer < QuestionRecord.nTotalAnswers; ++nAnswer) { /* Display answer number and answer. */ cnt2++; if(colorsch==COLOR_DEF) od_printf("`bright green`%2d. `green`%s", nAnswer + 1, QuestionRecord.aszAnswer[cnt]); else od_printf("`bright`%2d. `bright black`%s", nAnswer + 1, QuestionRecord.aszAnswer[cnt]); if((CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[nAnswer])==FALSE) od_printf("\n\r"); else { if(colorsch==COLOR_DEF) od_printf("`bright red`"); else od_printf("`bright`"); od_printf(" [Voted On]\n\r"); } if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { cnt++; } else { if(strlen(QuestionRecord.aszAnswer[cnt+1])>0) { if(colorsch==COLOR_DEF) od_printf("`green`"); else od_printf("`bright black`"); od_printf(" %s\n\r",QuestionRecord.aszAnswer[cnt+1]); } cnt+=2; } /* } else { if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { cnt++; } else { cnt+=2; } }*/ } if(cnt2==0) goto donewith; if(QuestionRecord.bitflags & MULTIPLE_ANSWERS) { if(colorsch==COLOR_DEF) od_printf("`bright`\n\rThis question allows multiple answers, select all you want and press [D]one"); else od_printf("`bright black`\n\rThis question allows multiple answers`white`,`bright black` select all you want and press `white`[`bright black`D`white`]`bright black`one"); } /* Display prompt to user. */ if(colorsch==COLOR_DEF) od_printf("`bright`"); else od_printf("`bright black`"); od_printf("\n\rEnter answer number"); if((QuestionRecord.bitflags & CAN_ADD_ANSWERS) && ((CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[15])==FALSE || QuestionRecord.bitflags & MULTIPLE_ADDS_P_U)) { if(colorsch==COLOR_DEF) od_printf(", [A]dd your own response"); else od_printf("`white`, [`bright black`A`white`]`bright black`dd your own response"); } if(Forcevote!=2 && Forcevote!=4 && Forcevote<100) { if(all==TRUE) { if(colorsch==COLOR_DEF) od_printf(", [S]kip"); else od_printf("`white`, [`bright black`S`white`]`bright black`kip"); } if(colorsch==COLOR_DEF) od_printf(", [Q]uit"); else od_printf("`white`, [`bright black`Q`white`]`bright black`uit"); } if(colorsch==COLOR_DEF) od_printf(": `green`"); else od_printf("`white`: `bright`"); /* Get response from user. */ od_input_str(szUserInput, 2, ' ', 255); /* Add a blank line. */ od_printf("\n\r"); if(Forcevote!=2 && Forcevote!=4 && Forcevote<100) { /* If user entered Q, return to main menu. */ if (szUserInput[0]=='Q' || szUserInput[0]=='q') { return; } if (szUserInput[0]=='S' || szUserInput[0]=='s') { goto skipques; } } if((QuestionRecord.bitflags & MULTIPLE_ANSWERS) && (CurrentUserRecord.bVotedOnQuestion[nQuestion]!=answers[15] && CurrentUserRecord.bVotedOnQuestion[nQuestion]!=0)) { if (szUserInput[0]=='D' || szUserInput[0]=='d') { goto donewith; } } /* If user enetered A, and adding answers is premitted ... */ if ((szUserInput[0]=='A' || szUserInput[0]=='a') && (QuestionRecord.bitflags & CAN_ADD_ANSWERS) && ((CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[15])==FALSE || QuestionRecord.bitflags & MULTIPLE_ADDS_P_U)) { /* aladd=FALSE;*/ /* ... Prompt for answer from user. */ if(colorsch==COLOR_DEF) { od_printf("`bright green`Please enter your new answer:\n\r"); od_printf("`green`[------------------------------]\n\r "); } else { od_printf("`bright black`Please enter your new answer`white`:\n\r"); od_printf("`white`[------------------------------]\n\r "); } if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { /* Get string from user. */ od_input_str(szNewAnswer, ANSWER_STR_SIZE - 1, ' ', 255); } else { warp_line(szNewAnswer,szNewAnswer2," "); } /* Get string from user. */ /* od_input_str(szNewAnswer, ANSWER_STR_SIZE - 1, ' ', 255); if(!(QuestionRecord.bitflags & BF_15_BY_1_MODE)) { od_printf(" "); od_input_str(szNewAnswer2, ANSWER_STR_SIZE - 1, ' ', 255); }*/ /* Record that user entered a new answer answer. */ nAnswer = NEW_ANSWER; /* If user entered a valid answer, then exit loop. */ if(strlen(szNewAnswer) > 0 || ((QuestionRecord.bitflags & BF_15_BY_1_MODE)&&strlen(szNewAnswer2) > 0)) { break; } } /* Otherwise, attempt to get answer number from user. */ nAnswer = atoi(szUserInput) - 1; if((QuestionRecord.bitflags & MULTIPLE_ANSWERS) && (CurrentUserRecord.bVotedOnQuestion[nQuestion]==0 || CurrentUserRecord.bVotedOnQuestion[nQuestion]==answers[15]) && (szUserInput[0]=='D' || szUserInput[0]=='d')) { if(colorsch!=COLOR_DEF) od_printf("`bright black`"); od_printf("You need to have at least one answer checked"); if(colorsch!=COLOR_DEF) od_printf("`white`"); od_printf("!\n\r\n"); WaitForEnter(); } /* If user input is not a valid answer. */ else if(nAnswer < 0 || nAnswer >= QuestionRecord.nTotalAnswers) // || (CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[nAnswer])) { /* Display message. */ if(colorsch!=COLOR_DEF) od_printf("`bright black`"); od_printf("That is not a valid response"); if(colorsch!=COLOR_DEF) od_printf("`white`"); od_printf(".\n\r\n"); WaitForEnter(); } else { /* Otherwise, exit loop. */ break; } } /* Add user's vote to question. */ /* If user entered their own answer, try to add it to the question. */ if(nAnswer == NEW_ANSWER) { /* Check that there is still room for another answer. */ if(QuestionRecord.bitflags & BF_15_BY_1_MODE) cnt=MAX_ANSWERS; else cnt=MAX_ANSWERS2; if((fpFile=QRead(&QuestionRecord,nQuestion))==NULL) return; if(QuestionRecord.nTotalAnswers >= cnt) { fclose(fpFile); if(colorsch!=COLOR_DEF) od_printf("`bright black`"); od_printf("Sorry, this question already has the maximum number of answers"); if(colorsch!=COLOR_DEF) od_printf("`white`"); od_printf(".\n\r"); WaitForEnter(); return; } /* Set answer number to number of new answer. */ nAnswer = QuestionRecord.nTotalAnswers; /* Add 1 to total number of answers. */ ++QuestionRecord.nTotalAnswers; /* Initialize new answer string and count. */ if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { strcpy(QuestionRecord.aszAnswer[nAnswer], szNewAnswer); } else { strcpy(QuestionRecord.aszAnswer[nAnswer*2], szNewAnswer); strcpy(QuestionRecord.aszAnswer[(nAnswer*2)+1], szNewAnswer2); } QuestionRecord.auVotesForAnswer[nAnswer] = 0; if(!QWrite(&QuestionRecord,fpFile,nQuestion)) return; CurrentUserRecord.bVotedOnQuestion[nQuestion] |= answers[15]; } /* Add user's vote to question. */ /*else --QuestionRecord.auVotesForAnswer[nAnswer];*/ // if(addcnt) // addcnt=FALSE; /* Record that user has voted on this question. */ if(CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[nAnswer]) CurrentUserRecord.bVotedOnQuestion[nQuestion] &=~ answers[nAnswer]; else CurrentUserRecord.bVotedOnQuestion[nQuestion] |= answers[nAnswer]; if(QuestionRecord.bitflags & MULTIPLE_ANSWERS) goto moreanswers; donewith: if((fpFile=QRead(&QuestionRecord,nQuestion))==NULL) return; ++QuestionRecord.uTotalVotes; for(x=0;x<15;x++) { if(CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[x]) ++QuestionRecord.auVotesForAnswer[x]; } if(!QWrite(&QuestionRecord,fpFile,nQuestion)) return; WriteCurrentUser(); /* Open user file for exclusive access by this node. */ // fpFile = ExculsiveFileOpen(USER_FILENAME, "r+b"); // if(fpFile == NULL) // { /* If unable to access file, display error and return. */ // od_printf("Unable to access the user file.\n\r"); // WaitForEnter(); // return; // } /* Update the user's record in the user file. */ // fseek(fpFile, (long)nCurrentUserNumber * USERRECORD_SIZE, SEEK_SET); // if(fwrite(&CurrentUserRecord, sizeof(tUserRecord), 1, fpFile) != 1) // { /* If unable to access file, display error and return. */ // fclose(fpFile); // od_printf("Unable to write to user file.\n\r"); // WaitForEnter(); // return; // } /* Close the user file to allow access by other nodes. */ // fclose(fpFile); /* Display the result of voting on this question to the user. */ DisplayQuestionResult(&QuestionRecord,FALSE); /* Add 1 to count of questions that the user has voted on. */ nQuestionsVotedOn++; } } void ChangeQuestion(void) { int nQuestion=-1; int nAnswer; tQuestionRecord QuestionRecord; char szNewAnswer[ANSWER_STR_SIZE]; char szNewAnswer2[ANSWER_STR_SIZE]; char szUserInput[3]; FILE *fpFile; unsigned int original_answers; int nPageLocation = 0; int cnt,cnt2,decvotes=FALSE,x; /* Loop until the user chooses to return to the main menu, or until */ /* there are no more questions to vote on. */ for(;;) { /* Allow the user to choose a question from the list of questions */ /* that they have not voted on. */ nQuestion = ChooseQuestion(QUESTIONS_VOTED_ON, " Change A Vote\n\r", &nPageLocation); /* If the user did not choose a question, return to main menu. */ if(nQuestion == NO_QUESTION) { return; } /* moreanswers:*/ /* Read the question chosen by the user. */ if(!GetQuestion(nQuestion, &QuestionRecord)) { /* If unable to access file, return to main menu. */ return; } original_answers=CurrentUserRecord.bVotedOnQuestion[nQuestion]; decvotes=FALSE; moreanswers: /* Don't allow addition of new answers if maximum number of answers */ /* have already been added. */ if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { if(QuestionRecord.nTotalAnswers >= MAX_ANSWERS) { QuestionRecord.bitflags &=~ CAN_ADD_ANSWERS; } } else { if(QuestionRecord.nTotalAnswers >= MAX_ANSWERS2) { QuestionRecord.bitflags &=~ CAN_ADD_ANSWERS; } } /* Loop until user makes a valid respose. */ for(;;) { /* Display question to user. */ /* Clear the screen. */ // od_printf("\n\n\r"); my_clr_scr(); /* Display question itself. */ if(colorsch==COLOR_DEF) od_printf("`bright red`"); else od_printf("`bright`"); od_printf("%s\n\r\n\r", QuestionRecord.szQuestion); /* Loop for each answer to the question. */ for(nAnswer = cnt = cnt2 = 0; nAnswer < QuestionRecord.nTotalAnswers; ++nAnswer) { /* if(CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[nAnswer]) { od_printf("`bright red`->"); } else { od_printf(" "); }*/ /* Display answer number and answer. */ cnt2++; if(colorsch==COLOR_DEF) od_printf("`bright green`%2d. `green`%s", nAnswer + 1, QuestionRecord.aszAnswer[cnt]); else od_printf("`bright`%2d. `bright black`%s", nAnswer + 1, QuestionRecord.aszAnswer[cnt]); if(CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[nAnswer]) { if(colorsch==COLOR_DEF) od_printf("`bright red`"); else od_printf("`bright`"); od_printf(" [Voted On]\n\r"); } else { od_printf("\n\r"); } if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { cnt++; } else { if(strlen(QuestionRecord.aszAnswer[cnt+1])>0) if(colorsch==COLOR_DEF) od_printf("`green`"); else od_printf("`bright black`"); od_printf(" %s\n\r",QuestionRecord.aszAnswer[cnt+1]); cnt+=2; } } if(cnt2==0) goto donewith; if(QuestionRecord.bitflags & MULTIPLE_ANSWERS) { if(colorsch==COLOR_DEF) od_printf("`bright`\n\rThis question allows multiple answers, Toggle your answers and press [D]one"); else od_printf("`bright black`\n\rThis question allows multiple answers`white`, `bright black`Toggle your answers and press `white`[`bright black`D`white`]`bright black`one"); } /* Display prompt to user. */ if(colorsch==COLOR_DEF) od_printf("`bright`"); else od_printf("`bright black"); od_printf("\n\rEnter answer number"); if((QuestionRecord.bitflags & CAN_ADD_ANSWERS) && ((CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[15])==FALSE || QuestionRecord.bitflags & MULTIPLE_ADDS_P_U)) { if(colorsch==COLOR_DEF) od_printf(", [A]dd your own response"); else od_printf("`white`, [`bright black`A`white`]`bright black`dd your own response"); } if(bAllowUnvote==TRUE) { if(colorsch==COLOR_DEF) od_printf(", [M]ark as unanswered"); else od_printf("`white`, [`bright black`M`white`]`bright black`ark as unanswered"); } if(colorsch==COLOR_DEF) od_printf(", [Q]uit: `green`"); else od_printf("`white`, [`bright black`Q`white`]`bright black`uit`white`: `bright`"); /* Get response from user. */ od_input_str(szUserInput, 2, ' ', 255); /* Add a blank line. */ od_printf("\n\r"); /* If user entered Q, return to main menu. */ if (szUserInput[0]=='Q' || szUserInput[0]=='q') { return; } /* If user enetered A, and adding answers is premitted ... */ if ((szUserInput[0]=='A' || szUserInput[0]=='a') && (QuestionRecord.bitflags & CAN_ADD_ANSWERS) && ((CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[15])==FALSE || QuestionRecord.bitflags & MULTIPLE_ADDS_P_U)) { /* ... Prompt for answer from user. */ if(colorsch==COLOR_DEF) { od_printf("`bright green`Please enter your new answer:\n\r"); od_printf("`green`[------------------------------]\n\r "); } else { od_printf("`bright black`Please enter your new answer`white`:\n\r"); od_printf("[------------------------------]\n\r "); } if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { /* Get string from user. */ od_input_str(szNewAnswer, ANSWER_STR_SIZE - 1, ' ', 255); } else { warp_line(szNewAnswer,szNewAnswer2," "); } /* Get string from user. */ /* od_input_str(szNewAnswer, ANSWER_STR_SIZE - 1, ' ', 255); if(!(QuestionRecord.bitflags & BF_15_BY_1_MODE)) { od_printf(" "); od_input_str(szNewAnswer2, ANSWER_STR_SIZE - 1, ' ', 255); }*/ /* Record that user entered a new answer answer. */ nAnswer = NEW_ANSWER; /* If user entered a valid answer, then exit loop. */ if(strlen(szNewAnswer) > 0) { break; } } if((QuestionRecord.bitflags & MULTIPLE_ANSWERS) && (CurrentUserRecord.bVotedOnQuestion[nQuestion]!=answers[15] && CurrentUserRecord.bVotedOnQuestion[nQuestion]!=0)) { if (szUserInput[0]=='D' || szUserInput[0]=='d') { goto donewith; } } /* Otherwise, attempt to get answer number from user. */ nAnswer = atoi(szUserInput) - 1; if ((szUserInput[0]=='M' || szUserInput[0]=='m') && bAllowUnvote==TRUE) { if(colorsch==COLOR_DEF) od_printf("`bright green`Clear your answer to this question and set it as unanswered? [Y] or [N] `green`"); else od_printf("`bright black`Clear your answer to this question and set it as unanswered`white`? [`bright black`Y`white`] `bright black`or `white`[`bright black`N`white`] `bright`"); if(od_get_answer("YN")=='Y') { od_printf("Yes\n\r\n"); nAnswer=SET_UN_ANSWERED; break; } else { od_printf("No\n\r\n"); } } else if((QuestionRecord.bitflags & MULTIPLE_ANSWERS) && (CurrentUserRecord.bVotedOnQuestion[nQuestion]==0 || CurrentUserRecord.bVotedOnQuestion[nQuestion]==answers[15]) && (szUserInput[0]=='D' || szUserInput[0]=='d')) { /* if(answers[nAnswer]==CurrentUserRecord.bVotedOnQuestion[nQuestion] || CurrentUserRecord.bVotedOnQuestion[nQuestion]==answers[15]+answers[nAnswer]) {*/ if(colorsch!=COLOR_DEF) od_printf("`bright black`"); od_printf("You need to have at least one answer checked"); if(colorsch!=COLOR_DEF) od_printf("`white`"); od_printf("!\n\r\n"); WaitForEnter(); /* If user input is not a valid answer. */ } else if(nAnswer < 0 || nAnswer >= QuestionRecord.nTotalAnswers) { /* Display message. */ if(colorsch!=COLOR_DEF) od_printf("`bright black`"); od_printf("That is not a valid response"); if(colorsch!=COLOR_DEF) od_printf("`white`"); od_printf(".\n\r\n"); WaitForEnter(); } else { /* Otherwise, exit loop. */ break; } } /* Add user's vote to question. */ /* If user entered their own answer, try to add it to the question. */ if(nAnswer == NEW_ANSWER) { /* Check that there is still room for another answer. */ if(QuestionRecord.bitflags & BF_15_BY_1_MODE) cnt=MAX_ANSWERS; else cnt=MAX_ANSWERS2; if((fpFile=QRead(&QuestionRecord,nQuestion))==NULL) return; if(QuestionRecord.nTotalAnswers >= cnt) { fclose(fpFile); if(colorsch!=COLOR_DEF) od_printf("`bright black`"); od_printf("Sorry, this question already has the maximum number of answers"); if(colorsch!=COLOR_DEF) od_printf("`white`"); od_printf(".\n\r"); WaitForEnter(); goto moreanswers; } /* Set answer number to number of new answer. */ nAnswer = QuestionRecord.nTotalAnswers; /* Add 1 to total number of answers. */ ++QuestionRecord.nTotalAnswers; /* Initialize new answer string and count. */ if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { strcpy(QuestionRecord.aszAnswer[nAnswer], szNewAnswer); } else { strcpy(QuestionRecord.aszAnswer[nAnswer*2], szNewAnswer); strcpy(QuestionRecord.aszAnswer[(nAnswer*2)+1], szNewAnswer2); } QuestionRecord.auVotesForAnswer[nAnswer] = 0; if(!QWrite(&QuestionRecord,fpFile,nQuestion)) return; CurrentUserRecord.bVotedOnQuestion[nQuestion] |= answers[15]; } if(nAnswer == SET_UN_ANSWERED) { /* for(cnt=0;cnt<QuestionRecord.nTotalAnswers;cnt++) { if(CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[cnt]) { --QuestionRecord.auVotesForAnswer[cnt]; CurrentUserRecord.bVotedOnQuestion[nQuestion] &=~ answers[cnt]; } }*/ if(CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[15]) { CurrentUserRecord.bVotedOnQuestion[nQuestion] = 0; CurrentUserRecord.bVotedOnQuestion[nQuestion] |= answers[15]; } else { CurrentUserRecord.bVotedOnQuestion[nQuestion] = 0; } decvotes=TRUE; // --QuestionRecord.uTotalVotes; goto donewith; }// else { if(QuestionRecord.bitflags & MULTIPLE_ANSWERS) { /* Record that user has voted on this question. */ if(CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[nAnswer]) CurrentUserRecord.bVotedOnQuestion[nQuestion] &=~ answers[nAnswer]; else CurrentUserRecord.bVotedOnQuestion[nQuestion] |= answers[nAnswer]; } else { if(CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[15]) { CurrentUserRecord.bVotedOnQuestion[nQuestion] = answers[nAnswer]; CurrentUserRecord.bVotedOnQuestion[nQuestion] |= answers[15]; } else { CurrentUserRecord.bVotedOnQuestion[nQuestion] = answers[nAnswer]; } } /*if(QuestionRecord.bitflags & MULTIPLE_ANSWERS) {*/ /* Add user's vote to question. */ /* if(CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[nAnswer]) { --QuestionRecord.auVotesForAnswer[nAnswer]; CurrentUserRecord.bVotedOnQuestion[nQuestion] &=~ answers[nAnswer]; } else { CurrentUserRecord.bVotedOnQuestion[nQuestion] |= answers[nAnswer]; ++QuestionRecord.auVotesForAnswer[nAnswer]; } } else { if(!(CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[nAnswer])) { for(cnt=0;cnt<QuestionRecord.nTotalAnswers;cnt++) { if(CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[cnt]) { --QuestionRecord.auVotesForAnswer[cnt]; CurrentUserRecord.bVotedOnQuestion[nQuestion] &=~ answers[cnt]; break; } } ++QuestionRecord.auVotesForAnswer[nAnswer]; CurrentUserRecord.bVotedOnQuestion[nQuestion] |= answers[nAnswer]; } }*/ // } if((QuestionRecord.bitflags & MULTIPLE_ANSWERS) && nAnswer != SET_UN_ANSWERED) goto moreanswers; donewith: if((fpFile=QRead(&QuestionRecord,nQuestion))==NULL) return; if(decvotes==TRUE) { --QuestionRecord.uTotalVotes; decvotes=3; } for(x=0;x<15;x++) { if((CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[x]) && ((original_answers & answers[x])==FALSE)) ++QuestionRecord.auVotesForAnswer[x]; else if(((CurrentUserRecord.bVotedOnQuestion[nQuestion] & answers[x])==FALSE) && (original_answers & answers[x])) --QuestionRecord.auVotesForAnswer[x]; } if(!QWrite(&QuestionRecord,fpFile,nQuestion)) return; WriteCurrentUser(); if(decvotes!=3) /* Display the result of voting on this question to the user. */ DisplayQuestionResult(&QuestionRecord,FALSE); decvotes=FALSE; /* Add 1 to count of questions that the user has voted on. */ nQuestionsVotedOn++; } } /* The ViewResults function is called when the user chooses the "view */ /* results" command from the main menu. This function alows the user to */ /* choose a question from the list of questions, and then displays the */ /* results of voting on that question. */ void ViewResults(int all) { int nChoice=-1; tQuestionRecord QuestionRecord; int nPageLocation = 0; /* Loop until user chooses to return to main menu. */ for(;;) { /* Allow the user to choose a question from the list of questions that */ /* they have already voted on. */ if (all==FALSE) { if(view_own_results==FALSE) { nChoice = ChooseQuestion(nViewResultsFrom, " View Results\n\r", &nPageLocation); } else { nChoice = ChooseQuestion(nViewResultsFrom | CURRENT_USER_ONLY, " View Results\n\r", &nPageLocation); } } else { if(view_own_results==FALSE) { nChoice = FirstQuestion(nViewResultsFrom,nChoice+1); } else { nChoice = FirstQuestion(nViewResultsFrom | CURRENT_USER_ONLY,nChoice+1); } } /* If the user did not choose a question, return to main menu. */ if(nChoice == NO_QUESTION) { return; } /* Read the specified question number from the question file. */ if(!GetQuestion(nChoice, &QuestionRecord)) { return; } /* Display the results for the selected question. */ if (DisplayQuestionResult(&QuestionRecord,all)==FALSE) return; } } /* The GetQuestion function read the record for the specified question */ /* number from the question file. */ int GetQuestion(int nQuestion, tQuestionRecord *pQuestionRecord) { FILE *fpQuestionFile; if((fpQuestionFile=QRead(pQuestionRecord,nQuestion))==NULL) return(FALSE); /* Close the question file to allow access by other nodes. */ fclose(fpQuestionFile); /* Return with success. */ return(TRUE); } /* The AddQuestion() function is called when the user chooses the "add */ /* question" option from the main menu. This function allows the user */ /* to enter a new question, possible responses, and save the question for */ /* other users to vote on. */ void AddQuestion(void) { tQuestionRecord QuestionRecord; FILE *fpQuestionFile; char szLogMessage[100]; int cnt,cnt2; QuestionRecord.bitflags=0; /* Clear the screen. */ // od_printf("\n\n\r"); my_clr_scr(); /* Display screen header. */ if(colorsch==COLOR_DEF) od_printf("`bright red`"); else od_printf("`bright`"); od_printf(" Add A Question\n\r"); if(colorsch==COLOR_DEF) od_printf("`red`"); else od_printf("`bright black`"); if(od_control.user_ansi || od_control.user_avatar) { od_repeat((unsigned char)196, 79); } else { od_repeat('-', 79); } od_printf("\n\r\n\r"); if(multiple_answers==TRUE) { if(colorsch==COLOR_DEF) { od_printf("`bright green`Can people choose more than one answer? If not they will be allowed to only\r\n"); od_printf("choose one of the answers. (Y/N)`green`"); } else { od_printf("`bright black`Can people choose more than one answer`white`? `bright black`If not they will be allowed to only\r\n"); od_printf("choose one of the answers`white`. (`bright black`Y`white`/`bright black`N`white`)"); } if(od_get_answer("YN")=='Y'){ od_printf(" Yes\n\r\n\r"); QuestionRecord.bitflags |= MULTIPLE_ANSWERS; } else { od_printf(" No\n\r\n\r"); QuestionRecord.bitflags &=~ MULTIPLE_ANSWERS; } } if(colorsch==COLOR_DEF) { od_printf("`bright green`Should the answers to the question be:\n\r"); od_printf(" 1) 15 answers, 1 line per answer or,\n\r"); od_printf(" 2) 7 answers, 2 lines per answer\n\r"); od_printf("Well:`green`"); } else { od_printf("`bright black`Should the answers to the question be`white`:\n\r"); od_printf(" `bright`1`white`) `bright`15 `bright black`answers`white`, `bright`1 `bright black`line per answer or`white`,\n\r"); od_printf(" `bright`2`white`) `bright`7 `bright black`answers`white`, `bright`2 `bright black`lines per answer\n\r"); od_printf("`bright black`Well`white`:"); } if(od_get_answer("12")=='1'){ od_printf(" 15 by 1\n\r\n\r"); QuestionRecord.bitflags |= BF_15_BY_1_MODE; } else { od_printf(" 7 by 2\n\r\n\r"); QuestionRecord.bitflags &=~ BF_15_BY_1_MODE; } if(anonymous_posting==TRUE) { if(colorsch==COLOR_DEF) od_printf("`bright green`Do You want to post the question as Anonymous? (Y/N)`green`"); else od_printf("`bright black`Do You want to post the question as Anonymous`white`? (`bright black`Y`white`/`bright black`N`white`)"); if(od_get_answer("YN")=='Y'){ od_printf(" Yes\n\r\n\r"); QuestionRecord.bitflags |= ANONYMOUS_QUESTION; } else { od_printf(" No\n\r\n\r"); QuestionRecord.bitflags &=~ ANONYMOUS_QUESTION; } } if(sysop_sec<=od_control.user_security || strcmp(od_control.sysop_name, od_control.user_name) == 0) { if(colorsch==COLOR_DEF) od_printf("`bright green`Do you want your question to never be deleted (by timed deletion)? (Y/N)`green`"); else od_printf("`bright black`Do you want your question to never be deleted `white`(`bright black`by timed deletion`white`)? (`bright black`Y`white`/`bright black`N`white`)"); if(od_get_answer("YN")=='Y'){ od_printf(" Yes\n\r\n\r"); QuestionRecord.bitflags |= NEVER_DELETE_QUESTION; } else { od_printf(" No\n\r\n\r"); QuestionRecord.bitflags &=~ NEVER_DELETE_QUESTION; } if(colorsch==COLOR_DEF) { od_printf("`bright green`Do you want your question to be forced? So that everybody who enters the door\n\r"); od_printf("will have to vote on it? (Y/N)`green`"); } else { od_printf("`bright black`Do you want your question to be forced`white`? `bright black`So that everybody who enters the door\n\r"); od_printf("will have to vote on it`white`? (`bright black`Y`white`/`bright black`N`white`)"); } if(od_get_answer("YN")=='Y'){ od_printf(" Yes\n\r\n\r"); QuestionRecord.bitflags |= FORCED_QUESTION; } else { od_printf(" No\n\r\n\r"); QuestionRecord.bitflags &=~ FORCED_QUESTION; } } /* Clear the screen. */ // od_printf("\n\n\r"); my_clr_scr(); /* Display screen header. */ if(colorsch==COLOR_DEF) od_printf("`bright red`"); else od_printf("`bright`"); od_printf(" Add A Question\n\r"); if(colorsch==COLOR_DEF) od_printf("`red`"); else od_printf("`bright black`"); if(od_control.user_ansi || od_control.user_avatar) { od_repeat((unsigned char)196, 79); } else { od_repeat('-', 79); } od_printf("\n\r\n\r"); /* Obtain quesiton text from the user. */ if(colorsch==COLOR_DEF) { od_printf("`bright green`Enter Your Question (blank line cancels)\n\r"); od_printf("`green`[----------------------------------------------------------------------]\n\r "); } else { od_printf("`bright black`Enter Your Question `white`(`bright black`blank line cancels`white`)\n\r"); od_printf("[----------------------------------------------------------------------]\n\r "); } od_input_str(QuestionRecord.szQuestion, QUESTION_STR_SIZE - 1, ' ', 255); /* If question was empty, then return to main menu. */ if(strlen(QuestionRecord.szQuestion) == 0) { return; } /* Display prompt for answers. */ if(colorsch==COLOR_DEF) { od_printf("\n\r`bright green`Enter Possible Answers (blank line when done)\n\r"); od_printf("`green` [------------------------------]\n\r"); } else { od_printf("\n\r`bright black`Enter Possible Answers `white`(`bright black`blank line when done`white`)\n\r"); od_printf(" [------------------------------]\n\r"); } /* Loop, getting answers from user. */ if(QuestionRecord.bitflags & BF_15_BY_1_MODE) cnt2=MAX_ANSWERS; else cnt2=MAX_ANSWERS2; for(QuestionRecord.nTotalAnswers = cnt = 0; QuestionRecord.nTotalAnswers < cnt2; QuestionRecord.nTotalAnswers++) { askansweragain: /* Display prompt with answer number. */ if(colorsch==COLOR_DEF) od_printf("`bright green`%2d: `green`", QuestionRecord.nTotalAnswers + 1); else od_printf("`bright`%2d`white`: `white`", QuestionRecord.nTotalAnswers + 1); if(QuestionRecord.bitflags & BF_15_BY_1_MODE) { /* Get string from user. */ od_input_str(QuestionRecord.aszAnswer[cnt], ANSWER_STR_SIZE - 1, ' ', 255); } else { if(colorsch==COLOR_DEF) warp_line(QuestionRecord.aszAnswer[cnt],QuestionRecord.aszAnswer[cnt+1],"`bright green` : `green`"); else warp_line(QuestionRecord.aszAnswer[cnt],QuestionRecord.aszAnswer[cnt+1],"`white` : "); } /* if(!(QuestionRecord.bitflags & BF_15_BY_1_MODE) && strlen(QuestionRecord.aszAnswer[cnt])>0) { od_printf("`bright green` : `green`");*/ /* Get string from user. */ /* od_input_str(QuestionRecord.aszAnswer[cnt+1], ANSWER_STR_SIZE - 1, ' ', 255); } */ /* If string was empty, but only one answer added then */ if(strlen(QuestionRecord.aszAnswer[cnt]) == 0 && QuestionRecord.nTotalAnswers <2) { if(colorsch==COLOR_DEF) { od_printf("\n\r`bright red`Question has to have at least 2 answers!\n\r"); od_printf("`green` [------------------------------]\n\r"); } else { od_printf("\n\r`bright black`Question has to have at least `bright`2 `bright black`answers`white`!\n\r"); od_printf(" [------------------------------]\n\r"); } goto askansweragain; } /* If string was empty, then exit loop. */ if(strlen(QuestionRecord.aszAnswer[cnt]) == 0) { break; } /* Reset count of votes for this answer to zero. */ QuestionRecord.auVotesForAnswer[QuestionRecord.nTotalAnswers] = 0; if(!(QuestionRecord.bitflags & BF_15_BY_1_MODE)) cnt+=2; else cnt++; } /* If no answers were supplied, then cancel, returning to main menu. */ /* if(QuestionRecord.nTotalAnswers == 0) { return; }*/ QuestionRecord.bitflags &=~ CAN_ADD_ANSWERS; QuestionRecord.bitflags &=~ MULTIPLE_ADDS_P_U; if(answer_adding==1 && QuestionRecord.nTotalAnswers < cnt2) { /* Ask whether users should be able to add their own answers. */ if(colorsch==COLOR_DEF) od_printf("\n\r`bright green`Should voters be able to add their own options? (Y/N) `green`"); else od_printf("\n\r`bright black`Should voters be able to add their own options`white`? (`bright black`Y`white`/`bright black`N`white`) "); /* Get answer from user. */ if(od_get_answer("YN") == 'Y') { /* If user pressed the 'Y' key. */ od_printf("Yes\n\r"); /* Record user's response. */ QuestionRecord.bitflags |= CAN_ADD_ANSWERS; if((sysop_sec<=od_control.user_security || strcmp(od_control.sysop_name, od_control.user_name) == 0) || more_adds_p_u==TRUE) { if(colorsch==COLOR_DEF) od_printf("\n\r`bright green`Should one voter be able to add more than one answer? (Y/N) `green`"); else od_printf("\n\r`bright black`Should one voter be able to add more than one answer`white`? (`bright black`Y`white`/`bright black`N`white`) "); if(od_get_answer("YN") == 'Y') { /* If user pressed the 'Y' key. */ od_printf("Yes\n\r"); /* Record user's response. */ QuestionRecord.bitflags |= MULTIPLE_ADDS_P_U; } else { /* If user pressed the 'N' key. */ od_printf("No\n\r"); /* Record user's response. */ QuestionRecord.bitflags &=~ MULTIPLE_ADDS_P_U; } } else { QuestionRecord.bitflags &=~ MULTIPLE_ADDS_P_U; } } else { /* If user pressed the 'N' key. */ od_printf("No\n\r"); /* Record user's response. */ QuestionRecord.bitflags &=~ CAN_ADD_ANSWERS; QuestionRecord.bitflags &=~ MULTIPLE_ADDS_P_U; } } else { QuestionRecord.bitflags &=~ CAN_ADD_ANSWERS; QuestionRecord.bitflags &=~ MULTIPLE_ADDS_P_U; } if(answer_adding==2 && QuestionRecord.nTotalAnswers < cnt2) QuestionRecord.bitflags |= CAN_ADD_ANSWERS; if(more_adds_p_u==2) QuestionRecord.bitflags |= MULTIPLE_ADDS_P_U; /* Confirm save of new question. */ if(colorsch==COLOR_DEF) od_printf("\n\r`bright green`Do you wish to save this new question? (Y/N) `green`"); else od_printf("\n\r`bright black`Do you wish to save this new question`white`? (`bright black`Y`white`/`bright black`N`white`) "); /* If user does not want to save the question, return to main menu now. */ if(od_get_answer("YN") == 'N') { return; } /* Set total number of votes for this question to 0. */ QuestionRecord.uTotalVotes = 0; /* Set creator name and creation time for this question. */ strcpy(QuestionRecord.szCreatorName, sz_user_name); QuestionRecord.lCreationTime = time(NULL); QuestionRecord.bitflags &=~ QUESTION_DELETED; /* Open question file for exclusive access by this node. */ fpQuestionFile = ExculsiveFileOpen(QUESTION_FILENAME, "a+b"); if(fpQuestionFile == NULL) { od_printf("Unable to access the question file.\n\r"); WaitForEnter(); return; } /* Determine number of records in question file. */ fseek(fpQuestionFile, 0, SEEK_END); /* If question file is full, display message and return to main menu */ /* after closing file. */ if(ftell(fpQuestionFile) / QUESTIONRECORD_SIZE >= MAX_QUESTIONS) { fclose(fpQuestionFile); od_printf("`bright`Cannot add another question, FrEevOtE is limited to %d questions.\n\r", MAX_QUESTIONS); WaitForEnter(); return; } /* Add new question to file. */ if(fwriteQuestionRecord(&QuestionRecord, fpQuestionFile) != 1) { fclose(fpQuestionFile); od_printf("Unable to write to question file.\n\r"); WaitForEnter(); return; } /* Close question file, allowing other nodes to access file. */ fclose(fpQuestionFile); /* Record in the logfile that user has added a new question. */ sprintf(szLogMessage, "User adding questions: %s", QuestionRecord.szQuestion); od_log_write(szLogMessage); } /* The DeleteQuestion() function is called when the sysop chooses the */ /* "delete question" option from the main menu. This function displays */ /* a list of all questions, allowing the sysop to choose a question for */ /* deletion. */ void DeleteQuestion(void) { int nQuestion; tQuestionRecord QuestionRecord; FILE *fpFile; int nPageLocation = 0; deletemore: /* Check that user is system operator. */ if(sysop_sec>od_control.user_security && strcmp(od_control.user_name, od_control.sysop_name) != 0) { if(bAllowDelete==TRUE) { DeleteYourQuestion(); } return; } /* Allow the user to choose a question from the list of all questions. */ nQuestion = ChooseQuestion(QUESTIONS_NOT_VOTED_ON | QUESTIONS_VOTED_ON, " Delete A Question\n\r", &nPageLocation); /* If the user did not choose a question, return to main menu. */ if(nQuestion == NO_QUESTION) { return; } /* Read the question chosen by the user. */ if(!GetQuestion(nQuestion, &QuestionRecord)) { /* If unable to access file, return to main menu. */ return; } /* Confirm deletion of this question. */ if(colorsch==COLOR_DEF) { od_printf("\n\r\n`bright green`Are you sure you want to delete the question:\n\r `green`%s\n\r", QuestionRecord.szQuestion); od_printf("`bright green`[Y]es or [N]o? `green`"); } else { od_printf("\n\r\n`bright black`Are you sure you want to delete the question`white`:\n\r `bright`%s\n\r", QuestionRecord.szQuestion); od_printf("`white`[`bright black`Y`white`]`bright black`es or `white`[`bright black`N`white`]`bright black`o`white`? "); } /* If user canceled deletion, return now. */ if(od_get_answer("YN") == 'N') { goto deletemore; } od_printf("Y\n\r"); /* if(((int)((nQuestion+1)/QUESTION_PAGE_SIZE)*QUESTION_PAGE_SIZE)==(nQuestion+1)) nPageLocation-=QUESTION_PAGE_SIZE;*/ /* Mark the question as being deleted. */ QuestionRecord.bitflags |= QUESTION_DELETED; /* Open question file for exclusive access by this node. */ fpFile = ExculsiveFileOpen(QUESTION_FILENAME, "r+b"); if(fpFile == NULL) { /* If unable to access file, display error and return. */ od_printf("\n\n\rUnable to access the question file.\n\n\r"); WaitForEnter(); return; } /* Write the question record back to the file. */ fseek(fpFile, (long)nQuestion * QUESTIONRECORD_SIZE, SEEK_SET); if(fwriteQuestionRecord(&QuestionRecord, fpFile) != 1) { /* If unable to access file, display error and return. */ fclose(fpFile); od_printf("\n\rUnable to write question to file.\n\r"); WaitForEnter(); return; } /* Close the question file to allow access by other nodes. */ fclose(fpFile); goto deletemore; } void DeleteYourQuestion(void) { int nQuestion; tQuestionRecord QuestionRecord; FILE *fpFile; int nPageLocation = 0; deletemore: /* Allow the user to choose a question from the list of all questions. */ nQuestion = ChooseQuestion(CURRENT_USER_ONLY, " Delete A Question\n\r", &nPageLocation); /* If the user did not choose a question, return to main menu. */ if(nQuestion == NO_QUESTION) { return; } /* Read the question chosen by the user. */ if(!GetQuestion(nQuestion, &QuestionRecord)) { /* If unable to access file, return to main menu. */ return; } /* Confirm deletion of this question. */ if(colorsch==COLOR_DEF) { od_printf("\n\r\n`bright green`Are you sure you want to delete the question:\n\r `green`%s\n\r", QuestionRecord.szQuestion); od_printf("`bright green`[Y]es or [N]o? `green`"); } else { od_printf("\n\r\n`bright black`Are you sure you want to delete the question`white`:\n\r `bright`%s\n\r", QuestionRecord.szQuestion); od_printf("`white`[`bright black`Y`white`]`bright black`es or `white`[`bright black`N`white`]`bright black`o`white`? "); } /* If user canceled deletion, return now. */ if(od_get_answer("YN") == 'N') { goto deletemore; } od_printf("Yes\n\r"); /* if(((int)((nQuestion+1)/QUESTION_PAGE_SIZE)*QUESTION_PAGE_SIZE)==(nQuestion+1)) nPageLocation-=QUESTION_PAGE_SIZE;*/ /* Mark the question as being deleted. */ QuestionRecord.bitflags |= QUESTION_DELETED; /* Open question file for exclusive access by this node. */ fpFile = ExculsiveFileOpen(QUESTION_FILENAME, "r+b"); if(fpFile == NULL) { /* If unable to access file, display error and return. */ od_printf("\n\n\rUnable to access the question file.\n\n\r"); WaitForEnter(); return; } /* Write the question record back to the file. */ fseek(fpFile, (long)nQuestion * QUESTIONRECORD_SIZE, SEEK_SET); if(fwriteQuestionRecord(&QuestionRecord, fpFile) != 1) { /* If unable to access file, display error and return. */ fclose(fpFile); od_printf("\n\rUnable to write question to file.\n\r"); WaitForEnter(); return; } /* Close the question file to allow access by other nodes. */ fclose(fpFile); goto deletemore; } int CountQuestions() { int QuestionCount,nFileQuestion; unsigned int bVotedOnQuestion; tQuestionRecord QuestionRecord; FILE *fpQuestionFile; /* Attempt to open question file. */ fpQuestionFile = ExculsiveFileOpen(QUESTION_FILENAME, "r+b"); /* If unable to open question file, assume that no questions have been */ /* created. */ if(fpQuestionFile == NULL) { /* Display "no questions yet" message. */ if(colorsch==COLOR_DEF) od_printf("\n\r`bright cyan`No questions have been created so far.\n\r"); else od_printf("\n\r`bright black`No questions have been created so far`white`.\n\r"); return(0); } QuestionCount=0; nFileQuestion=0; /* Loop for every question record in the file. */ while(freadQuestionRecord(&QuestionRecord, fpQuestionFile) == 1) { /* Determine whether or not the user has voted on this question. */ bVotedOnQuestion = CurrentUserRecord.bVotedOnQuestion[nFileQuestion]; /* If this is the kind of question that the user is choosing from */ /* right now. */ if(bVotedOnQuestion==answers[15] || bVotedOnQuestion==0) { /* If question is not deleted. */ if(!(QuestionRecord.bitflags & QUESTION_DELETED)) { QuestionCount++; } } nFileQuestion++; } /* Close question file to allow other nodes to access the file. */ fclose(fpQuestionFile); if(colorsch==COLOR_DEF) { if(QuestionCount==1) od_printf("\n\r`bright cyan`There is 1 new question!\n\r"); else if(QuestionCount>1) od_printf("\n\r`bright cyan`There are %d new questions!\n\r",QuestionCount); else od_printf("\n\r`bright cyan`There are no new questions!\n\r",QuestionCount); } else { if(QuestionCount==1) od_printf("\n\r`bright black`There is `bright`1 `bright black`new question`white`!\n\r"); else if(QuestionCount>1) od_printf("\n\r`bright black`There are `bright`%d `bright black`new questions`white`!\n\r",QuestionCount); else od_printf("\n\r`bright black`There are no new questions`white`!\n\r",QuestionCount); } return(QuestionCount); } int CountQuestionsF() { int QuestionCount,nFileQuestion; unsigned int bVotedOnQuestion; tQuestionRecord QuestionRecord; FILE *fpQuestionFile; /* Attempt to open question file. */ fpQuestionFile = ExculsiveFileOpen(QUESTION_FILENAME, "r+b"); /* If unable to open question file, assume that no questions have been */ /* created. */ if(fpQuestionFile == NULL) { /* Display "no questions yet" message. */ // od_printf("\n\r`bright cyan`No questions have been created so far.\n\r"); return(0); } QuestionCount=0; nFileQuestion=0; /* Loop for every question record in the file. */ while(freadQuestionRecord(&QuestionRecord, fpQuestionFile) == 1) { /* Determine whether or not the user has voted on this question. */ bVotedOnQuestion = CurrentUserRecord.bVotedOnQuestion[nFileQuestion]; /* If this is the kind of question that the user is choosing from */ /* right now. */ if(bVotedOnQuestion==answers[15] || bVotedOnQuestion==0) { /* If question is not deleted. */ if(!(QuestionRecord.bitflags & QUESTION_DELETED) && (QuestionRecord.bitflags & FORCED_QUESTION)) { QuestionCount++; } } nFileQuestion++; } /* Close question file to allow other nodes to access the file. */ fclose(fpQuestionFile); /* if(QuestionCount==1) od_printf("\n\r`bright cyan`There is 1 new question!\n\r"); else if(QuestionCount>1) od_printf("\n\r`bright cyan`There are %d new questions!\n\r",QuestionCount); else od_printf("\n\r`bright cyan`There are no new questions!\n\r",QuestionCount);*/ return(QuestionCount); } /* The ChooseQuestion() function provides a list of questions and allows */ /* the user to choose a particular question, cancel back to the main menu, */ /* and page up and down in the list of questions. Depending upon the value */ /* of the nFromWhichQuestions parameter, this function will present a list */ /* of questions that the user has voted on, a list of questions that the */ /* user has not voted on, or a list of all questions. */ int ChooseQuestion(unsigned int nFromWhichQuestions, char *pszTitle, int *nLocation) { int nCurrent; int nFileQuestion; int nPagedToQuestion = *nLocation; int nDisplayedQuestion; unsigned int bVotedOnQuestion; char chCurrent; tQuestionRecord QuestionRecord; FILE *fpQuestionFile; static char szQuestionName[MAX_QUESTIONS][QUESTION_STR_SIZE]; static int nQuestionNumber[MAX_QUESTIONS]; nFileQuestion = 0; nDisplayedQuestion = 0; /* Attempt to open question file. */ fpQuestionFile = ExculsiveFileOpen(QUESTION_FILENAME, "r+b"); /* If unable to open question file, assume that no questions have been */ /* created. */ if(fpQuestionFile == NULL) { /* Display "no questions yet" message. */ if(colorsch!=COLOR_DEF) od_printf("`bright black`"); od_printf("\n\rNo questions have been created so far"); if(colorsch!=COLOR_DEF) od_printf("`white`"); od_printf(".\n\n\r"); /* Wait for user to press enter. */ WaitForEnter(); /* Indicate that no question has been chosen. */ return(NO_QUESTION); } /* Loop for every question record in the file. */ while(freadQuestionRecord(&QuestionRecord, fpQuestionFile) == 1) { /* Determine whether or not the user has voted on this question. */ bVotedOnQuestion = CurrentUserRecord.bVotedOnQuestion[nFileQuestion]; /* If this is the kind of question that the user is choosing from */ /* right now. */ if(((bVotedOnQuestion!=answers[15] && bVotedOnQuestion!=0) && (nFromWhichQuestions & QUESTIONS_VOTED_ON)) || ((bVotedOnQuestion==answers[15] || bVotedOnQuestion==0) && (nFromWhichQuestions & QUESTIONS_NOT_VOTED_ON)) || (strcmp(sz_user_name,QuestionRecord.szCreatorName)==0 && (nFromWhichQuestions & CURRENT_USER_ONLY))) { /* If question is not deleted. */ if(!(QuestionRecord.bitflags & QUESTION_DELETED)) { /* Add this question to list to be displayed. */ strcpy(szQuestionName[nDisplayedQuestion], QuestionRecord.szQuestion); nQuestionNumber[nDisplayedQuestion] = nFileQuestion; /* Add one to number of questions to be displayed in list. */ nDisplayedQuestion++; } } /* Move to next question in file. */ ++nFileQuestion; } /* Close question file to allow other nodes to access the file. */ fclose(fpQuestionFile); /* If there are no questions for the user to choose, display an */ /* appropriate message and return. */ if(nDisplayedQuestion == 0) { /* If we were to list all questions. */ if((nFromWhichQuestions & QUESTIONS_VOTED_ON) && (nFromWhichQuestions & QUESTIONS_NOT_VOTED_ON)) { if(colorsch!=COLOR_DEF) od_printf("`bright black`"); od_printf("\n\rThere are no questions"); if(colorsch!=COLOR_DEF) od_printf("`white`"); od_printf(".\n\n\r"); } /* If we were to list questions that the user has voted on. */ else if(nFromWhichQuestions & QUESTIONS_VOTED_ON) { if(colorsch!=COLOR_DEF) od_printf("`bright black`"); od_printf("\n\rThere are no questions that you have voted on"); if(colorsch!=COLOR_DEF) od_printf("`white`"); od_printf(".\n\n\r"); } else if(nFromWhichQuestions & CURRENT_USER_ONLY) { if(colorsch!=COLOR_DEF) od_printf("`bright black`"); od_printf("\n\rYou have not created any questions"); if(colorsch!=COLOR_DEF) od_printf("`white`"); od_printf(".\n\n\r"); } /* Otherwise, we were to list questions that use has not voted on. */ else { if(colorsch!=COLOR_DEF) od_printf("`bright black`"); od_printf("\n\rYou have voted on all the questions"); if(colorsch!=COLOR_DEF) od_printf("`white`"); od_printf(".\n\n\r"); } /* Wait for user to press enter key. */ WaitForEnter(); /* Return, indicating that no question was chosen. */ return(NO_QUESTION); } /* Ensure that initial paged to location is within range. */ while(nPagedToQuestion >= nDisplayedQuestion) { nPagedToQuestion -= QUESTION_PAGE_SIZE; } /* Loop, displaying current page of questions, until the user makes a */ /* choice. */ for(;;) { /* Clear the screen. */ // od_printf("\n\n\r"); my_clr_scr(); /* Display header. */ if(colorsch==COLOR_DEF) od_printf("`bright red`"); else od_printf("`bright`"); od_printf(pszTitle); if(colorsch==COLOR_DEF) od_printf("`red`"); else od_printf("`white`"); if(od_control.user_ansi || od_control.user_avatar) { od_repeat((unsigned char)196, 79); } else { od_repeat('-', 79); } od_printf("\n\r"); /* Display list of questions on this page. */ for(nCurrent = 0; nCurrent < QUESTION_PAGE_SIZE && nCurrent < (nDisplayedQuestion - nPagedToQuestion); ++nCurrent) { /* Determine character to display for current line. */ if(nCurrent < 9) { chCurrent = (char)('1' + nCurrent); } else { chCurrent = (char)('A' + (nCurrent - 9)); } /* Display this question's title. */ if(colorsch==COLOR_DEF) od_printf("`bright green`"); else od_printf("`bright`"); od_printf("%c.", chCurrent); if(colorsch==COLOR_DEF) od_printf("`green`"); else od_printf("`bright black`"); od_printf(" %s\n\r", szQuestionName[nCurrent + nPagedToQuestion]); } /* Display prompt for input. */ if(colorsch==COLOR_DEF) od_printf("\n\r`bright`[Page %d] Choose a question or", (nPagedToQuestion / QUESTION_PAGE_SIZE) + 1); else od_printf("\n\r`white`[`bright black`Page `bright`%d`white`] `bright black`Choose a question or", (nPagedToQuestion / QUESTION_PAGE_SIZE) + 1); if(nPagedToQuestion < nDisplayedQuestion - QUESTION_PAGE_SIZE) { if(colorsch==COLOR_DEF) od_printf(" [N]ext page,"); else od_printf(" `white`[`bright black`N`white`]`bright black`ext page`white`,"); } if(nPagedToQuestion > 0) { if(colorsch==COLOR_DEF) od_printf(" [P]revious page,"); else od_printf(" `white`[`bright black`P`white`]`bright black`revious page`white`,"); } if(colorsch==COLOR_DEF) od_printf(" [Q]uit:"); else od_printf(" `white`[`bright black`Q`white`]`bright black`uit`white`:"); /* Loop until the user makes a valid choice. */ for(;;) { /* Get input from user */ chCurrent = (char)od_get_key(TRUE); chCurrent = (char)toupper(chCurrent); /* Respond to user's input. */ /* If user pressed Q key. */ if(chCurrent == 'Q') { /* Return without a choosing a question. */ return(NO_QUESTION); } /* If user pressed P key. */ else if(chCurrent == 'P') { /* If we are not at the first page. */ if(nPagedToQuestion > 0) { /* Move paged to location up one page. */ nPagedToQuestion -= QUESTION_PAGE_SIZE; /* Exit user input loop to display next page. */ break; } } /* If user pressed N key. */ else if(chCurrent == 'N') { /* If there is more questions after this page. */ if(nPagedToQuestion < nDisplayedQuestion - QUESTION_PAGE_SIZE) { /* Move paged.to location down one page. */ nPagedToQuestion += QUESTION_PAGE_SIZE; /* Exit user input loop to display next page. */ break; } } /* Otherwise, check whether the user chose a valid question. */ else if ((chCurrent >= '1' && chCurrent <= '9') || (chCurrent >= 'A' && chCurrent <= 'H')) { /* Get question number from key pressed. */ if(chCurrent >= '1' && chCurrent <= '9') { nCurrent = chCurrent - '1'; } else { nCurrent = (chCurrent - 'A') + 9; } /* Add current paged to position to user's choice. */ nCurrent += nPagedToQuestion; /* If this is valid question number. */ if(nCurrent < nDisplayedQuestion) { /* Set caller's current question number. */ *nLocation = nPagedToQuestion; /* Return actual question number in file. */ return(nQuestionNumber[nCurrent]); } } } } } /* The ChooseQuestion() function provides a list of questions and allows */ /* the user to choose a particular question, cancel back to the main menu, */ /* and page up and down in the list of questions. Depending upon the value */ /* of the nFromWhichQuestions parameter, this function will present a list */ /* of questions that the user has voted on, a list of questions that the */ /* user has not voted on, or a list of all questions. */ int FirstQuestion(unsigned int nFromWhichQuestions, int nFileQuestion) { int nCurrent; // int nFileQuestion = 0; // int nPagedToQuestion = *nLocation; // int nDisplayedQuestion = 0; unsigned int bVotedOnQuestion; // char chCurrent; tQuestionRecord QuestionRecord; FILE *fpQuestionFile; // static char szQuestionName[MAX_QUESTIONS][QUESTION_STR_SIZE]; // static int nQuestionNumber[MAX_QUESTIONS]; /* Attempt to open question file. */ fpQuestionFile = ExculsiveFileOpen(QUESTION_FILENAME, "r+b"); /* If unable to open question file, assume that no questions have been */ /* created. */ if(fpQuestionFile == NULL) { /* Display "no questions yet" message. */ if(Forcevote!=4) { if(colorsch!=COLOR_DEF) od_printf("`bright black`"); od_printf("\n\rNo questions have been created so far"); if(colorsch!=COLOR_DEF) od_printf("`white`"); od_printf(".\n\n\r"); } /* Wait for user to press enter. */ if(Forcevote!=4) WaitForEnter(); /* Indicate that no question has been chosen. */ return(NO_QUESTION); } /* Loop for every question record in the file. */ fseek(fpQuestionFile,QUESTIONRECORD_SIZE*(long)nFileQuestion,SEEK_SET); while(freadQuestionRecord(&QuestionRecord, fpQuestionFile) == 1) { /* Determine whether or not the user has voted on this question. */ bVotedOnQuestion = CurrentUserRecord.bVotedOnQuestion[nFileQuestion]; /* If this is the kind of question that the user is choosing from */ /* right now. */ if(((bVotedOnQuestion!=answers[15] && bVotedOnQuestion!=0) && (nFromWhichQuestions & QUESTIONS_VOTED_ON)) || ((bVotedOnQuestion==answers[15] || bVotedOnQuestion==0) && (nFromWhichQuestions & QUESTIONS_NOT_VOTED_ON)) || (strcmp(sz_user_name,QuestionRecord.szCreatorName)==0 && (nFromWhichQuestions & CURRENT_USER_ONLY))) { /* If question is not deleted. */ if(!(QuestionRecord.bitflags & QUESTION_DELETED)) { if(nFromWhichQuestions & QUESTIONS_FORCED) { if(QuestionRecord.bitflags & FORCED_QUESTION) { fclose(fpQuestionFile); return(nFileQuestion); } } else { fclose(fpQuestionFile); return(nFileQuestion); } } } /* Move to next question in file. */ ++nFileQuestion; } /* Close question file to allow other nodes to access the file. */ fclose(fpQuestionFile); /* If we were to list all questions. */ if((nFromWhichQuestions & QUESTIONS_VOTED_ON) && (nFromWhichQuestions & QUESTIONS_NOT_VOTED_ON)) { if(Forcevote!=4) { if(colorsch!=COLOR_DEF) od_printf("`bright black`"); od_printf("\n\r\nThere are no more questions"); if(colorsch!=COLOR_DEF) od_printf("`white`"); od_printf(".\n\n\r"); } } /* If we were to list questions that the user has voted on. */ else if(nFromWhichQuestions & QUESTIONS_VOTED_ON) { if(colorsch!=COLOR_DEF) od_printf("`bright black`"); od_printf("\n\n\rThere are no more questions that you have voted on"); if(colorsch!=COLOR_DEF) od_printf("`white`"); od_printf(".\n\n\r"); } /* Otherwise, we were to list questions that use has not voted on. */ else { if(Forcevote!=4 && Forcevote<100) { if(colorsch!=COLOR_DEF) od_printf("`bright black`"); od_printf("\n\rYou have voted on all the questions"); if(colorsch!=COLOR_DEF) od_printf("`white`"); od_printf(".\n\n\r"); } } /* Wait for user to press enter key. */ if(Forcevote!=4 && Forcevote<100) WaitForEnter(); /* Return, indicating that no question was chosen. */ return(NO_QUESTION); } /* The DisplayQuestionResult() function is called to display the results */ /* of voting on a paricular question, and is passed the question record */ /* of the question. This function is called when the user selects a */ /* question using the "view results" option, and is also called after */ /* the user has voted on a question, to display the results of voting on */ /* that question. */ int DisplayQuestionResult(tQuestionRecord *pQuestionRecord,int all) { int nAnswer; int uPercent; int maxpercent=0; int cnt; /* Clear the screen. */ // od_printf("\n\n\r"); my_clr_scr(); /* Check that there have been votes on this question. */ if(pQuestionRecord->uTotalVotes == 0) { /* If there have been no votes for this question, display a message */ /* and return.*/ if(colorsch==COLOR_DEF) od_printf("`bright green`"); else od_printf("`bright`"); od_printf("%s",pQuestionRecord->szQuestion); if(colorsch==COLOR_DEF) od_printf("\n\n\r`green`Nobody has voted on this question yet.\n\n\r"); else od_printf("\n\n\r`bright black`Nobody has voted on this question yet`white`.\n\n\r"); WaitForEnter(); return(TRUE); } /* Display question itself. */ if(colorsch==COLOR_DEF) od_printf("`bright red`"); else od_printf("`bright`"); od_printf("%s\n\r", pQuestionRecord->szQuestion); if(sysop_sec<=od_control.user_security || strcmp(od_control.sysop_name, od_control.user_name) == 0) { if((pQuestionRecord->bitflags & ANONYMOUS_QUESTION)==FALSE) { /* Display author's name. */ if(colorsch==COLOR_DEF) od_printf("`red`Question created by %s on %s\n\r", pQuestionRecord->szCreatorName, ctime(&pQuestionRecord->lCreationTime)); else od_printf("`bright black`Question created by `white`%s`bright black` on `bright`%s\n\r", pQuestionRecord->szCreatorName, ctime(&pQuestionRecord->lCreationTime)); } else { if(colorsch==COLOR_DEF) od_printf("`red`Question created `bright`Anonymously`red` by %s on %s\n\r", pQuestionRecord->szCreatorName, ctime(&pQuestionRecord->lCreationTime)); else od_printf("`bright black`Question created `bright`Anonymously`bright black` by `white`%s on `bright`%s\n\r", pQuestionRecord->szCreatorName, ctime(&pQuestionRecord->lCreationTime)); } } else { if((pQuestionRecord->bitflags & ANONYMOUS_QUESTION)==FALSE) { /* Display author's name. */ if(colorsch==COLOR_DEF) od_printf("`red`Question created by %s on %s\n\r", pQuestionRecord->szCreatorName, ctime(&pQuestionRecord->lCreationTime)); else od_printf("`bright black`Question created by `white`%s`bright black` on `bright`%s\n\r", pQuestionRecord->szCreatorName, ctime(&pQuestionRecord->lCreationTime)); } else { if(colorsch==COLOR_DEF) od_printf("`red`Question created by Anonymous on %s\n\r", ctime(&pQuestionRecord->lCreationTime)); else od_printf("`bright black`Question created by `white`Anonymous`bright black` on `bright`%s\n\r", ctime(&pQuestionRecord->lCreationTime)); } } /* Display heading for responses. */ if(colorsch==COLOR_DEF) od_printf("`bright green`"); else od_printf("`bright black`"); od_printf("Response Votes Percent Graph\n\r"); if(colorsch==COLOR_DEF) od_printf("`green`"); else od_printf("`white`"); if(od_control.user_ansi || od_control.user_avatar) { od_repeat((unsigned char)196, 79); } else { od_repeat('-', 79); } od_printf("\n\r"); for(nAnswer = 0; nAnswer < pQuestionRecord->nTotalAnswers; ++nAnswer) { /* Determine percent of users who voted for this answer. */ uPercent = (pQuestionRecord->auVotesForAnswer[nAnswer] * 100) / pQuestionRecord->uTotalVotes; if(uPercent>maxpercent) maxpercent=uPercent; } /* Loop for each answer to the question. */ for(nAnswer = cnt = 0; nAnswer < pQuestionRecord->nTotalAnswers; ++nAnswer) { /* Determine percent of users who voted for this answer. */ uPercent = (pQuestionRecord->auVotesForAnswer[nAnswer] * 100) / pQuestionRecord->uTotalVotes; /* Display answer, total votes and percentage of votes. */ if(ColoredResults==FALSE) { if(colorsch==COLOR_DEF) od_printf("`green`"); else od_printf("`bright black`"); } else if(nAnswer == int(nAnswer/2)*2) od_printf("`bright yellow`"); else od_printf("`bright cyan`"); od_printf("%-30.30s %-5u %3u%% ", pQuestionRecord->aszAnswer[cnt], pQuestionRecord->auVotesForAnswer[nAnswer], uPercent); if(colorsch==COLOR_DEF) od_printf("`bright`"); else od_printf("`white`"); /* Display a bar graph corresponding to percent of users who voted */ /* for this answer. */ if(uPercent==maxpercent) { if(colorsch==COLOR_DEF) od_printf("`bright red`"); else od_printf("`bright`"); } if(od_control.user_ansi || od_control.user_avatar) { od_repeat((unsigned char)220, (unsigned char)((uPercent * 31) / maxpercent)); } else { od_repeat('=', (unsigned char)((uPercent * 31) / maxpercent)); } /* Move to next line. */ od_printf("\n\r"); if(!(pQuestionRecord->bitflags & BF_15_BY_1_MODE)) { /* Display answer, total votes and percentage of votes. */ if(ColoredResults==FALSE) { if(colorsch==COLOR_DEF) od_printf("`green`"); else od_printf("`bright black`"); } else if(nAnswer == int(nAnswer/2)*2) od_printf("`bright yellow`"); else od_printf("`bright cyan`"); od_printf("%-30.30s ", pQuestionRecord->aszAnswer[cnt+1]); if(colorsch==COLOR_DEF) od_printf("`bright`"); else od_printf("`white`"); /* Display a bar graph corresponding to percent of users who voted */ /* for this answer. */ if(uPercent==maxpercent) { if(colorsch==COLOR_DEF) od_printf("`bright red`"); else od_printf("`bright`"); } if(od_control.user_ansi || od_control.user_avatar) { od_repeat((unsigned char)223, (unsigned char)((uPercent * 31) / maxpercent)); } /* Move to next line. */ od_printf("\n\r"); cnt+=2; } else { cnt++; } } /* Display footer. */ if(colorsch==COLOR_DEF) od_printf("`green`"); else od_printf("`white`"); if(od_control.user_ansi || od_control.user_avatar) { od_repeat((unsigned char)196, 79); } else { od_repeat('-', 79); } od_printf("\n\r"); if(colorsch==COLOR_DEF) od_printf("`green` PEOPLE WHO VOTED: %u\n\r", pQuestionRecord->uTotalVotes); else od_printf("`bright black` PEOPLE WHO VOTED`white`: `bright`%u\n\r", pQuestionRecord->uTotalVotes); /* Wait for user to press enter. */ if (all==TRUE) { if(colorsch==COLOR_DEF) od_printf("`bright`Press [ENTER] to continue or [S] to stop :"); else od_printf("`bright black`Press `white`[`bright black`ENTER`white`] `bright black`to continue or `white`[`bright black`S`white`] `bright black`to stop `white`:"); if (od_get_answer("S\n\r")=='S') return(FALSE); } else { WaitForEnter(); } return(TRUE); } /* The ReadOrAddCurrentUser() function is used by EZVote to search the */ /* EZVote user file for the record containing information on the user who */ /* is currently using the door. If this is the first time that the user */ /* has used this door, then their record will not exist in the user file. */ /* In this case, this function will add a new record for the current */ /* user. This function returns TRUE on success, or FALSE on failure. */ int ReadOrAddCurrentUser(void) { FILE *fpUserFile; int bGotUser; int nQuestion; bGotUser = FALSE; /* Attempt to open the user file for exclusize access by this node. */ /* This function will wait up to the pre-set amount of time (as defined */ /* near the beginning of this file) for access to the user file. */ fpUserFile = ExculsiveFileOpen(USER_FILENAME, "rb"); /* If unable to open user file, return with failure. */ if(fpUserFile != NULL) { /* Begin with the current user record number set to 0. */ nCurrentUserNumber = 0; /* Loop for each record in the file */ // fseek(fpUserFile, (long)nCurrentUserNumber * USERRECORD_SIZE, SEEK_SET); while(freadUserRecord(&CurrentUserRecord, fpUserFile) == 1) { /* If name in record matches the current user name ... */ if(stricmp(CurrentUserRecord.szUserName, sz_user_name) == 0) { /* ... then record that we have found the user's record, */ bGotUser = TRUE; /* and exit the loop. */ break; } /* Move user record number to next user record. */ nCurrentUserNumber++; // fseek(fpUserFile, (long)nCurrentUserNumber * USERRECORD_SIZE, SEEK_SET); } fclose(fpUserFile); } else { nCurrentUserNumber=0; bGotUser=FALSE; } /* If the user was not found in the file, attempt to add them as a */ /* new user if the user file is not already full. */ if(!bGotUser && nCurrentUserNumber < MAX_USERS) { /* Place the user's name in the current user record. */ strcpy(CurrentUserRecord.szUserName, sz_user_name); /* Record that user hasn't voted on any of the questions. */ for(nQuestion = 0; nQuestion < MAX_QUESTIONS; ++nQuestion) { CurrentUserRecord.bVotedOnQuestion[nQuestion] = 0; } fpUserFile = ExculsiveFileOpen(USER_FILENAME, "a+b"); /* Write the new record to the file. */ if(fwriteUserRecord(&CurrentUserRecord, fpUserFile) == 1) { /* If write succeeded, record that we now have a valid user record. */ bGotUser = TRUE; } fclose(fpUserFile); } /* Close the user file to allow other nodes to access it. */ // fclose(fpUserFile); /* Return, indciating whether or not a valid user record now exists for */ /* the user that is currently online. */ return(bGotUser); } /* The WriteCurrentUser() function is called to save the information on the */ /* user who is currently using the door, to the EZVOTE.USR file. */ void WriteCurrentUser(void) { FILE *fpUserFile; /* Attempt to open the user file for exclusize access by this node. */ /* This function will wait up to the pre-set amount of time (as defined */ /* near the beginning of this file) for access to the user file. */ fpUserFile = ExculsiveFileOpen(USER_FILENAME, "r+b"); /* If unable to access the user file, display an error message and */ /* return. */ if(fpUserFile == NULL) { od_printf("Unable to access the user file.\n\r"); WaitForEnter(); return; } /* Move to appropriate location in user file for the current user's */ /* record. */ fseek(fpUserFile, (long)nCurrentUserNumber * USERRECORD_SIZE, SEEK_SET); /* Write the new record to the file. */ if(fwriteUserRecord(&CurrentUserRecord, fpUserFile) < 1) { /* If unable to write the record, display an error message. */ fclose(fpUserFile); od_printf("Unable to update your user record file.\n\r"); WaitForEnter(); return; } /* Close the user file to allow other nodes to access it again. */ fclose(fpUserFile); } #ifdef ODPLAT_NIX FILE *fsopen(char *pszFilename, char *pszMode, int shmode) { int file; int Mode=0; char pszNewMode[3]; char *p; for(p=pszMode;*p;p++) { switch (*p) { case 'r': Mode |= 1; break; case 'w': Mode |= 2; break; case 'a': Mode |= 4; break; case '+': Mode |= 8; break; case 'b': case 't': break; default: errno=EINVAL; return(NULL); } } switch(Mode) { case 1: Mode=O_RDONLY; break; case 2: Mode=O_WRONLY|O_CREAT; break; case 4: Mode=O_APPEND|O_WRONLY|O_CREAT; break; case 9: Mode=O_RDWR; break; case 10: Mode=O_RDWR|O_CREAT; break; case 12: Mode=O_RDWR|O_APPEND|O_CREAT; break; default: errno=EINVAL; return(NULL); } if(Mode&O_CREAT) file=sopen(pszFilename,Mode,shmode,S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); else file=sopen(pszFilename,Mode,shmode); if(file==-1) return(NULL); return(fdopen(file,pszMode)); } #endif /* This function opens the specified file in the specified mode for */ /* exculsive access by this node; while the file is open, other nodes will */ /* be unable to open the file. This function will wait for up to the number */ /* of seconds set by FILE_ACCESS_MAX_WAIT, which is defined near the */ /* beginning of this file. */ FILE *ExculsiveFileOpen(char *pszFileName, char *pszMode) { FILE *fpFile = NULL; time_t StartTime = time(NULL); /* Attempt to open the file while there is still time remaining. */ while((fpFile = fsopen(pszFileName, pszMode, SH_DENYRW)) == NULL && errno == EACCES && difftime(time(NULL), StartTime) < 60) { /* If we were unable to open the file, call od_kernal, so that */ /* OpenDoors can continue to respond to sysop function keys, loss */ /* of connection, etc. */ od_kernal(); } /* Return FILE pointer for opened file, if any. */ return(fpFile); } void warp_line(char line1[], char line2[],char intro[]) { int cnt,last_space=ANSWER_STR_SIZE-2; char key,warp=TRUE; /* od_printf(" ");*/ line1[ANSWER_STR_SIZE-1]=0; line2[ANSWER_STR_SIZE-1]=0; for(cnt=0;cnt<(ANSWER_STR_SIZE);cnt++) { key=od_get_key(TRUE); if((key==' ' || key=='-' || key==',' || key=='.' || key==':' || key==';' || key=='?' || key=='!') && cnt<(ANSWER_STR_SIZE-1)) last_space=cnt; if(key=='\n' || key=='\r') { line1[cnt]=0; warp=FALSE; break; } else if(key=='\b') { if(cnt>0) { od_printf("\b \b"); line1[cnt-1]=0; cnt-=2; } } else { od_putch(key); line1[cnt]=key; } } if(warp==TRUE) { for(cnt=last_space;cnt<(ANSWER_STR_SIZE-1);cnt++) od_putch('\b'); for(cnt=last_space;cnt<(ANSWER_STR_SIZE-1);cnt++) od_putch(' '); od_printf("\n\r"); od_printf(intro); for(cnt=last_space;cnt<(ANSWER_STR_SIZE-1);cnt++) { line2[cnt-last_space]=line1[1+cnt]; od_putch(line1[cnt+1]); } } else { last_space=ANSWER_STR_SIZE-1; od_printf("\n\r"); od_printf(intro); } line1[last_space+1]=0; /* printf("\n\n%s\n\n",line1);*/ if(line1[0]==0) return; cnt=ANSWER_STR_SIZE-last_space-1; /* printf("\r\n\n%d",cnt);*/ for(;;) { key=od_get_key(TRUE); if(key=='\n' || key=='\r') { line2[cnt]=0; break; } else if(key=='\b') { if(cnt>0) { od_printf("\b \b"); line2[cnt-1]=0; cnt-=2; } } else { od_putch(key); line2[cnt]=key; } if(cnt<(ANSWER_STR_SIZE-1)) cnt++; else od_printf("\b \b"); } line2[cnt]=0; /* printf("\n\n%s\n\n",line2);*/ od_printf("\n\r"); } /* The WaitForEnter() function is used by EZVote to create its custom */ /* "Press [ENTER] to continue." prompt. */ void WaitForEnter(void) { /* Display prompt. */ if(colorsch==COLOR_DEF) od_printf("`bright`Press [ENTER] to continue."); else od_printf("`bright black`Press `white`[`bright black`ENTER`white`]`bright black` to continue`white`.`bright black`"); /* Wait for a Carriage Return or Line Feed character from the user. */ od_get_answer("\n\r"); od_printf("\n\r"); }