static T_Status Login(T_WWW internet, T_Glyph_Ptr email, T_Glyph_Ptr password, bool is_report_success) { static T_Glyph_Ptr l_last_email = NULL; static T_Glyph_Ptr l_last_password = NULL; T_Status status; T_Glyph_Ptr ptr, newline, invalid; /* Save our last email and password if given, or re-use them if we weren't passed in an email or password */ if (email != NULL) l_last_email = email; else email = l_last_email; if (password != NULL) l_last_password = password; else password = l_last_password; /* If we don't have an email or password, we can't log in */ if ((email[0] == '\0') || (password[0] == '\0')) x_Status_Return_Success(); /* Set up our arrays of name/value parameters to use for the login POST */ T_Glyph_Ptr names[] = { "email", "password" }; T_Glyph_Ptr values[] = { email, password }; /* Logging in is a simple POST of our username & password to the D&DI server */ status = WWW_HTTP_Post(internet,LOGIN_URL,x_Array_Size(names),names,values,&ptr); if (x_Trap_Opt(!x_Is_Success(status))) { Log_Message("Couldn't make login HTTP post!\n", true); x_Status_Return(status); } /* If the string 'invalid' appears in the first line of our response, it's a failed login. */ newline = strchr(ptr, '\n'); if (newline == NULL) { Log_Message("\n**** Login error - could not log in to D&D insider.\n", true); x_Status_Return(LWD_ERROR); } invalid = strstr(ptr, "invalid"); if ((invalid != NULL) && (invalid < newline)) { Log_Message("\n**** Login error - username / password not recognised.\n", true); x_Status_Return(LWD_ERROR); } Log_Message("Login succeeded.\n", is_report_success); l_is_password = true; x_Status_Return_Success(); }
bool Is_Regex_Match(T_Glyph_Ptr regexp, T_Glyph_Ptr text, T_Glyph_Ptr capture1, T_Glyph_Ptr capture2) { int result, size; bool is_match = false; regex_t rx; regmatch_t matches[3]; // entire string + 2 return parameters if (capture1 != NULL) capture1[0] = '\0'; if (capture2 != NULL) capture2[0] = '\0'; if (text[0] == '\0') return(false); result = regcomp(&rx, regexp, REG_EXTENDED); if (x_Trap_Opt(result != 0)) return(false); /* If we didn't match, there are no capture groups to return. If the caller doesn't want us to capture anything, we can just pass 0 for the size. */ size = ((capture1 == NULL) && (capture2 == NULL)) ? 0 : x_Array_Size(matches); result = regexec(&rx, text, size, matches, 0); if (result == REG_NOMATCH) goto cleanup_exit; if (x_Trap_Opt(result != 0)) goto cleanup_exit; is_match = true; /* Copy our captures into the parameters, if provided. NOTE: matches[0] holds the entire matched string, so we only care about what's in matches[1] and following, which are the capture group results. */ if (capture1 != NULL) Copy_Capture(capture1, text, &matches[1]); if (capture2 != NULL) Copy_Capture(capture2, text, &matches[2]); cleanup_exit: regfree(&rx); return(is_match); }
static void Output_Key_Skills(T_Ritual_Info * info) { T_Int32U i, length, temp_length, chunk_count; T_Glyph_Ptr ptr, temp, chunks[1000]; T_Glyph buffer[100000], message[1000]; if ((info->keyskill == NULL) || (info->keyskill[0] == '\0')) { sprintf(message, "No key skill present for ritual %s\n", info->name); Log_Message(message); return; } /* First, check for '(no check)' at the end */ temp = "(no check)"; temp_length = strlen(temp); ptr = info->keyskill; length = strlen(ptr); if (temp_length < length) { ptr = info->keyskill + length - temp_length; if (strcmp(ptr, temp) == 0) { Output_Tag(info->node, "RitualSkl", "NoCheck", info); while ((ptr > info->keyskill) && (ptr[-1] == ' ')) ptr--; *ptr = '\0'; } } chunk_count = x_Array_Size(chunks); Split_To_Array(buffer, chunks, &chunk_count, info->keyskill, ", "); for (i = 0; i < chunk_count; i++) { /* If this is 'or', ignore it */ if (strcmp(chunks[i], "or") == 0) continue; Output_Tag(info->node, "RitualSkl", chunks[i], info, "skill"); } }
{ STRING_TAG_MISSING, "One or more required child tag(s) (%0) are missing" }, { STRING_PCDATA_NONCOMPLIANT, "Element '%0' PCDATA is not compliant with specified rules" }, { STRING_EXPECTED_CLOSE_TAG, "Expected close tag for element '%0'" }, { STRING_PCDATA_NOT_ALLOWED, "Encountered PCDATA for element '%0' proscribed against PCDATA" }, { STRING_UNKNOWN_TAG, "Encountered unknown element tag '%0'" }, { STRING_ELEMENT_LIMIT_ONE, "Child element '%0' appears more times than its limit (1) in '%1'" }, { STRING_ELEMENT_EXACTLY_ONCE, "Element tag '%0' does not appear exactly once in '%1'" }, { STRING_ELEMENT_REQUIRED, "Element tag '%0' must appear at least once in '%1'" }, { STRING_UNEXPECTED_END, "Unexpected end of data - ill-formed XML" }, { STRING_CDATA_TERMINATION, "CDATA block not properly terminated" }, { STRING_SPECIAL_TOKEN, "Unrecognized special token following '&'" }, { STRING_ASSIGNMENT_SYNTAX, "Invalid value syntax for attribute assignment" }, { STRING_BAD_VERSION_TAG, "Invalid version tag" }, { STRING_EXPECTED_START_TAG, "Expected start of an element tag" }, { STRING_BAD_TOPLEVEL_TAG, "Invalid top-level element tag" }, { STRING_COMMENT_DOUBLE_DASH, "The character sequence '--' may not be used inside a comment" }, { STRING_COMMENT_TERMINATION, "Comment block not properly terminated" }, { STRING_BAD_CHARACTER_ENCODING,"Unrecognized character encoding specified" }, { STRING_ELEMENT_TERMINATION, "Expected closing '>' for element '%0'" }, { STRING_BAD_ATTRIBUTE_VALUE, "Value specified for attribute '%0' is not valid" }, { STRING_PREMATURE_END, "Premature end of document encountered" }, { STRING_ATTRIBUTE_YES_NO, "Value for attribute '%0' must be 'yes' or 'no'" }, { STRING_EXTRANEOUS_DATA, "Extraneous data encountered past end of top-level element" }, { STRING_BAD_STYLESHEET_TAG, "Invalid stylesheet tag" }, { STRING_INVALID_XML_DOCUMENT, "Document does not possess a valid structure" } }; T_Internal_String_Table g_xml_strings = { MODULE_ID_XML, x_Array_Size(l_strings), l_strings, FALSE };
/* Note - this function should be resilient to stuff in the HTML changing, so if we don't find what we expect, we should just return successfully and not complain about it. */ T_Status C_DDI_Rituals::Parse_Entry_Details(T_Glyph_Ptr contents, T_Ritual_Info * info, T_Glyph_Ptr ptr, T_Glyph_Ptr checkpoint, vector<T_Ritual_Info> * extras) { T_Status status; T_Glyph_Ptr end; T_Glyph_Ptr starts[] = { "???", }; T_Glyph_Ptr ends[] = { "<br", "</p", "</span" }; ptr = Extract_Text(&info->flavor, m_pool, ptr, checkpoint, "<span class=\"flavor\">", "</span>"); Strip_Bad_Characters(info->flavor); /* This was parsed from the index above, but we might as well grab it again here, in case there's more information */ starts[0] = "<b>Component Cost</b>:"; ptr = Extract_Text(&info->componentcost, m_pool, ptr, checkpoint, starts, x_Array_Size(starts), ends, x_Array_Size(ends)); Strip_Bad_Characters(info->componentcost); /* Although we've parsed the skill out of the index, replace it if we can - the one on the actual page has more data (e.g. "no check" info). */ starts[0] = "<b>Key Skill</b>:"; ptr = Extract_Text(&info->keyskill, m_pool, ptr, checkpoint, starts, x_Array_Size(starts), ends, x_Array_Size(ends)); Strip_Bad_Characters(info->keyskill); /* Although we've parsed the level out of the index, replace it if we can - the one on the actual page has more data. */ starts[0] = "<b>Level</b>:"; ptr = Extract_Text(&info->level, m_pool, ptr, checkpoint, starts, x_Array_Size(starts), ends, x_Array_Size(ends)); Strip_Bad_Characters(info->level); starts[0] = "<b>Category</b>:"; ptr = Extract_Text(&info->category, m_pool, ptr, checkpoint, starts, x_Array_Size(starts), ends, x_Array_Size(ends)); Strip_Bad_Characters(info->category); starts[0] = "<b>Time</b>:"; ptr = Extract_Text(&info->time, m_pool, ptr, checkpoint, starts, x_Array_Size(starts), ends, x_Array_Size(ends)); Strip_Bad_Characters(info->time); starts[0] = "<b>Duration</b>:"; ptr = Extract_Text(&info->duration, m_pool, ptr, checkpoint, starts, x_Array_Size(starts), ends, x_Array_Size(ends)); Strip_Bad_Characters(info->duration); starts[0] = "<b>Prerequisite</b>:"; ptr = Extract_Text(&info->prerequisite, m_pool, ptr, checkpoint, starts, x_Array_Size(starts), ends, x_Array_Size(ends)); Strip_Bad_Characters(info->prerequisite); /* Parse out any paragraph close tag we encounter here */ if (strnicmp(ptr, "</p>", 4) == 0) ptr += 4; /* Now parse the rest of the description - it might end in a </p> tag, or it might not! Who knows! */ end = Find_Text(ptr, "</p>", checkpoint, false, false); if (end == NULL) end = checkpoint; *end = '\0'; status = Parse_Description_Text(&info->description, ptr, m_pool); if (x_Trap_Opt(!x_Is_Success(status))) x_Status_Return(status); *end = '<'; x_Status_Return_Success(); }