void Board_load_board(int board_type) { FILE *fl; int i, len1 = 0, len2 = 0; char *tmp1 = NULL, *tmp2 = NULL; if (!(fl = fopen(FILENAME(board_type), "rb"))) { perror("Error reading board"); return; } fread(&(num_of_msgs[board_type]), sizeof(int), 1, fl); if (num_of_msgs[board_type] < 1 || num_of_msgs[board_type] > MAX_BOARD_MESSAGES) { stderr_log("SYSERR: Board file corrupt. Resetting."); Board_reset_board(board_type); return; } for (i = 0; i < num_of_msgs[board_type]; i++) { fread(&(msg_index[board_type][i]), sizeof(struct board_msginfo), 1, fl); if (!(len1 = msg_index[board_type][i].heading_len)) { stderr_log("SYSERR: Board file corrupt! Resetting."); Board_reset_board(board_type); return; } if (!(tmp1 = (char *) malloc(sizeof(char) * len1))) { stderr_log("SYSERR: Error - malloc failed for board header"); fflush(NULL); exit(1); } fread(tmp1, sizeof(char), len1, fl); MSG_HEADING(board_type, i) = tmp1; if ((len2 = msg_index[board_type][i].message_len)) { if ((MSG_SLOTNUM(board_type, i) = find_slot()) == -1) { stderr_log("SYSERR: Out of slots booting board! Resetting..."); Board_reset_board(board_type); return; } if (!(tmp2 = (char *) malloc(sizeof(char) * len2))) { stderr_log("SYSERR: malloc failed for board text"); fflush(NULL); exit(1); } fread(tmp2, sizeof(char), len2, fl); msg_storage[MSG_SLOTNUM(board_type, i)] = tmp2; } } fclose(fl); }
void init_boards(void) { int i, j, fatal_error = 0; char buf[256]; for (i = 0; i < INDEX_SIZE; i++) { msg_storage[i] = 0; msg_storage_taken[i] = 0; } for (i = 0; i < NUM_OF_BOARDS; i++) { if ((BOARD_RNUM(i) = real_object(BOARD_VNUM(i))) == -1) { sprintf(buf, "SYSERR: Fatal board error: board vnum %d does not exist!", BOARD_VNUM(i)); stderr_log(buf); fatal_error = 1; } num_of_msgs[i] = 0; for (j = 0; j < MAX_BOARD_MESSAGES; j++) { memset((char *) &(msg_index[i][j]), 0, sizeof(struct board_msginfo)); msg_index[i][j].slot_num = -1; } Board_load_board(i); } CMD_READ = find_command("read"); CMD_WRITE = find_command("write"); CMD_REMOVE = find_command("remove"); CMD_LOOK = find_command("look"); if (fatal_error) { fprintf(stderr, "Received fatal error shutting down.\n"); fflush(NULL); exit(1); } }
int find_first_step(sh_int src, sh_int target, int stay_zone) { int curr_dir; sh_int curr_room; int src_zone = ((src - (src % 100)) / 100); int target_zone = ((target - (target % 100)) / 100); if (src < 0 || src > top_of_world || target < 0 || target > top_of_world) { stderr_log("Illegal value passed to find_first_step (graph.c)"); return BFS_ERROR; } /* dez 19980805 if ((src_zone != target_zone && stay_zone == 1) || stay_zone == 2) { return BFS_NO_PATH; } */ if (src_zone != target_zone && stay_zone == 1) { return BFS_NO_PATH; } if (src == target) { return BFS_ALREADY_THERE; } /* clear marks first */ for (curr_room = 0; curr_room <= top_of_world; curr_room++) { UNMARK(curr_room); } MARK(src); /* first, enqueue the first steps, saving which direction we're going. */ for (curr_dir = 0; curr_dir < NUM_OF_DIRS; curr_dir++) { if (VALID_EDGE(src, curr_dir)) { MARK(TOROOM(src, curr_dir)); bfs_enqueue(TOROOM(src, curr_dir), curr_dir); } } /* now, do the classic BFS. */ while (queue_head) { if (queue_head->room == target) { curr_dir = queue_head->dir; bfs_clear_queue(); return curr_dir; } else { for (curr_dir = 0; curr_dir < NUM_OF_DIRS; curr_dir++) { if (VALID_EDGE(queue_head->room, curr_dir)) { MARK(TOROOM(queue_head->room, curr_dir)); bfs_enqueue(TOROOM(queue_head->room, curr_dir), queue_head->dir); } } bfs_dequeue(); } } return BFS_NO_PATH; }
void Board_write_message(int board_type, struct char_data * ch, char *arg) { char *tmstr; int len; time_t ct; char buf[MAX_INPUT_LENGTH], buf2[MAX_INPUT_LENGTH]; if (WRITE_LVL(board_type) != 0 && !COM_FLAGGED(ch, WRITE_LVL(board_type))) { send_to_char("You are not holy enough to write on this board.\r\n", ch); return; } if (num_of_msgs[board_type] >= MAX_BOARD_MESSAGES) { send_to_char("The board is full.\r\n", ch); return; } if ((NEW_MSG_INDEX(board_type).slot_num = find_slot()) == -1) { send_to_char("The board is malfunctioning - sorry.\r\n", ch); stderr_log("SYSERR: Board: failed to find empty slot on write."); return; } /* skip blanks */ skip_spaces(&arg); delete_doubledollar(arg); if (!*arg) { send_to_char("We must have a headline!\r\n", ch); return; } ct = time(0); tmstr = (char *) asctime(localtime(&ct)); *(tmstr + strlen(tmstr) - 1) = '\0'; sprintf(buf2, "(%s)", GET_NAME(ch)); sprintf(buf, "%6.10s %-12s :: %s", tmstr, buf2, arg); len = strlen(buf) + 1; if (!(NEW_MSG_INDEX(board_type).heading = (char *) malloc(sizeof(char) * len))) { send_to_char("The board is malfunctioning - sorry.\r\n", ch); return; } strcpy(NEW_MSG_INDEX(board_type).heading, buf); NEW_MSG_INDEX(board_type).heading[len - 1] = '\0'; NEW_MSG_INDEX(board_type).level = GET_LEVEL(ch); sprintf(logbuffer, "%s writing new message (%s) on board in #%d", GET_NAME(ch), buf, world[ch->in_room].number); mudlog(logbuffer, 'B', COM_ADMIN, FALSE); send_to_char("Write your message. (/s saves /h for help)\r\n\r\n", ch); act("$n starts to write a message.", TRUE, ch, 0, 0, TO_ROOM); if (!IS_NPC(ch)) SET_BIT(PLR_FLAGS(ch), PLR_WRITING); ch->desc->str = &(msg_storage[NEW_MSG_INDEX(board_type).slot_num]); ch->desc->max_str = MAX_MESSAGE_LENGTH; ch->desc->mail_to = (char*) board_type + BOARD_MAGIC; num_of_msgs[board_type]++; }
int Board_display_msg(int board_type, struct char_data * ch, char *arg) { char number[MAX_STRING_LENGTH], buffer[MAX_STRING_LENGTH]; int msg, ind; one_argument(arg, number); if (!*number) return 0; if (isname(number, "board bulletin")) /* so "read board" works */ return (Board_show_board(board_type, ch, arg)); if (!isdigit(*number) || (!(msg = atoi(number)))) return 0; if (READ_LVL(board_type) != 0 && !COM_FLAGGED(ch, READ_LVL(board_type))) { send_to_char("You try but fail to understand the holy words.\r\n", ch); return 1; } if (!num_of_msgs[board_type]) { send_to_char("The board is empty!\r\n", ch); return (1); } if (msg < 1 || msg > num_of_msgs[board_type]) { send_to_char("That message exists only in your imagination.\r\n", ch); return (1); } ind = msg - 1; if (MSG_SLOTNUM(board_type, ind) < 0 || MSG_SLOTNUM(board_type, ind) >= INDEX_SIZE) { send_to_char("Sorry, the board is not working.\r\n", ch); stderr_log("SYSERR: Board is screwed up."); return 1; } if (!(MSG_HEADING(board_type, ind))) { send_to_char("That message appears to be screwed up.\r\n", ch); return 1; } if (!(msg_storage[MSG_SLOTNUM(board_type, ind)])) { send_to_char("That message seems to be empty.\r\n", ch); return 1; } sprintf(buffer, "Message %d : %s\r\n\r\n%s\r\n", msg, MSG_HEADING(board_type, ind), msg_storage[MSG_SLOTNUM(board_type, ind)]); page_string(ch->desc, buffer, 1); return 1; }
int Board_show_board(int board_type, struct char_data * ch, char *arg) { int i; char tmp[MAX_STRING_LENGTH], buf[MAX_STRING_LENGTH]; if (!ch->desc) return 0; one_argument(arg, tmp); if (!*tmp || !isname(tmp, "board bulletin")) return 0; if (READ_LVL(board_type) != 0 && !COM_FLAGGED(ch, READ_LVL(board_type))) { send_to_char("You try but fail to understand the holy words.\r\n", ch); return 1; } act("$n studies the board.", TRUE, ch, 0, 0, TO_ROOM); strcpy(buf, "This is a bulletin board. Usage: READ/REMOVE <messg #>, WRITE <header>.\r\n" "You will need to look at the board to save your message.\r\n"); if (!num_of_msgs[board_type]) strcat(buf, "The board is empty.\r\n"); else { sprintf(buf + strlen(buf), "There are %d messages on the board.\r\n", num_of_msgs[board_type]); /* uncomment below if want most recent message at bottom */ /* for (i = 0; i < num_of_msgs[board_type]; i++) { */ for (i = num_of_msgs[board_type] - 1; i >= 0; i--) { if (MSG_HEADING(board_type, i)) sprintf(buf + strlen(buf), "%s%-2d%s : %s%s\r\n", CBWHT(ch, C_NRM), i + 1, CCCYN(ch, C_NRM), MSG_HEADING(board_type, i), CCNRM(ch, C_NRM)); else { stderr_log("SYSERR: The board is fubar'd."); send_to_char("Sorry, the board isn't working.\r\n", ch); return 1; } } } page_string(ch->desc, buf, 1); return 1; }
int Board_remove_msg(int board_type, struct char_data * ch, char *arg) { int ind, msg, slot_num; char number[MAX_INPUT_LENGTH], buf[MAX_INPUT_LENGTH]; struct descriptor_data *d; one_argument(arg, number); if (!*number || !isdigit(*number)) return 0; if (!(msg = atoi(number))) return (0); if (!num_of_msgs[board_type]) { send_to_char("The board is empty!\r\n", ch); return 1; } if (msg < 1 || msg > num_of_msgs[board_type]) { send_to_char("That message exists only in your imagination.\r\n", ch); return 1; } ind = msg - 1; if (!MSG_HEADING(board_type, ind)) { send_to_char("That message appears to be screwed up.\r\n", ch); return 1; } sprintf(buf, "(%s)", GET_NAME(ch)); if (REMOVE_LVL(board_type) != 0 && !COM_FLAGGED(ch, REMOVE_LVL(board_type)) && !(strstr(MSG_HEADING(board_type, ind), buf))) { send_to_char("You are not holy enough to remove other people's messages.\r\n", ch); return 1; } if (GET_LEVEL(ch) < MSG_LEVEL(board_type, ind)) { send_to_char("You can't remove a message holier than yourself.\r\n", ch); return 1; } slot_num = MSG_SLOTNUM(board_type, ind); if (slot_num < 0 || slot_num >= INDEX_SIZE) { stderr_log("SYSERR: The board is seriously screwed up."); send_to_char("That message is majorly screwed up.\r\n", ch); return 1; } for (d = descriptor_list; d; d = d->next) if (!d->connected && d->str == &(msg_storage[slot_num])) { send_to_char("At least wait until the author is finished before removing it!\r\n", ch); return 1; } sprintf(logbuffer, "%s removed message #%d (%s) from board #%d", GET_NAME(ch), msg, MSG_HEADING(board_type, ind), world[ch->in_room].number); mudlog(logbuffer, 'B', COM_ADMIN, FALSE); if (msg_storage[slot_num]) FREE(msg_storage[slot_num]); msg_storage[slot_num] = 0; msg_storage_taken[slot_num] = 0; if (MSG_HEADING(board_type, ind)) FREE(MSG_HEADING(board_type, ind)); for (; ind < num_of_msgs[board_type] - 1; ind++) { MSG_HEADING(board_type, ind) = MSG_HEADING(board_type, ind + 1); MSG_SLOTNUM(board_type, ind) = MSG_SLOTNUM(board_type, ind + 1); MSG_LEVEL(board_type, ind) = MSG_LEVEL(board_type, ind + 1); } num_of_msgs[board_type]--; send_to_char("Message removed.\r\n", ch); sprintf(buf, "$n just removed message %d.", msg); act(buf, FALSE, ch, 0, 0, TO_ROOM); Board_save_board(board_type); return 1; }
void parse_quest(FILE *quest_file, int vnum) { static int i = 0; struct char_data *mob = NULL; char line[MAX_INPUT_LENGTH]; char value[MAX_INPUT_LENGTH]; char field[20]; int numval = 0; int nummsgs = 0; int numneeds = 0; int mob_rnum = 0; i++; mob_rnum = real_mobile(vnum); if (mob_rnum == -1) { stderr_log("Error trying to assign quest to non-existant mob."); fflush(NULL); exit(1); } mob = (mob_proto + mob_rnum); GET_MOB_QUEST_NUM(mob) = i; (mob_quests + i)->maxlevel = 51; (mob_quests + i)->qnum = i; while (get_line(quest_file, line)) { if (line[0] == 'S') { return; } parse_pline(line, field, value); numval = atoi(value); switch (UPPER(*field)) { case 'A': if (strcmp(field, "amount") == 0) { (mob_quests + i)->needs[numneeds].amount = numval; numneeds++; (mob_quests + i)->maxneeds = numneeds; } else { sprintf(buf2, "Unknown Quest field [%s]", field); stderr_log(buf2); } break; case 'C': if (strcmp(field, "classlist") == 0) { (mob_quests + i)->classlist = asciiflag_conv(value); } else { sprintf(buf2, "Unknown Quest field [%s]", field); stderr_log(buf2); } break; case 'D': if (strcmp(field, "destroy") == 0) { if (strcasecmp(value, "no") == 0) { (mob_quests + i)->needs[numneeds].destroy = 0; } } else { sprintf(buf2, "Unknown Quest field [%s]", field); stderr_log(buf2); } break; case 'F': if (strcmp(field, "flags") == 0) { (mob_quests + i)->flags = asciiflag_conv(value); } else { sprintf(buf2, "Unknown Quest field [%s]", field); stderr_log(buf2); } break; case 'G': if (strcmp(field, "goal") == 0) { (mob_quests + i)->goal = search_block(value, goal_list, FALSE); } else { sprintf(buf2, "Unknown Quest field [%s]", field); stderr_log(buf2); } break; case 'K': if (strcmp(field, "keywords") == 0) { RECREATE((mob_quests + i)->messages, struct quest_message_data, nummsgs + 1); (mob_quests + i)->messages[nummsgs].keywords = strdup(value); } else if (strcmp(field, "knowledge") == 0) { line[0] = '\0'; (mob_quests + i)->knowledge = fread_string(quest_file, line); } else { sprintf(buf2, "Unknown Quest field [%s]", field); stderr_log(buf2); } break; case 'M': if (strcmp(field, "maxlevel") == 0) { (mob_quests + i)->maxlevel = numval; } else if (strcmp(field, "message") == 0) { line[0] = '\0'; (mob_quests + i)->messages[nummsgs].message = fread_string(quest_file, line); nummsgs++; (mob_quests + i)->maxmsgs = nummsgs; } else { sprintf(buf2, "Unknown Quest field [%s]", field); stderr_log(buf2); } break; case 'N': if (strcmp(field, "needs") == 0) { RECREATE((mob_quests + i)->needs, struct quest_needs_data, numneeds + 1); (mob_quests + i)->needs[numneeds].destroy = 1; (mob_quests + i)->needs[numneeds].participants = NULL; (mob_quests + i)->needs[numneeds].type = search_block(value, needs_list, FALSE); (mob_quests + i)->needs[numneeds].complete = 0; (mob_quests + i)->needs[numneeds].needs_complete_msg = NULL; (mob_quests + i)->needs[numneeds].need_more_msg = NULL; } else if (strcmp(field, "need_more_msg") == 0) {
/* return values: 0 - successful load, keep char in rent room. 1 - load failure or load of crash items -- put char in temple. 2 - rented equipment lost (no $) */ int Crash_load(struct char_data * ch) { void Crash_save(struct char_data * ch, int type); FILE *fl; char fname[MAX_STRING_LENGTH]; char buf[MAX_STRING_LENGTH]; char input[MAX_INPUT_LENGTH + 1]; char tag[MAX_INPUT_LENGTH + 1]; char tag_arguments[MAX_INPUT_LENGTH + 1]; int val; struct obj_data *tmpobj = NULL; struct obj_data *tmpobj2; struct obj_data *next_obj; int found_begin = 0; int affect_counter = 0; int found; char *p; struct corpse_obj_save *crash_load_stack = NULL; struct corpse_obj_save *temp_stack = NULL; struct corpse_obj_save *temp_stack_next = NULL; int chg; int ovnum = 0; int j; if (!get_filename(GET_NAME(ch), fname, CRASH_FILE)) { return 1; } if (!(fl = fopen(fname, "r"))) { if (errno != ENOENT) { /* if it fails, NOT because of no file */ sprintf(buf1, "SYSERR: READING OBJECT FILE %s (5)", fname); perror(buf1); send_to_char("\r\n********************* NOTICE *********************\r\n" "There was a problem loading your objects from disk.\r\n" "Contact a God for assistance.\r\n", ch); } sprintf(buf, "%s entering game with no equipment.", GET_NAME(ch)); mudlog(buf, 'R', COM_IMMORT, TRUE); plog(buf, ch, 0); return 1; } while (get_line(fl, input)) { parse_pline(input, tag, tag_arguments); while ((p = strrchr(tag_arguments, '\n')) != NULL) { *p = '\0'; } val = atoi(tag_arguments); switch (tag[4]) { case 'a': case 'A': if (strcasecmp(tag, "obj_affect_loc") == 0 && affect_counter < MAX_OBJ_AFFECT) { tmpobj->affected[affect_counter].location = val; } else if (strcasecmp(tag, "obj_affect_mod") == 0 && affect_counter < MAX_OBJ_AFFECT) { tmpobj->affected[affect_counter].modifier = val; affect_counter++; } else { sprintf(buf, "Unknown Rent-File Tag: %s", tag); stderr_log(buf); } break; case 'b': case 'B': if (strcasecmp(tag, "obj_begin") == 0) { if (found_begin) { send_to_char("\r\n********************* NOTICE *********************\r\n" "There was a problem loading your objects from disk.\r\n" "Contact a God for assistance.\r\n", ch); return 1; } found_begin = 1; } else if (strcasecmp(tag, "obj_bitvector") == 0) { GET_OBJ_BITV(tmpobj) = asciiflag_conv(tag_arguments); } else if (strcasecmp(tag, "obj_bitvector2") == 0) { GET_OBJ_BITV2(tmpobj) = asciiflag_conv(tag_arguments); } else { sprintf(buf, "Unknown Rent-File Tag: %s", tag); stderr_log(buf); } break; case 'e': case 'E': if (strcasecmp(tag, "obj_extra_flags") == 0) { GET_OBJ_EXTRA(tmpobj) = asciiflag_conv(tag_arguments); } else if (strcasecmp(tag, "obj_end") == 0) { if (ovnum >= 0) { if (!found_begin) { send_to_char("\r\n********************* NOTICE *********************\r\n" "There was a problem loading your objects from disk.\r\n" "Contact a God for assistance.\r\n", ch); return 1; } found_begin = 0; affect_counter = 0; CREATE(crash_load_stack, struct corpse_obj_save, 1); crash_load_stack->level = 0; crash_load_stack->prev = NULL; for (tmpobj2 = ch->carrying, found = 0; tmpobj2 && !found; tmpobj2 = next_obj) { next_obj = tmpobj2->next_content; if (tmpobj2->objnum == tmpobj->inobj) { obj_to_obj(tmpobj, tmpobj2); found = 1; } if (tmpobj2->contains) { crash_load_stack->next_obj = next_obj; CREATE(temp_stack, struct corpse_obj_save, 1); temp_stack->level = crash_load_stack->level + 1; temp_stack->prev = crash_load_stack; crash_load_stack = temp_stack; next_obj = tmpobj2->contains; if (tmpobj2 == next_obj) { /* infinite loop */ next_obj = NULL; continue; } } else if (next_obj == NULL && crash_load_stack->level > 0) { temp_stack = crash_load_stack; crash_load_stack = crash_load_stack->prev; FREE(temp_stack); next_obj = crash_load_stack->next_obj; } } for (temp_stack = crash_load_stack; temp_stack; temp_stack = temp_stack_next) { temp_stack_next = temp_stack->prev; FREE(temp_stack); } if (!found) { obj_to_char(tmpobj, ch); } } else { extract_obj(tmpobj); found_begin = 0; affect_counter = 0; ovnum = 0; } } else {
int Crash_clean_file(char *name) { char fname[MAX_STRING_LENGTH]; char input[MAX_INPUT_LENGTH + 1]; char tag[MAX_INPUT_LENGTH + 1]; char tag_arguments[MAX_INPUT_LENGTH + 1]; int val; extern int rent_file_timeout, crash_file_timeout; FILE *fl; time_t rent_time = time(NULL); char *p; if (!get_filename(name, fname, CRASH_FILE)) { return 0; } if (!(fl = fopen(fname, "r"))) { if (errno != ENOENT) { /* if it fails, NOT because of no file */ sprintf(buf1, "SYSERR: OPENING OBJECT FILE %s (4)", fname); perror(buf1); } return 0; } while (get_line(fl, input)) { parse_pline(input, tag, tag_arguments); while ((p = strrchr(tag_arguments, '\n')) != NULL) { *p = '\0'; } val = atoi(tag_arguments); switch (tag[0]) { case 'r': case 'R': if (strcasecmp(tag, "rent_time") == 0) rent_time = val; else if (strcasecmp(tag, "rent_type") == 0) { fclose(fl); switch (val) { case RENT_CRASH: case RENT_FORCED: case RENT_TIMEDOUT: if (rent_time < (time(NULL) - (crash_file_timeout * SECS_PER_REAL_DAY))) { Crash_delete_file(name); switch (val) { case RENT_CRASH: sprintf(buf, " Deleting %s's crash file.", name); break; case RENT_FORCED: sprintf(buf, " Deleting %s's forced rent file.", name); break; case RENT_TIMEDOUT: sprintf(buf, " Deleting %s's idlesave file.", name); break; } stderr_log(buf); return 1; } break; case RENT_RENTED: case RENT_CAMPED: if (rent_time < (time(0) - (rent_file_timeout * SECS_PER_REAL_DAY))) { Crash_delete_file(name); switch (val) { case RENT_RENTED: sprintf(buf, " Deleting %s's rent file.", name); break; case RENT_CAMPED: sprintf(buf, " Deleting %s's camp file.", name); break; } stderr_log(buf); return 1; } } return 1; } break; } } return (0); }
void ident_check(struct descriptor_data *d, int pulse) { fd_set fd, efd; int rc, rmt_port, our_port, len; char user[256], *p; extern struct timeval null_time; extern int port; /* * Each pulse, this checks if the ident is ready to proceed to the * next state, by calling select to see if the socket is writeable * (connected) or readable (response waiting). */ switch (STATE(d)) { case CON_IDCONING: /* waiting for connect() to finish */ if (d->ident_sock != INVALID_SOCKET) { FD_ZERO(&fd); FD_ZERO(&efd); FD_SET(d->ident_sock, &fd); FD_SET(d->ident_sock, &efd); } if ((rc = select(d->ident_sock + 1, (fd_set *) 0, &fd, &efd, &null_time)) == 0) break; else if (rc < 0) { logerror("ident check select (conning)"); STATE(d) = CON_ASKNAME; break; } if (FD_ISSET(d->ident_sock, &efd)) { /* exception, such as failure to connect */ STATE(d) = CON_ASKNAME; break; } STATE(d) = CON_IDCONED; break; case CON_IDCONED: /* connected, write request */ sprintf(buf, "%d, %d\n\r", ntohs(d->peer_port), port); len = strlen(buf); #ifdef CIRCLE_WINDOWS if (send(d->ident_sock, buf, len, 0) < 0) { #else if (write(d->ident_sock, buf, len) != len) { if (errno != EPIPE) /* read end closed (no remote identd) */ #endif logerror("ident check write (conned)"); STATE(d) = CON_ASKNAME; break; } STATE(d) = CON_IDREADING; break; case CON_IDREADING: /* waiting to read */ if (d->ident_sock != INVALID_SOCKET) { FD_ZERO(&fd); FD_ZERO(&efd); FD_SET(d->ident_sock, &fd); FD_SET(d->ident_sock, &efd); } if ((rc = select(d->ident_sock + 1, &fd, (fd_set *) 0, &efd, &null_time)) == 0) break; else if (rc < 0) { logerror("ident check select (reading)"); STATE(d) = CON_ASKNAME; break; } if (FD_ISSET(d->ident_sock, &efd)) { STATE(d) = CON_ASKNAME; break; } STATE(d) = CON_IDREAD; break; case CON_IDREAD: /* read ready, get the info */ #ifdef CIRCLE_WINDOWS if ((len = recv(d->ident_sock, buf, sizeof(buf) - 1, 0)) < 0) #else if ((len = read(d->ident_sock, buf, sizeof(buf) - 1)) < 0) #endif logerror("ident check read (read)"); else { buf[len] = '\0'; if (sscanf(buf, "%u , %u : USERID :%*[^:]:%255s", &rmt_port, &our_port, user) != 3) { /* check if error or malformed */ if (sscanf(buf, "%u , %u : ERROR : %255s", &rmt_port, &our_port, user) == 3) { sprintf(buf2, "Ident error from %s: \"%s\"", d->hostIP, user); stderr_log(buf2); } else { /* strip off trailing newline */ for (p = buf + len - 1; p > buf && ISNEWL(*p); p--) ; p[1] = '\0'; sprintf(buf2, "Malformed ident response from %s: \"%s\"", d->hostIP, buf); stderr_log(buf2); } } else { len = HOST_LENGTH - strlen(d->hostIP); if (len > 0) { strncpy(buf2, user, len - 1); buf2[len - 1] = '\0'; strcpy(d->username, buf2); } /* if len <= 0, no space for username */ } } STATE(d) = CON_ASKNAME; break; case CON_ASKNAME: /* ident complete, ask for name */ /* close up the ident socket, if one is opened. */ if (d->ident_sock != INVALID_SOCKET) { close(d->ident_sock); d->ident_sock = INVALID_SOCKET; } d->idle_tics = 0; /* extra ban check */ if ((d->host[0] != '\0' && isbanned(d->host) == BAN_ALL) || isbanned(d->hostIP)) { if (d->host[0] != '\0') { sprintf(buf, "Connection attempt denied from [%s]", d->host); } else { sprintf(buf, "Connection attempt denied from [%s]", d->hostIP); } mudlog(buf, 'S', COM_IMMORT, TRUE); close_socket(d); return; } /* SEND_TO_Q("\x1B[2K\n\rBy what name do you wish to be known? ", d); */ STATE(d) = CON_GET_TERMTYPE; return; default: return; } /* * Print a dot every second so the user knows he hasn't been forgotten. * Allow the user to go on anyways after waiting IDENT_TIMEOUT seconds. */ if ((pulse % PASSES_PER_SEC) == 0) { SEND_TO_Q(".", d); if (d->idle_tics++ >= IDENT_TIMEOUT) STATE(d) = CON_ASKNAME; } } /* returns 1 if waiting for ident to complete, else 0 */ int waiting_for_ident(struct descriptor_data *d) { switch (STATE(d)) { case CON_IDCONING: case CON_IDCONED: case CON_IDREADING: case CON_IDREAD: case CON_ASKNAME: return 1; } return 0; }