static const char *json_root(ACL_JSON *json, const char *data) { SKIP_WHILE(*data != '{' && *data != '[', data); if (*data == 0) return data; if (*data == '{') { json->root->left_ch = '{'; json->root->right_ch = '}'; json->status = ACL_JSON_S_MEMBER; json->root->type = ACL_JSON_T_OBJ; } else { json->root->left_ch = '['; json->root->right_ch = ']'; json->status = ACL_JSON_S_ELEMENT; json->root->type = ACL_JSON_T_ARRAY; } data++; json->curr_node = json->root; json->depth = json->depth; return data; }
static const char *xml_parse_next_left_lt(ACL_XML2 *xml, const char *data) { SKIP_SPACE(data); SKIP_WHILE(*data != '<', data); if (*data == 0) return data; data++; xml->curr_node->status = ACL_XML2_S_LLT; return data; }
const string& query::to_string() { if (params_.empty()) return sql_; if (sql_buf_ == NULL) sql_buf_ = NEW string(sql_.length() + 32); else sql_buf_->clear(); #define SKIP_WHILE(cond, ptr) { while(*ptr && (cond)) ptr++; } char last_ch; char* src = sql_.c_str(), *ptr, *key; while (*src != 0) { ptr = strchr(src, ':'); if (ptr == NULL) { sql_buf_->append(src); break; } else if (*++ptr == 0) { sql_buf_->append(src); logger_warn("the last char is ':'"); break; } sql_buf_->append(src, ptr - src - 1); key = ptr; SKIP_WHILE(*ptr != ',' && *ptr != ';' && *ptr != ' ' && *ptr != '\t' && *ptr != '(' && *ptr != ')' && *ptr != '\r' && *ptr != '\n', ptr); if (ptr - key == 1) { logger_warn("only found: ':%c'", *ptr); sql_buf_->append(key, ptr - key + 1); src = ptr + 2; continue; } last_ch = *ptr; *ptr = 0; (void) append_key(*sql_buf_, key); *ptr = last_ch; if (last_ch == '\0') break; src = ptr; } return *sql_buf_; }
static const char *xml_parse_attr(ACL_XML *xml, const char *data) { int ch; ACL_XML_ATTR *attr = xml->curr_node->curr_attr; if (attr == NULL || LEN(attr->name) == 0) { SKIP_SPACE(data); /* 略过 ' ', '\t' */ if (*data == 0) return (NULL); SKIP_WHILE(*data == '=', data); if (*data == 0) return (NULL); } if (*data == '>') { xml->curr_node->status = ACL_XML_S_LGT; xml_parse_check_self_closed(xml); xml->curr_node->curr_attr = NULL; data++; return (data); } xml->curr_node->last_ch = *data; if (*data == '/') { data++; return (data); } if (attr == NULL) { attr = acl_xml_attr_alloc(xml->curr_node); xml->curr_node->curr_attr = attr; } while ((ch = *data) != 0) { xml->curr_node->last_ch = ch; if (ch == '=') { xml->curr_node->status = ACL_XML_S_AVAL; data++; break; } if (!IS_SPACE(ch)) ACL_VSTRING_ADDCH(attr->name, ch); data++; } ACL_VSTRING_TERMINATE(attr->name); return (data); }
static const char *json_root(ACL_JSON *json, const char *data) { SKIP_WHILE(*data != '{', data); if (*data == 0) return NULL; data++; json->root->left_ch = '{'; json->root->right_ch = '}'; json->status = ACL_JSON_S_MEMBER; json->curr_node = json->root; json->root->type = ACL_JSON_T_OBJ; json->depth = json->depth; return data; }
bool HttpCookie::splitNameValue(char* data, HTTP_PARAM* param) { #define SKIP_SPECIAL(x) { while (*(x) == ' ' || *(x) == '\t' || *(x) == '=') (x)++; } #define SKIP_WHILE(cond, x) { while(*(x) && (cond)) (x)++; } // 开始解析过程 param->name = data; // 去掉开头无用的特殊字符 SKIP_SPECIAL(param->name); if (*(param->name) == 0) return false; // 找到 '=' param->value = param->name; SKIP_WHILE(*(param->value) != '=', param->value); if (*(param->value) != '=') return false; // 去掉 '=' 前面的空格 char* ptr = param->value - 1; *param->value++ = 0; while (ptr > param->name && (*ptr == ' ' || *ptr == '\t')) *ptr-- = 0; // 去掉 value 开始的无效字符 SKIP_SPECIAL(param->value); // 找到 value 值的结束位置 // 允许 value = "\0" ptr = param->value + strlen(param->value) - 1; while (ptr >= param->value && (*ptr == ' ' || *ptr == '\t')) *ptr-- = 0; return true; }
static const char *xml_parse_attr(ACL_XML2 *xml, const char *data) { int ch; ACL_XML2_ATTR *attr = xml->curr_node->curr_attr; if (attr == NULL || attr->name == xml->addr) { SKIP_SPACE(data); SKIP_WHILE(*data == '=', data); } if (*data == 0) return data; if (*data == '>') { xml_parse_check_self_closed(xml); if ((xml->curr_node->flag & ACL_XML2_F_SELF_CL) && xml->curr_node->last_ch == '/') { xml->curr_node->status = ACL_XML2_S_RGT; } else xml->curr_node->status = ACL_XML2_S_LGT; xml->curr_node->curr_attr = NULL; if (xml->len < MIN_LEN) return data; data++; xml->len--; *xml->ptr++ = 0; return data; } xml->curr_node->last_ch = *data; if (*data == '/') { data++; /* 此处返回后会触发本函数再次被调用,当下一个字节为 '>' 时, * 上面通过调用 xml_parse_check_self_closed 检查是否为自封闭 * 标签: "/>" */ return data; } if (attr == NULL) { attr = acl_xml2_attr_alloc(xml->curr_node); xml->curr_node->curr_attr = attr; attr->name = xml->ptr; } while ((ch = *data) != 0) { xml->curr_node->last_ch = ch; if (ch == '=') { if (xml->len < MIN_LEN) return data; data++; xml->len--; attr->name_size = xml->ptr - attr->name; *xml->ptr++ = 0; xml->curr_node->status = ACL_XML2_S_AVAL; break; } if (!IS_SPACE(ch)) { if (xml->len < MIN_LEN) return data; xml->len--; *xml->ptr++ = ch; } data++; } return data; }
int make_dirs(const char *path, int perms) { char *saved_path; unsigned char *cp; int saved_ch; struct stat st; int ret; mode_t saved_mode = 0; /* * Initialize. Make a copy of the path that we can safely clobber. */ cp = (unsigned char *) (saved_path = mystrdup(path)); /* * I didn't like the 4.4BSD "mkdir -p" implementation, but coming up with * my own took a day, spread out over several days. */ #define SKIP_WHILE(cond, ptr) { while(*ptr && (cond)) ptr++; } SKIP_WHILE(*cp == '/', cp); for (;;) { SKIP_WHILE(*cp != '/', cp); if ((saved_ch = *cp) != 0) *cp = 0; if ((ret = stat(saved_path, &st)) >= 0) { if (!S_ISDIR(st.st_mode)) { errno = ENOTDIR; ret = -1; break; } saved_mode = st.st_mode; } else { if (errno != ENOENT) break; /* * mkdir(foo) fails with EEXIST if foo is a symlink. */ #if 0 /* * Create a new directory. Unfortunately, mkdir(2) has no * equivalent of open(2)'s O_CREAT|O_EXCL safety net, so we must * require that the parent directory is not world writable. * Detecting a lost race condition after the fact is not * sufficient, as an attacker could repeat the attack and add one * directory level at a time. */ if (saved_mode & S_IWOTH) { msg_warn("refusing to mkdir %s: parent directory is writable by everyone", saved_path); errno = EPERM; ret = -1; break; } #endif if ((ret = mkdir(saved_path, perms)) < 0) { if (errno != EEXIST) break; /* Race condition? */ if ((ret = stat(saved_path, &st)) < 0) break; if (!S_ISDIR(st.st_mode)) { errno = ENOTDIR; ret = -1; break; } } } if (saved_ch != 0) *cp = saved_ch; SKIP_WHILE(*cp == '/', cp); if (*cp == 0) break; } /* * Cleanup. */ myfree(saved_path); return (ret); }
int acl_make_dirs(const char *path, int perms) { const char *myname = "acl_make_dirs"; char *saved_path; unsigned char *cp; int saved_ch; struct stat st; int ret; /* * Initialize. Make a copy of the path that we can safely clobber. */ cp = (unsigned char *) (saved_path = acl_mystrdup(path)); if ((*cp >= 'a' && *cp <='z') || (*cp >= 'A' && *cp <= 'Z')) { if (*(cp + 1) == ':' && *(cp + 2) == '\\') { char buf[4]; buf[0] = *cp++; /* 'a-z' | 'A-Z' */ buf[1] = *cp++; /* ':' */ buf[2] = *cp++; /* '\\' */ buf[3] = 0; if (stat(buf, &st) < 0) { acl_msg_error("%s(%d): %s not exist(%s)", myname, __LINE__, strerror(errno)); return (-1); } } } if (*cp == 0) return (0); /* * I didn't like the 4.4BSD "mkdir -p" implementation, but coming up * with my own took a day, spread out over several days. */ #define SKIP_WHILE(cond, ptr) { while(*ptr && (cond)) ptr++; } SKIP_WHILE(*cp == '/' || *cp == '\\', cp); for (;;) { SKIP_WHILE(*cp != '/' && *cp != '\\', cp); if ((saved_ch = *cp) != 0) *cp = 0; if ((ret = stat(saved_path, &st)) >= 0) { if (!S_ISDIR(st.st_mode)) { errno = ENOTDIR; acl_set_error(ERROR_PATH_NOT_FOUND); ret = -1; break; } } else { if (errno != ENOENT) break; /*if ((ret = mkdir(saved_path)) < 0) {*/ if (!CreateDirectory(saved_path, NULL)) { int error = acl_last_error(); if (error != ERROR_ALREADY_EXISTS) break; /* Race condition? */ if ((ret = stat(saved_path, &st)) < 0) break; if (!S_ISDIR(st.st_mode)) { acl_set_error(ENOTDIR); ret = -1; break; } } } if (saved_ch != 0) *cp = saved_ch; SKIP_WHILE(*cp == '/' || *cp == '\\', cp); if (*cp == 0) break; } /* * Cleanup. */ acl_myfree(saved_path); return (ret); }
/* 分析配置文件中的第四个参数, 将其进行分解并存入动态数组之中 */ ACL_ARRAY *aut_parse_args_list(const char *str_in) { const char *myname = "aut_parse_args_list"; ACL_ARRAY *argvs_array = NULL; AUT_ARG_ITEM *arg_item = NULL; char *ptr_item, *pstr, *pstr_saved, *pname, *pvalue; char *ptr; int len; char tbuf[256]; argvs_array = acl_array_create(10); pstr = acl_mystrdup(str_in); pstr_saved = pstr; #define SKIP_WHILE(_cond, _ptr) { while (*_ptr && (_cond)) _ptr++; } #define SKIP_WHILE_DEC(_cond, _ptr) { while (*_ptr && (_cond)) _ptr--; } len = strlen("="); while (1) { /* 找到每一参数项, 分隔符为逗号 */ ptr_item = acl_mystrtok(&pstr, ","); if (ptr_item == NULL) break; /* 删除变量名前的空格和 tab */ SKIP_WHILE((*ptr_item == ' ' || *ptr_item == '\t'), ptr_item); pname = ptr_item; /* 先找到等于号分隔符 */ pvalue = strstr(ptr_item, "="); if (pvalue == NULL) /* not found '=' */ continue; ptr = pvalue; /* 删除等号左边的空格或 tab */ SKIP_WHILE_DEC((*ptr == ' ' || *ptr == '\t'), ptr); if (ptr < pvalue) *(++ptr) = 0; *pvalue = 0; pvalue += len; /* skip '=' */ /* 删除等号右边的空格和ab */ SKIP_WHILE((*pvalue == ' ' || *pvalue == '\t'), pvalue); if (*pvalue == 0) continue; /* 分配一个参数项 */ arg_item = (AUT_ARG_ITEM *) acl_mycalloc(1, sizeof(AUT_ARG_ITEM)); arg_item->name = acl_mystrdup(pname); arg_item->value = acl_mystrdup(pvalue); /* 把该参数项加入到动态数组之中 */ if (acl_array_append(argvs_array, (void *) arg_item) < 0) aut_log_fatal("%s(%d): append to array error(%s)", myname, __LINE__, acl_last_strerror(tbuf, sizeof(tbuf))); } acl_myfree(pstr_saved); return (argvs_array); }