// // Configurators, and Register. // static const char* auth_url(cmd_parms* cmd, void* _conf, const char* param) { auth_conf* conf = _conf; if(ap_is_url(param)) { conf->url = apr_pstrdup(conf->pool, param); } else if(apr_isalpha(param[0])) { conf->url = apr_pstrdup(conf->pool, param); } else if(param[0]=='/') { conf->url = apr_psprintf(conf->pool, "localhost%s", param); } else { return "Bad string for request."; } return NULL; }
static apr_dbd_t *dbd_mysql_open(apr_pool_t *pool, const char *params, const char **error) { static const char *const delims = " \r\n\t;|,"; const char *ptr; int i; const char *key; size_t klen; const char *value; size_t vlen; #if MYSQL_VERSION_ID >= 50013 my_bool do_reconnect = 1; #endif MYSQL *real_conn; unsigned long flags = 0; struct { const char *field; const char *value; } fields[] = { {"host", NULL}, {"user", NULL}, {"pass", NULL}, {"dbname", NULL}, {"port", NULL}, {"sock", NULL}, {"flags", NULL}, {"fldsz", NULL}, {"group", NULL}, #if MYSQL_VERSION_ID >= 50013 {"reconnect", NULL}, {"connecttimeout", NULL}, {"readtimeout", NULL}, {"writetimeout", NULL}, #endif {NULL, NULL} }; unsigned int port = 0; #if MYSQL_VERSION_ID >= 50013 unsigned int timeout = 0; #endif apr_dbd_t *sql = apr_pcalloc(pool, sizeof(apr_dbd_t)); sql->fldsz = FIELDSIZE; sql->conn = mysql_init(sql->conn); if ( sql->conn == NULL ) { return NULL; } for (ptr = strchr(params, '='); ptr; ptr = strchr(ptr, '=')) { /* don't dereference memory that may not belong to us */ if (ptr == params) { ++ptr; continue; } for (key = ptr-1; apr_isspace(*key); --key); klen = 0; while (apr_isalpha(*key)) { /* don't parse backwards off the start of the string */ if (key == params) { --key; ++klen; break; } --key; ++klen; } ++key; for (value = ptr+1; apr_isspace(*value); ++value); vlen = strcspn(value, delims); for (i = 0; fields[i].field != NULL; i++) { if (!strncasecmp(fields[i].field, key, klen)) { fields[i].value = apr_pstrndup(pool, value, vlen); break; } } ptr = value+vlen; } if (fields[4].value != NULL) { port = atoi(fields[4].value); } if (fields[6].value != NULL && !strcmp(fields[6].value, "CLIENT_FOUND_ROWS")) { flags |= CLIENT_FOUND_ROWS; /* only option we know */ } if (fields[7].value != NULL) { sql->fldsz = atol(fields[7].value); } if (fields[8].value != NULL) { mysql_options(sql->conn, MYSQL_READ_DEFAULT_GROUP, fields[8].value); } #if MYSQL_VERSION_ID >= 50013 if (fields[9].value != NULL) { do_reconnect = atoi(fields[9].value) ? 1 : 0; } if (fields[10].value != NULL) { timeout = atoi(fields[10].value); mysql_options(sql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const void *)&timeout); } if (fields[11].value != NULL) { timeout = atoi(fields[11].value); mysql_options(sql->conn, MYSQL_OPT_READ_TIMEOUT, (const void *)&timeout); } if (fields[12].value != NULL) { timeout = atoi(fields[12].value); mysql_options(sql->conn, MYSQL_OPT_WRITE_TIMEOUT, (const void *)&timeout); } #endif #if MYSQL_VERSION_ID >= 50013 /* the MySQL manual says this should be BEFORE mysql_real_connect */ mysql_options(sql->conn, MYSQL_OPT_RECONNECT, &do_reconnect); #endif real_conn = mysql_real_connect(sql->conn, fields[0].value, fields[1].value, fields[2].value, fields[3].value, port, fields[5].value, flags); if(real_conn == NULL) { if (error) { *error = apr_pstrdup(pool, mysql_error(sql->conn)); } mysql_close(sql->conn); return NULL; } #if MYSQL_VERSION_ID >= 50013 /* Some say this should be AFTER mysql_real_connect */ mysql_options(sql->conn, MYSQL_OPT_RECONNECT, &do_reconnect); #endif return sql; }
APU_DECLARE(int) apr_dbd_prepare(const apr_dbd_driver_t *driver, apr_pool_t *pool, apr_dbd_t *handle, const char *query, const char *label, apr_dbd_prepared_t **statement) { size_t qlen; int i, nargs = 0, nvals = 0; char *p, *pq; const char *q; apr_dbd_type_e *t; if (!driver->pformat) { return APR_ENOTIMPL; } /* find the number of parameters in the query */ for (q = query; *q; q++) { if (q[0] == '%') { if (apr_isalpha(q[1])) { nargs++; } else if (q[1] == '%') { q++; } } } nvals = nargs; qlen = strlen(query) + nargs * (strlen(driver->pformat) + sizeof(nargs) * 3 + 2) + 1; pq = apr_palloc(pool, qlen); t = apr_pcalloc(pool, sizeof(*t) * nargs); for (p = pq, q = query, i = 0; *q; q++) { if (q[0] == '%') { if (apr_isalpha(q[1])) { switch (q[1]) { case 'd': t[i] = APR_DBD_TYPE_INT; break; case 'u': t[i] = APR_DBD_TYPE_UINT; break; case 'f': t[i] = APR_DBD_TYPE_FLOAT; break; case 'h': switch (q[2]) { case 'h': switch (q[3]){ case 'd': t[i] = APR_DBD_TYPE_TINY; q += 2; break; case 'u': t[i] = APR_DBD_TYPE_UTINY; q += 2; break; } break; case 'd': t[i] = APR_DBD_TYPE_SHORT; q++; break; case 'u': t[i] = APR_DBD_TYPE_USHORT; q++; break; } break; case 'l': switch (q[2]) { case 'l': switch (q[3]){ case 'd': t[i] = APR_DBD_TYPE_LONGLONG; q += 2; break; case 'u': t[i] = APR_DBD_TYPE_ULONGLONG; q += 2; break; } break; case 'd': t[i] = APR_DBD_TYPE_LONG; q++; break; case 'u': t[i] = APR_DBD_TYPE_ULONG; q++; break; case 'f': t[i] = APR_DBD_TYPE_DOUBLE; q++; break; } break; case 'p': if (q[2] == 'D') { switch (q[3]) { case 't': t[i] = APR_DBD_TYPE_TEXT; q += 2; break; case 'i': t[i] = APR_DBD_TYPE_TIME; q += 2; break; case 'd': t[i] = APR_DBD_TYPE_DATE; q += 2; break; case 'a': t[i] = APR_DBD_TYPE_DATETIME; q += 2; break; case 's': t[i] = APR_DBD_TYPE_TIMESTAMP; q += 2; break; case 'z': t[i] = APR_DBD_TYPE_ZTIMESTAMP; q += 2; break; case 'b': t[i] = APR_DBD_TYPE_BLOB; q += 2; break; case 'c': t[i] = APR_DBD_TYPE_CLOB; q += 2; break; case 'n': t[i] = APR_DBD_TYPE_NULL; q += 2; break; } } break; } q++; switch (t[i]) { case APR_DBD_TYPE_NONE: /* by default, we expect strings */ t[i] = APR_DBD_TYPE_STRING; break; case APR_DBD_TYPE_BLOB: case APR_DBD_TYPE_CLOB: /* three (3) more values passed in */ nvals += 3; break; default: break; } /* insert database specific parameter reference */ p += apr_snprintf(p, qlen - (p - pq), driver->pformat, ++i); } else if (q[1] == '%') { /* reduce %% to % */ *p++ = *q++; } else { *p++ = *q; } } else { *p++ = *q; } } *p = '\0'; return driver->prepare(pool,handle,pq,label,nargs,nvals,t,statement); }
/* * Convert a floating point number to a string formats 'f', 'e' or 'E'. * The result is placed in buf, and len denotes the length of the string * The sign is returned in the is_negative argument (and is not placed * in buf). */ static char *conv_fp(register char format, register double num, boolean_e add_dp, int precision, int *is_negative, char *buf, apr_size_t *len) { register char *s = buf; register char *p; int decimal_point; char buf1[NDIG]; if (format == 'f') p = apr_fcvt(num, precision, &decimal_point, is_negative, buf1); else /* either e or E format */ p = apr_ecvt(num, precision + 1, &decimal_point, is_negative, buf1); /* * Check for Infinity and NaN */ if (apr_isalpha(*p)) { *len = strlen(p); memcpy(buf, p, *len + 1); *is_negative = FALSE; return (buf); } if (format == 'f') { if (decimal_point <= 0) { *s++ = '0'; if (precision > 0) { *s++ = '.'; while (decimal_point++ < 0) *s++ = '0'; } else if (add_dp) *s++ = '.'; } else { while (decimal_point-- > 0) *s++ = *p++; if (precision > 0 || add_dp) *s++ = '.'; } } else { *s++ = *p++; if (precision > 0 || add_dp) *s++ = '.'; } /* * copy the rest of p, the NUL is NOT copied */ while (*p) *s++ = *p++; if (format != 'f') { char temp[EXPONENT_LENGTH]; /* for exponent conversion */ apr_size_t t_len; int exponent_is_negative; *s++ = format; /* either e or E */ decimal_point--; if (decimal_point != 0) { p = conv_10((apr_int32_t) decimal_point, FALSE, &exponent_is_negative, &temp[EXPONENT_LENGTH], &t_len); *s++ = exponent_is_negative ? '-' : '+'; /* * Make sure the exponent has at least 2 digits */ if (t_len == 1) *s++ = '0'; while (t_len--) *s++ = *p++; } else { *s++ = '+'; *s++ = '0'; *s++ = '0'; } } *len = s - buf; return (buf); }
/* * Scanner for variable constructs $xxx and ${xxx} */ static int DefineIndex(apr_pool_t *p, const char *pScope, char *cpLine, int *pos, int *len, char **cpVar) { int rc; char *cp; char *cp2; CharClass cc; char cEscape; char cDefine; char cBraceOpen; char cBraceClose; char *cpError; ScanState s; cEscape = DEFAULT_MC_ESCAPE[0]; if ((cp = DefineFetch(p, "mod_define", "escape")) != NULL) cEscape = cp[0]; cDefine = DEFAULT_MC_DOLLAR[0]; if ((cp = DefineFetch(p, "mod_define", "dollar")) != NULL) cDefine = cp[0]; cBraceOpen = DEFAULT_MC_BRACEOPEN[0]; if ((cp = DefineFetch(p, "mod_define", "braceopen")) != NULL) cBraceOpen = cp[0]; cBraceClose = DEFAULT_MC_BRACECLOSE[0]; if ((cp = DefineFetch(p, "mod_define", "braceclose")) != NULL) cBraceClose = cp[0]; rc = 0; *len = 0; cc = CC_OTHER; s = SS_NONE; for (cp = cpLine+(*pos); cc != CC_EOS; cp++) { if (*cp == cEscape) cc = CC_ESCAPE; else if (*cp == cDefine) cc = CC_DOLLAR; else if (*cp == cBraceOpen) cc = CC_BRACEOPEN; else if (*cp == cBraceClose) cc = CC_BRACECLOSE; else if (apr_isalpha(*cp)) cc = CC_IDCHAR1; else if (apr_isdigit(*cp) || *cp == '_' || *cp == ':' || *cp == '-') cc = CC_IDCHAR; else if (*cp == '\0') cc = CC_EOS; else cc = CC_OTHER; switch (s) { case SS_NONE: switch (cc) { case CC_ESCAPE: s = SS_SKIP; break; case CC_DOLLAR: s = SS_DOLLAR; break; default: break; } break; case SS_SKIP: s = SS_NONE; continue; break; case SS_DOLLAR: switch (cc) { case CC_BRACEOPEN: s = SS_TOKEN_BRACED; *pos = cp-cpLine-1; (*len) = 2; *cpVar = cp+1; break; case CC_IDCHAR1: s = SS_TOKEN_UNBRACED; *pos = cp-cpLine-1; (*len) = 2; *cpVar = cp; break; case CC_ESCAPE: s = SS_SKIP; break; default: s = SS_NONE; break; } break; case SS_TOKEN_BRACED: switch (cc) { case CC_IDCHAR1: case CC_IDCHAR: (*len)++; break; case CC_BRACECLOSE: (*len)++; cp2 = apr_palloc(p, cp-*cpVar+1); apr_cpystrn(cp2, *cpVar, cp-*cpVar+1); *cpVar = cp2; s = SS_FOUND; break; default: cpError = apr_psprintf(p, "Illegal character '%c' in identifier", *cp); s = SS_ERROR; break; } break; case SS_TOKEN_UNBRACED: switch (cc) { case CC_IDCHAR1: case CC_IDCHAR: (*len)++; break; default: cp2 = apr_palloc(p, cp-*cpVar+1); apr_cpystrn(cp2, *cpVar, cp-*cpVar+1); *cpVar = cp2; s = SS_FOUND; break; } break; case SS_FOUND: case SS_ERROR: break; } if (s == SS_ERROR) { fprintf(stderr, "Error: %s\n", cpError); break; } else if (s == SS_FOUND) { rc = 1; break; } } return rc; }
/* Parse one revision specification. Return pointer to character after revision, or NULL if the revision is invalid. Modifies str, so make sure to pass a copy of anything precious. Uses POOL for temporary allocation. */ static char *parse_one_rev(svn_opt_revision_t *revision, char *str, apr_pool_t *pool) { char *end, save; /* Allow any number of 'r's to prefix a revision number, because that way if a script pastes svn output into another svn command (like "svn log -r${REV_COPIED_FROM_OUTPUT}"), it'll Just Work, even when compounded. As it happens, none of our special revision words begins with "r". If any ever do, then this code will have to get smarter. Incidentally, this allows "r{DATE}". We could avoid that with some trivial code rearrangement, but it's not clear what would be gained by doing so. */ while (*str == 'r') str++; if (*str == '{') { svn_boolean_t matched; apr_time_t tm; svn_error_t *err; /* Brackets denote a date. */ str++; end = strchr(str, '}'); if (!end) return NULL; *end = '\0'; err = svn_parse_date(&matched, &tm, str, apr_time_now(), pool); if (err) { svn_error_clear(err); return NULL; } if (!matched) return NULL; revision->kind = svn_opt_revision_date; revision->value.date = tm; return end + 1; } else if (apr_isdigit(*str)) { /* It's a number. */ end = str + 1; while (apr_isdigit(*end)) end++; save = *end; *end = '\0'; revision->kind = svn_opt_revision_number; revision->value.number = SVN_STR_TO_REV(str); *end = save; return end; } else if (apr_isalpha(*str)) { end = str + 1; while (apr_isalpha(*end)) end++; save = *end; *end = '\0'; if (revision_from_word(revision, str) != 0) return NULL; *end = save; return end; } else return NULL; }
static DBPROCESS *freetds_open(apr_pool_t *pool, const char *params, const char **error) { char *server = NULL; DBPROCESS *process; LOGINREC *login; static const char *delims = " \r\n\t;|,"; char *ptr; char *key; char *value; int vlen; int klen; char *buf; char *databaseName = NULL; /* FIXME - this uses malloc */ /* FIXME - pass error message back to the caller in case of failure */ login = dblogin(); if (login == NULL) { return NULL; } /* now set login properties */ for (ptr = strchr(params, '='); ptr; ptr = strchr(ptr, '=')) { /* don't dereference memory that may not belong to us */ if (ptr == params) { ++ptr; continue; } for (key = ptr-1; apr_isspace(*key); --key); klen = 0; while (apr_isalpha(*key)) { --key; ++klen; } ++key; for (value = ptr+1; apr_isspace(*value); ++value); vlen = strcspn(value, delims); buf = apr_pstrndup(pool, value, vlen); /* NULL-terminated copy */ if (!strncasecmp(key, "username", klen)) { DBSETLUSER(login, buf); } else if (!strncasecmp(key, "password", klen)) { DBSETLPWD(login, buf); } else if (!strncasecmp(key, "appname", klen)) { DBSETLAPP(login, buf); } else if (!strncasecmp(key, "dbname", klen)) { databaseName = buf; } else if (!strncasecmp(key, "host", klen)) { DBSETLHOST(login, buf); } else if (!strncasecmp(key, "charset", klen)) { DBSETLCHARSET(login, buf); } else if (!strncasecmp(key, "lang", klen)) { DBSETLNATLANG(login, buf); } else if (!strncasecmp(key, "server", klen)) { server = buf; } else { /* unknown param */ } ptr = value+vlen; } process = dbopen(login, server); if (process != NULL && databaseName != NULL) { dbuse(process, databaseName); } dbloginfree(login); if (process == NULL) { return NULL; } return process; }