/* 23.4.13 */ acl_t acl_from_text(const char *buf_p) { acl_t acl; acl = acl_init(0); if (!acl) return NULL; if (!buf_p) { errno = EINVAL; return NULL; } while (*buf_p != '\0') { if (parse_acl_entry(&buf_p, &acl) != 0) goto fail; SKIP_WS(buf_p); if (*buf_p == ',') { buf_p++; SKIP_WS(buf_p); } } if (*buf_p != '\0') { errno = EINVAL; goto fail; } return acl; fail: acl_free(acl); return NULL; }
/* Read argument in macro expansion, starting from one offset from the initial * open parenthesis. Stop readin when reaching a comma, and nesting depth is * zero. Track nesting depth to allow things like MAX( foo(a), b ). */ static struct token *read_arg( const struct token *list, const struct token **endptr) { size_t n = 0; struct token *arg = calloc(1, sizeof(*arg)); int nesting = 0; SKIP_WS(list); do { if (list->token == END) { error("Unexpected end of input in expansion."); exit(1); } if (list->token == '(') { nesting++; } else if (list->token == ')') { nesting--; if (nesting < 0) { error("Negative nesting depth in expansion."); exit(1); } } arg = realloc(arg, (++n + 1) * sizeof(*arg)); arg[n - 1] = *list++; SKIP_WS(list); } while (nesting || (list->token != ',' && list->token != ')')); arg[n] = token_end; *endptr = list; return arg; }
int getproperty(FILE* html,char* property) { int c=0; char* p=property; int outword=0; int lim=MAX_PROPERTY-2; SKIP_WS(html,c); do { if (IS_SPACE(c)) {outword=1;SKIP_WS(html,c);} if (c==EOF) goto END_OF_FILE; if (c=='=') break; if (outword) {property=p;outword=0;} *property++=c; if (lim--<0) break; c=NEXT_CHAR(html); if (c==EOF) goto END_OF_FILE; } while (c!='='); *property='\0'; return 1; END_OF_FILE: *property='\0'; return 0; }
int gettag(FILE* html,char* tag) { int c=0; char* p=tag; int lim=MAX_TAG-2; do { c=NEXT_CHAR(html); if (c==EOF) break; } while (c!='<'); if (c==EOF) goto END_OF_FILE; SKIP_WS(html,c); do { if (lim--<0) break; *tag++=c; c=NEXT_CHAR(html); } while (!IS_SPACE(c)); *tag='\0'; return 1; END_OF_FILE: *tag='\0'; return 0; }
static bool parse_line(const char *line, char **key, char **value, char **errmsg) { const char *p, *q; #define SKIP_WS(x) while (isspace(*x)) { ++x; } *key = NULL; *value = NULL; p = line; SKIP_WS(p); if (*p == '\0' || *p == '#') { return true; } q = p; while (isalpha(*q) || *q == '_') { ++q; } *key = x_strndup(p, q - p); p = q; SKIP_WS(p); if (*p != '=') { *errmsg = x_strdup("missing equal sign"); free(*key); *key = NULL; return false; } ++p; /* Skip leading whitespace. */ SKIP_WS(p); q = p; while (*q) { ++q; } /* Skip trailing whitespace. */ while (isspace(q[-1])) { --q; } *value = x_strndup(p, q - p); return true; #undef SKIP_WS }
int getvalue(FILE* html,char* value) { int c=0; int quote_non=0; int quote_sng=0; int quote_dbl=0; int lim=MAX_VALUE-2; SKIP_WS(html,c); switch (c) { case '\"' : quote_dbl=1; break; case '\'' : quote_sng=1; break; default : quote_non=1; *value++=c; if (lim--<0) break; break; } do { c=NEXT_CHAR(html); if (END_OF_VALUE(c)) break; else { if (lim--<0) break; *value++=c; } } while (c!=EOF) ; if (c==EOF) goto END_OF_FILE; *value='\0'; // printf("%s\n",value); return 1; END_OF_FILE: *value='\0'; // printf("%s\n",value); return 0; }
static int skip_tag_name(const char **text_p, const char *token) { size_t len = strlen(token); const char *text = *text_p; SKIP_WS(text); if (strncmp(text, token, len) == 0) { text += len; goto delimiter; } if (*text == *token) { text++; goto delimiter; } return 0; delimiter: SKIP_WS(text); if (*text == ':') text++; *text_p = text; return 1; }
TCHAR* LabelCheck(TCHAR* s, TCHAR* pszLabel) { int nLen; if (s == NULL) { return NULL; } if (pszLabel == NULL) { return NULL; } nLen = _tcslen(pszLabel); SKIP_WS(s); // Skip whitespace if (_tcsncmp(s, pszLabel, nLen)){ // Doesn't match return NULL; } return s + nLen; }
int QuoteRead(TCHAR** ppszQuote, TCHAR** ppszEnd, TCHAR* pszSrc) // Read a (quoted) string from szSrc and point to the end { static TCHAR szQuote[QUOTE_MAX]; TCHAR* s = pszSrc; TCHAR* e; // Skip whitespace SKIP_WS(s); e = s; if (*s == _T('\"')) { // Quoted string s++; e++; // Find end quote FIND_QT(e); _tcsncpy(szQuote, s, e - s); // Zero-terminate szQuote[e - s] = _T('\0'); e++; } else { // Non-quoted string // Find whitespace FIND_WS(e); _tcsncpy(szQuote, s, e - s); // Zero-terminate szQuote[e - s] = _T('\0'); } if (ppszQuote) { *ppszQuote = szQuote; } if (ppszEnd) { *ppszEnd = e; } return 0; }
static char * get_token(const char **text_p) { char *token = NULL; const char *ep; ep = *text_p; SKIP_WS(ep); while (*ep!='\0' && *ep!='\r' && *ep!='\n' && *ep!=':' && *ep!=',') ep++; if (ep == *text_p) goto after_token; token = (char*)malloc(ep - *text_p + 1); if (token == 0) goto after_token; memcpy(token, *text_p, (ep - *text_p)); token[ep - *text_p] = '\0'; after_token: if (*ep == ':') ep++; *text_p = ep; return token; }
static int StringToInp(struct GameInp* pgi, TCHAR* s) { TCHAR* szRet = NULL; SKIP_WS(s); // skip whitespace szRet = LabelCheck(s, _T("undefined")); if (szRet) { pgi->nInput = 0; return 0; } szRet = LabelCheck(s, _T("constant")); if (szRet) { pgi->nInput = GIT_CONSTANT; s = szRet; pgi->Input.Constant.nConst=(unsigned char)_tcstol(s, &szRet, 0); *(pgi->Input.pVal) = pgi->Input.Constant.nConst; return 0; } szRet = LabelCheck(s, _T("switch")); if (szRet) { pgi->nInput = GIT_SWITCH; s = szRet; pgi->Input.Switch.nCode = (unsigned short)_tcstol(s, &szRet, 0); return 0; } // Analog using mouse axis: szRet = LabelCheck(s, _T("mouseaxis")); if (szRet) { pgi->nInput = GIT_MOUSEAXIS; return StringToMouseAxis(pgi, szRet); } // Analog using joystick axis: szRet = LabelCheck(s, _T("joyaxis-neg")); if (szRet) { pgi->nInput = GIT_JOYAXIS_NEG; return StringToJoyAxis(pgi, szRet); } szRet = LabelCheck(s, _T("joyaxis-pos")); if (szRet) { pgi->nInput = GIT_JOYAXIS_POS; return StringToJoyAxis(pgi, szRet); } szRet = LabelCheck(s, _T("joyaxis")); if (szRet) { pgi->nInput = GIT_JOYAXIS_FULL; return StringToJoyAxis(pgi, szRet); } // Analog using keyboard slider szRet = LabelCheck(s, _T("slider")); if (szRet) { s = szRet; pgi->nInput = GIT_KEYSLIDER; pgi->Input.Slider.SliderAxis.nSlider[0] = 0; // defaults pgi->Input.Slider.SliderAxis.nSlider[1] = 0; // pgi->Input.Slider.SliderAxis.nSlider[0] = (unsigned short)_tcstol(s, &szRet, 0); s = szRet; if (s == NULL) { return 1; } pgi->Input.Slider.SliderAxis.nSlider[1] = (unsigned short)_tcstol(s, &szRet, 0); s = szRet; if (s == NULL) { return 1; } szRet = SliderInfo(pgi, s); s = szRet; if (s == NULL) { // Get remaining slider info return 1; } return 0; } // Analog using joystick slider szRet = LabelCheck(s, _T("joyslider")); if (szRet) { s = szRet; pgi->nInput = GIT_JOYSLIDER; pgi->Input.Slider.JoyAxis.nJoy = 0; // defaults pgi->Input.Slider.JoyAxis.nAxis = 0; // pgi->Input.Slider.JoyAxis.nJoy = (unsigned char)_tcstol(s, &szRet, 0); s = szRet; if (s == NULL) { return 1; } pgi->Input.Slider.JoyAxis.nAxis = (unsigned char)_tcstol(s, &szRet, 0); s = szRet; if (s == NULL) { return 1; } szRet = SliderInfo(pgi, s); // Get remaining slider info s = szRet; if (s == NULL) { return 1; } return 0; } return 1; }
void load_cookies (const char *file) { char *line; FILE *fp = fopen (file, "r"); if (!fp) { logprintf (LOG_NOTQUIET, "Cannot open cookies file `%s': %s\n", file, strerror (errno)); return; } cookies_now = time (NULL); for (; ((line = read_whole_line (fp)) != NULL); xfree (line)) { struct cookie *cookie; char *p = line; int port; char *domain_b = NULL, *domain_e = NULL; char *ignore_b = NULL, *ignore_e = NULL; char *path_b = NULL, *path_e = NULL; char *secure_b = NULL, *secure_e = NULL; char *expires_b = NULL, *expires_e = NULL; char *name_b = NULL, *name_e = NULL; char *value_b = NULL, *value_e = NULL; SKIP_WS (p); if (!*p || *p == '#') /* empty line */ continue; SET_WORD_BOUNDARIES (p, domain_b, domain_e); SET_WORD_BOUNDARIES (p, ignore_b, ignore_e); SET_WORD_BOUNDARIES (p, path_b, path_e); SET_WORD_BOUNDARIES (p, secure_b, secure_e); SET_WORD_BOUNDARIES (p, expires_b, expires_e); SET_WORD_BOUNDARIES (p, name_b, name_e); /* Don't use SET_WORD_BOUNDARIES for value because it may contain whitespace. Instead, set value_e to the end of line, modulo trailing space (this will skip the line separator.) */ SKIP_WS (p); value_b = p; value_e = p + strlen (p); while (value_e > value_b && ISSPACE (*(value_e - 1))) --value_e; if (value_b == value_e) /* Hmm, should we check for empty value? I guess that's legal, so I leave it. */ ; cookie = cookie_new (); cookie->attr = strdupdelim (name_b, name_e); cookie->value = strdupdelim (value_b, value_e); cookie->path = strdupdelim (path_b, path_e); if (BOUNDED_EQUAL (secure_b, secure_e, "TRUE")) cookie->secure = 1; /* DOMAIN needs special treatment because we might need to extract the port. */ port = domain_port (domain_b, domain_e, (const char **)&domain_e); if (port) cookie->port = port; else cookie->port = cookie->secure ? DEFAULT_HTTPS_PORT : DEFAULT_HTTP_PORT; cookie->domain = strdupdelim (domain_b, domain_e); /* safe default in case EXPIRES field is garbled. */ cookie->expiry_time = cookies_now - 1; /* I don't like changing the line, but it's completely safe. (line is malloced.) */ *expires_e = '\0'; sscanf (expires_b, "%lu", &cookie->expiry_time); if (cookie->expiry_time < cookies_now) /* ignore stale cookie. */ goto abort; cookie->permanent = 1; store_cookie (cookie); next: continue; abort: delete_cookie (cookie); } fclose (fp); }
static int parse_acl_entry(const char **text_p, acl_t *acl_p) { acl_entry_obj entry_obj; acl_entry_t entry_d; char *str; const char *backup; int error, perm_chars; new_obj_p_here(acl_entry, &entry_obj); init_acl_entry_obj(entry_obj); /* parse acl entry type */ SKIP_WS(*text_p); switch (**text_p) { case 'u': /* user */ if (!skip_tag_name(text_p, "user")) goto fail; backup = *text_p; str = get_token(text_p); if (str) { entry_obj.etag = ACL_USER; error = get_uid(unquote(str), &entry_obj.eid.qid); free(str); if (error) { *text_p = backup; return -1; } } else { entry_obj.etag = ACL_USER_OBJ; } break; case 'g': /* group */ if (!skip_tag_name(text_p, "group")) goto fail; backup = *text_p; str = get_token(text_p); if (str) { entry_obj.etag = ACL_GROUP; error = get_gid(unquote(str), &entry_obj.eid.qid); free(str); if (error) { *text_p = backup; return -1; } } else { entry_obj.etag = ACL_GROUP_OBJ; } break; case 'm': /* mask */ if (!skip_tag_name(text_p, "mask")) goto fail; /* skip empty entry qualifier field (this field may be missing for compatibility with Solaris.) */ SKIP_WS(*text_p); if (**text_p == ':') (*text_p)++; entry_obj.etag = ACL_MASK; break; case 'o': /* other */ if (!skip_tag_name(text_p, "other")) goto fail; /* skip empty entry qualifier field (this field may be missing for compatibility with Solaris.) */ SKIP_WS(*text_p); if (**text_p == ':') (*text_p)++; entry_obj.etag = ACL_OTHER; break; default: goto fail; } for (perm_chars=0; perm_chars<3; perm_chars++, (*text_p)++) { switch(**text_p) { case 'r': if (entry_obj.eperm.sperm & ACL_READ) goto fail; entry_obj.eperm.sperm |= ACL_READ; break; case 'w': if (entry_obj.eperm.sperm & ACL_WRITE) goto fail; entry_obj.eperm.sperm |= ACL_WRITE; break; case 'x': if (entry_obj.eperm.sperm & ACL_EXECUTE) goto fail; entry_obj.eperm.sperm |= ACL_EXECUTE; break; case '-': /* ignore */ break; default: if (perm_chars == 0) goto fail; goto create_entry; } } create_entry: if (acl_create_entry(acl_p, &entry_d) != 0) return -1; if (acl_copy_entry(entry_d, int2ext(&entry_obj)) != 0) return -1; return 0; fail: errno = EINVAL; return -1; }
int parse_response (struct content *resp_content, struct response *resp) { char *p = resp_content->body; char *body = resp_content->body; /* The response should begin with HTTP/\d.\d \d\d\d, that is, HTTP version and status code */ if (strncmp (p, "HTTP", 4) != 0) { fprintf (stderr, "Protocol does not appear to be HTTP\n"); return -1; } resp->protocol = xstrdup ("HTTP"); p += 4; if (p[0] != '/' || !IS_DIGIT(p[1]) || p[2] != '.' || !IS_DIGIT(p[3])) { fprintf (stderr, "HTTP Version not found\n"); return -1; } p += 4; SKIP_WS(p); /* Get the status code */ if (!IS_DIGIT(p[0]) || !IS_DIGIT(p[1]) || !IS_DIGIT(p[2])) { fprintf (stderr, "Couldn't find the status code in the response body\n"); return -1; } resp->status = 100 * (p[0] - '0') + 10 * (p[1] - '0') + p[2] - '0'; fprintf (stderr, "Server returned status %d\n", resp->status); /* Find the next line. This is where the headers should begin */ resp->headers = hash_table_new (31); /* Make sure we are not at the end of the header */ while ((p = strstr (p, "\r\n"))) { char *name, *name_end; char *value, *value_end; if (strstr (p + 2, "\r\n") == p + 2) { p += 4; break; } p = p + 2; name_end = strchr (p, ':'); name = malloc (name_end - p + 1); strncpy (name, p, name_end - p); p = name_end + 2; value_end = strstr (p, "\r\n"); value = malloc (value_end - p + 1); strncpy (value, p, value_end - p); hash_table_put (resp->headers, name, value); } resp->header_body = calloc (1, p - body + 1); strncpy (resp->header_body, body, p - body); destroy_content (resp_content); return 0; }
static int ConfigParseFile(TCHAR* pszFilename) { #define INSIDE_NOTHING (0xFFFF & (1 << ((sizeof(TCHAR) * 8) - 1))) TCHAR szLine[1024]; TCHAR* s; TCHAR* t; int nLen; int nLine = 0; TCHAR nInside = INSIDE_NOTHING; CheatInfo* pCurrentCheat = NULL; FILE* h = _tfopen(pszFilename, _T("rt")); if (h == NULL) { return 1; } while (1) { if (_fgetts(szLine, sizeof(szLine), h) == NULL) { break; } nLine++; nLen = _tcslen(szLine); // Get rid of the linefeed at the end while (szLine[nLen - 1] == 0x0A || szLine[nLen - 1] == 0x0D) { szLine[nLen - 1] = 0; nLen--; } s = szLine; // Start parsing if (s[0] == _T('/') && s[1] == _T('/')) { // Comment continue; } if ((t = LabelCheck(s, _T("include"))) != 0) { // Include a file s = t; TCHAR szFilename[MAX_PATH] = _T(""); // Read name of the cheat file TCHAR* szQuote = NULL; QuoteRead(&szQuote, NULL, s); _stprintf(szFilename, _T("%s%s.dat"), szAppCheatsPath, szQuote); if (ConfigParseFile(szFilename)) { _stprintf(szFilename, _T("%s%s.ini"), szAppCheatsPath, szQuote); if (ConfigParseFile(szFilename)) { CheatError(pszFilename, nLine, NULL, _T("included file doesn't exist"), szLine); } } continue; } if ((t = LabelCheck(s, _T("cheat"))) != 0) { // Add new cheat s = t; // Read cheat name TCHAR* szQuote = NULL; TCHAR* szEnd = NULL; QuoteRead(&szQuote, &szEnd, s); s = szEnd; if ((t = LabelCheck(s, _T("advanced"))) != 0) { // Advanced cheat s = t; } SKIP_WS(s); if (nInside == _T('{')) { CheatError(pszFilename, nLine, pCurrentCheat, _T("missing closing bracket"), NULL); break; } #if 0 if (*s != _T('\0') && *s != _T('{')) { CheatError(pszFilename, nLine, NULL, _T("malformed cheat declaration"), szLine); break; } #endif nInside = *s; // Link new node into the list CheatInfo* pPreviousCheat = pCurrentCheat; pCurrentCheat = (CheatInfo*)malloc(sizeof(CheatInfo)); if (pCheatInfo == NULL) { pCheatInfo = pCurrentCheat; } memset(pCurrentCheat, 0, sizeof(CheatInfo)); pCurrentCheat->pPrevious = pPreviousCheat; if (pPreviousCheat) { pPreviousCheat->pNext = pCurrentCheat; } // Fill in defaults pCurrentCheat->nType = 0; // Default to cheat type 0 (apply each frame) pCurrentCheat->nStatus = -1; // Disable cheat memcpy(pCurrentCheat->szCheatName, szQuote, QUOTE_MAX); continue; } if ((t = LabelCheck(s, _T("type"))) != 0) { // Cheat type if (nInside == INSIDE_NOTHING || pCurrentCheat == NULL) { CheatError(pszFilename, nLine, pCurrentCheat, _T("rogue cheat type"), szLine); break; } s = t; // Set type pCurrentCheat->nType = _tcstol(s, NULL, 0); continue; } if ((t = LabelCheck(s, _T("default"))) != 0) { // Default option if (nInside == INSIDE_NOTHING || pCurrentCheat == NULL) { CheatError(pszFilename, nLine, pCurrentCheat, _T("rogue default"), szLine); break; } s = t; // Set default option pCurrentCheat->nDefault = _tcstol(s, NULL, 0); continue; } int n = _tcstol(s, &t, 0); if (t != s) { // New option if (nInside == INSIDE_NOTHING || pCurrentCheat == NULL) { CheatError(pszFilename, nLine, pCurrentCheat, _T("rogue option"), szLine); break; } // Link a new Option structure to the cheat if (n < CHEAT_MAX_OPTIONS) { s = t; // Read option name TCHAR* szQuote = NULL; TCHAR* szEnd = NULL; if (QuoteRead(&szQuote, &szEnd, s)) { CheatError(pszFilename, nLine, pCurrentCheat, _T("option name omitted"), szLine); break; } s = szEnd; if (pCurrentCheat->pOption[n] == NULL) { pCurrentCheat->pOption[n] = (CheatOption*)malloc(sizeof(CheatOption)); } memset(pCurrentCheat->pOption[n], 0, sizeof(CheatOption)); memcpy(pCurrentCheat->pOption[n]->szOptionName, szQuote, QUOTE_MAX * sizeof(TCHAR)); int nCurrentAddress = 0; bool bOK = true; while (nCurrentAddress < CHEAT_MAX_ADDRESS) { int nCPU = 0, nAddress = 0, nValue = 0; if (SkipComma(&s)) { nCPU = _tcstol(s, &t, 0); // CPU number if (t == s) { CheatError(pszFilename, nLine, pCurrentCheat, _T("CPU number omitted"), szLine); bOK = false; break; } s = t; SkipComma(&s); nAddress = _tcstol(s, &t, 0); // Address if (t == s) { bOK = false; CheatError(pszFilename, nLine, pCurrentCheat, _T("address omitted"), szLine); break; } s = t; SkipComma(&s); nValue = _tcstol(s, &t, 0); // Value if (t == s) { bOK = false; CheatError(pszFilename, nLine, pCurrentCheat, _T("value omitted"), szLine); break; } } else { if (nCurrentAddress) { // Only the first option is allowed no address break; } if (n) { bOK = false; CheatError(pszFilename, nLine, pCurrentCheat, _T("CPU / address / value omitted"), szLine); break; } } pCurrentCheat->pOption[n]->AddressInfo[nCurrentAddress].nCPU = nCPU; pCurrentCheat->pOption[n]->AddressInfo[nCurrentAddress].nAddress = nAddress; pCurrentCheat->pOption[n]->AddressInfo[nCurrentAddress].nValue = nValue; nCurrentAddress++; } if (!bOK) { break; } } continue; } SKIP_WS(s); if (*s == _T('}')) { if (nInside != _T('{')) { CheatError(pszFilename, nLine, pCurrentCheat, _T("missing opening bracket"), NULL); break; } nInside = INSIDE_NOTHING; } // Line isn't (part of) a valid cheat #if 0 if (*s) { CheatError(pszFilename, nLine, NULL, _T("rogue line"), szLine); break; } #endif } if (h) { fclose(h); } return 0; }