/* utility: strips trailing non-alnum chars from string */ static char *trim_str(char *str) { int i; while(*str && !valid_char(*str)) str++; for(i = strlen(str); i-- && !valid_char(str[i]);) { str[i] = 0; } return str; }
bool valid_phone_utf16le(const sbuf_t& sbuf, size_t pos, size_t len) { // We want invalid characters before and after (assuming there is a // before and after) bool invalid_before = false; bool invalid_after = false; if (pos > 16) { for (size_t i = pos-16; i < pos; ++i) { if (sbuf[i] != '\0' && !valid_char(sbuf[i])) { invalid_before = true; break; } } } else { invalid_before = true; } if (sbuf.bufsize < pos+len+16) { for (size_t i = pos+len; i < pos+len+16; ++i) { if (sbuf[i] != '\0' && !valid_char(sbuf[i])) { invalid_after = true; break; } } } else { invalid_after = true; } /* * 2013-05-28: if followed by ' #{1,5} ' then it's not a phone either! */ if (pos+len+10 < sbuf.bufsize) { if (sbuf[pos+len] == ' ' && sbuf[pos+len+1] == '\0' && isdigit(sbuf[pos+len+2]) && sbuf[pos+len+3] == '\0') { for (size_t i = pos+len+2; i+3 < sbuf.bufsize && i < pos+len+16; i += 2) { if (isdigit(sbuf[i]) && sbuf[i+1] == '\0' && sbuf[i+2] == ' ' && sbuf[i+3] == '\0') { return false; // not valid } } } } /* If it is followed by a dash and a number, it's not a phone number */ if (pos+len+4 < sbuf.bufsize) { if (sbuf[pos+len] == '-' && sbuf[pos+len+1] == '\0' && isdigit(sbuf[pos+len+2] && sbuf[pos+len+3] == '\0')) { return false; } } return invalid_before && invalid_after; }
static bool valid_new_order_single(fix_group* const group, const new_order_single* const order) { return valid_string(group, Account, fix_string_from_c_string(order->Account)) && valid_string(group, ClOrdID, fix_string_from_c_string(order->ClOrdID)) && valid_timestamp(group, TransactTime, &order->TransactTime) && valid_char(group, HandlInst, order->HandlInst) && valid_char(group, OrdType, order->OrdType) && valid_char(group, Side, order->Side) && valid_char(group, TimeInForce, order->TimeInForce) && valid_double(group, Price, order->Price); }
ParserNode* ParserWorkerHex::parse() { FileHandler->advance_whitespace(); int snapshot_begin = FileHandler->create_snapshot(); int c = FileHandler->getc(); if(c != '0') { FileHandler->restore_snapshot(snapshot_begin); return NULL; } c = FileHandler->getc(); if(c != 'x') { FileHandler->restore_snapshot(snapshot_begin); return NULL; } c = FileHandler->nextc(); if(!valid_char(c)) { FileHandler->set_error("Invalid hex digit at line %d, column %d",FileHandler->get_current_line(),FileHandler->get_current_line_nchar()); return NULL; } int num = get_num(); return new ParserNodeNum(num); }
/* * Snapshot names must be made up of alphanumeric characters plus the following * characters: * * [-_.:] */ int snapshot_namecheck(const char *path, namecheck_err_t *why, char *what) { const char *loc; if (strlen(path) >= MAXNAMELEN) { if (why) *why = NAME_ERR_TOOLONG; return (-1); } if (path[0] == '\0') { if (why) *why = NAME_ERR_EMPTY_COMPONENT; return (-1); } for (loc = path; *loc; loc++) { if (!valid_char(*loc)) { if (why) { *why = NAME_ERR_INVALCHAR; *what = *loc; } return (-1); } } return (0); }
int add_atm(Elan_t *elan, char *addr) { char *tmp; char *ch; int pos=0; ch = addr; assert(elan && addr); tmp = (char*)mem_alloc(COMP_NAME, ATM_ESA_LEN*2); if (!tmp) return -1; memset(tmp,0,ATM_ESA_LEN*2); while ((*ch)!='\0' && (*(ch+1))!='\0') { if (!valid_char(*ch)) { mem_free(COMP_NAME, tmp); return -1; } if (*(ch+1) == '.' || *(ch+1) == ':' || *(ch+1) == '-') { tmp[pos++] = '0'; tmp[pos++] = *ch; ch+=2; } else if (valid_char(*(ch+1))) { tmp[pos++] = *ch; tmp[pos++] = *(ch+1); ch+=2; } else { mem_free(COMP_NAME, tmp); return -1; } if (*ch == '.' || *ch == '-' || *ch == ':') ch++; } if ((*ch) != '\0' && *(ch+1) == '\0') { tmp[pos++] = '0'; tmp[pos++] = *ch; } if (pos<40) { mem_free(COMP_NAME, tmp); return -1; } elan->addresses[elan->no_addresses++] = tmp; return 0; }
// validators static bool valid_header(fix_group* const group, const header* const hdr) { return valid_string(group, SenderCompID, fix_string_from_c_string(hdr->SenderCompID)) && valid_string(group, TargetCompID, fix_string_from_c_string(hdr->TargetCompID)) && valid_long(group, MsgSeqNum, hdr->MsgSeqNum) && valid_timestamp(group, SendingTime, &hdr->SendingTime) && valid_char(group, PossDupFlag, hdr->PossDupFlag); }
static char * escape_byte_string (const char *str) { size_t len; int num_invalid, i; char *escaped_val, *p; unsigned char c; const char hex_digits[] = "0123456789abcdef"; len = strlen (str); num_invalid = 0; for (i = 0; i < len; i++) { if (!valid_char (str[i])) num_invalid++; } if (num_invalid == 0) return g_strdup (str); else { escaped_val = g_malloc (len + num_invalid*3 + 1); p = escaped_val; for (i = 0; i < len; i++) { c = str[i]; if (valid_char (c)) *p++ = c; else { *p++ = '\\'; *p++ = 'x'; *p++ = hex_digits[(c >> 4) & 0xf]; *p++ = hex_digits[c & 0xf]; } } *p++ = 0; return escaped_val; } }
/* * For pool names, we have the same set of valid characters as described in * dataset names, with the additional restriction that the pool name must begin * with a letter. The pool names 'raidz' and 'mirror' are also reserved names * that cannot be used. * * Returns 0 on success, -1 on error. */ int pool_namecheck(const char *pool, namecheck_err_t *why, char *what) { const char *c; /* * Make sure the name is not too long. * If we're creating a pool with version >= SPA_VERSION_DSL_SCRUB (v11) * we need to account for additional space needed by the origin ds which * will also be snapshotted: "poolname"+"/"+"$ORIGIN"+"@"+"$ORIGIN". * Play it safe and enforce this limit even if the pool version is < 11 * so it can be upgraded without issues. */ if (strlen(pool) >= (ZFS_MAX_DATASET_NAME_LEN - 2 - strlen(ORIGIN_DIR_NAME) * 2)) { if (why) *why = NAME_ERR_TOOLONG; return (-1); } c = pool; while (*c != '\0') { if (!valid_char(*c)) { if (why) { *why = NAME_ERR_INVALCHAR; *what = *c; } return (-1); } c++; } if (!(*pool >= 'a' && *pool <= 'z') && !(*pool >= 'A' && *pool <= 'Z')) { if (why) *why = NAME_ERR_NOLETTER; return (-1); } if (strcmp(pool, "mirror") == 0 || strcmp(pool, "raidz") == 0) { if (why) *why = NAME_ERR_RESERVED; return (-1); } if (pool[0] == 'c' && (pool[1] >= '0' && pool[1] <= '9')) { if (why) *why = NAME_ERR_DISKLIKE; return (-1); } return (0); }
/* * For pool names, we have the same set of valid characters as described in * dataset names, with the additional restriction that the pool name must begin * with a letter. The pool names 'raidz' and 'mirror' are also reserved names * that cannot be used. */ int pool_namecheck(const char *pool, namecheck_err_t *why, char *what) { const char *c; /* * Make sure the name is not too long. * * ZPOOL_MAXNAMELEN is the maximum pool length used in the userland * which is the same as MAXNAMELEN used in the kernel. * If ZPOOL_MAXNAMELEN value is changed, make sure to cleanup all * places using MAXNAMELEN. */ if (strlen(pool) >= MAXNAMELEN) { if (why) *why = NAME_ERR_TOOLONG; return (-1); } c = pool; while (*c != '\0') { if (!valid_char(*c)) { if (why) { *why = NAME_ERR_INVALCHAR; *what = *c; } return (-1); } c++; } if (!(*pool >= 'a' && *pool <= 'z') && !(*pool >= 'A' && *pool <= 'Z')) { if (why) *why = NAME_ERR_NOLETTER; return (-1); } if (strcmp(pool, "mirror") == 0 || strcmp(pool, "raidz") == 0) { if (why) *why = NAME_ERR_RESERVED; return (-1); } if (pool[0] == 'c' && (pool[1] >= '0' && pool[1] <= '9')) { if (why) *why = NAME_ERR_DISKLIKE; return (-1); } return (0); }
bool valid_phone(const sbuf_t &sbuf,size_t pos,size_t len) { /* We want invalid characters before and after (assuming there is a before and after */ int invalid_before = 0; int invalid_after = 0; if(pos>8){ for(size_t i=pos-8;i<pos;i++){ if(!valid_char(sbuf[i])) invalid_before = 1; } } else { invalid_before = 1; } if(sbuf.bufsize < pos+len+8){ for(size_t i=pos+len;i<pos+len+8;i++){ if(!valid_char(sbuf[i])) invalid_after = 1; } } else { invalid_after = 1; } /* * 2013-05-28: if followed by ' #{1,5} ' then it's not a phone either! */ if(pos+len+5 < sbuf.bufsize){ if(sbuf[pos+len]==' ' && isdigit(sbuf[pos+len+1])){ for(size_t i = pos+len+1 ; (i+1<sbuf.bufsize) && (i<pos+len+8);i++){ if(isdigit(sbuf[i]) && sbuf[i+1]==' ') return false; // not valid } } } /* If it is followed by a dash and a number, it's not a phone number */ if(pos+len+2 < sbuf.bufsize){ if(sbuf[pos+len]=='-' && isdigit(sbuf[pos+len+1])) return false; } return invalid_before!=0 && invalid_after!=0; }
unsigned char palindrome(char *word) { unsigned char i, j, n; n = strlen(word); for (i = 0; i < n; i++) if(!valid_char(word[i])) return 0; for (i = 0; i < n; i++) if(word[i] >= 'a') word[i] = word[i] - ' '; for (i = 0, j = n - 1; i <= j; i++, j--) if(word[i] != word[j]) return 0; return 1; }
/* * For pool names, we have the same set of valid characters as described in * dataset names, with the additional restriction that the pool name must begin * with a letter. The pool names 'raidz' and 'mirror' are also reserved names * that cannot be used. */ int pool_namecheck(const char *pool, namecheck_err_t *why, char *what) { const char *c; /* * Make sure the name is not too long. */ if (strlen(pool) >= ZFS_MAX_DATASET_NAME_LEN) { if (why) *why = NAME_ERR_TOOLONG; return (-1); } c = pool; while (*c != '\0') { if (!valid_char(*c)) { if (why) { *why = NAME_ERR_INVALCHAR; *what = *c; } return (-1); } c++; } if (!(*pool >= 'a' && *pool <= 'z') && !(*pool >= 'A' && *pool <= 'Z')) { if (why) *why = NAME_ERR_NOLETTER; return (-1); } if (strcmp(pool, "mirror") == 0 || strcmp(pool, "raidz") == 0) { if (why) *why = NAME_ERR_RESERVED; return (-1); } if (pool[0] == 'c' && (pool[1] >= '0' && pool[1] <= '9')) { if (why) *why = NAME_ERR_DISKLIKE; return (-1); } return (0); }
void find_key_values(unsigned char* buff, size_t buff_size, int key_size) { int i, n; unsigned int k; unsigned char plain_char; for (i = 0; i < key_size; i++) { canadites* canadate_list[256]; memset(canadate_list, 0, sizeof(canadate_list)); for (k = 0; k < 256; k++) { int e_count = 0; int a_count = 0; int byte_count = 0; bool valid = true; for (n = 0; (n * key_size) + i < buff_size; n++, byte_count++) { plain_char = buff[(n*key_size)+i] ^ k; if (!valid_char(plain_char)) { valid = false; break; } if (plain_char == 'e') { e_count++; } else if(plain_char == 'a') { a_count++; } } if (valid) { canadites * canadite = (canadites*) calloc(1, sizeof(canadites)); canadite->e_freq = (double)e_count/(double)byte_count; canadite->a_freq = (double)a_count/(double)byte_count; canadate_list[k] = canadite; } } for (k = 0; k < 256; k++) { if(canadate_list[k] != NULL) { printf("For Key index(%d) Canadate offset %02X for e freq %lf and a freq %lf\n",i, k, canadate_list[k]->e_freq, canadate_list[k]->a_freq); free(canadate_list[k]); } } } }
/* * Returns true if this is a valid user-defined property (one with a ':'). */ boolean_t zfs_prop_user(const char *name) { int i; char c; boolean_t foundsep = B_FALSE; for (i = 0; i < strlen(name); i++) { c = name[i]; if (!valid_char(c)) return (B_FALSE); if (c == ':') foundsep = B_TRUE; } if (!foundsep) return (B_FALSE); return (B_TRUE); }
/* * Every feature guid must contain exactly one colon which separates a reverse * dns organization name from the feature's "short" name (e.g. * "com.company:feature_name"). */ boolean_t zfeature_is_valid_guid(const char *name) { int i; boolean_t has_colon = B_FALSE; i = 0; while (name[i] != '\0') { char c = name[i++]; if (c == ':') { if (has_colon) return (B_FALSE); has_colon = B_TRUE; continue; } if (!valid_char(c, has_colon)) return (B_FALSE); } return (has_colon); }
/* * Dataset names must be of the following form: * * [component][/]*[component][@component] * * Where each component is made up of alphanumeric characters plus the following * characters: * * [-_.:%] * * We allow '%' here as we use that character internally to create unique * names for temporary clones (for online recv). */ int dataset_namecheck(const char *path, namecheck_err_t *why, char *what) { const char *loc, *end; int found_snapshot; /* * Make sure the name is not too long. * * ZFS_MAXNAMELEN is the maximum dataset length used in the userland * which is the same as MAXNAMELEN used in the kernel. * If ZFS_MAXNAMELEN value is changed, make sure to cleanup all * places using MAXNAMELEN. * * When HAVE_KOBJ_NAME_LEN is defined the maximum safe kobject name * length is 20 bytes. This 20 bytes is broken down as follows to * provide a maximum safe <pool>/<dataset>[@snapshot] length of only * 18 bytes. To ensure bytes are left for <dataset>[@snapshot] the * <pool> portition is futher limited to 9 bytes. For 2.6.27 and * newer kernels this limit is set to MAXNAMELEN. * * <pool>/<dataset> + <partition> + <newline> * (18) + (1) + (1) */ #ifdef HAVE_KOBJ_NAME_LEN if (strlen(path) > 18) { #else if (strlen(path) >= MAXNAMELEN) { #endif /* HAVE_KOBJ_NAME_LEN */ if (why) *why = NAME_ERR_TOOLONG; return (-1); } /* Explicitly check for a leading slash. */ if (path[0] == '/') { if (why) *why = NAME_ERR_LEADING_SLASH; return (-1); } if (path[0] == '\0') { if (why) *why = NAME_ERR_EMPTY_COMPONENT; return (-1); } loc = path; found_snapshot = 0; for (;;) { /* Find the end of this component */ end = loc; while (*end != '/' && *end != '@' && *end != '\0') end++; if (*end == '\0' && end[-1] == '/') { /* trailing slashes are not allowed */ if (why) *why = NAME_ERR_TRAILING_SLASH; return (-1); } /* Zero-length components are not allowed */ if (loc == end) { if (why) { /* * Make sure this is really a zero-length * component and not a '@@'. */ if (*end == '@' && found_snapshot) { *why = NAME_ERR_MULTIPLE_AT; } else { *why = NAME_ERR_EMPTY_COMPONENT; } } return (-1); } /* Validate the contents of this component */ while (loc != end) { if (!valid_char(*loc) && *loc != '%') { if (why) { *why = NAME_ERR_INVALCHAR; *what = *loc; } return (-1); } loc++; } /* If we've reached the end of the string, we're OK */ if (*end == '\0') return (0); if (*end == '@') { /* * If we've found an @ symbol, indicate that we're in * the snapshot component, and report a second '@' * character as an error. */ if (found_snapshot) { if (why) *why = NAME_ERR_MULTIPLE_AT; return (-1); } found_snapshot = 1; } /* * If there is a '/' in a snapshot name * then report an error */ if (*end == '/' && found_snapshot) { if (why) *why = NAME_ERR_TRAILING_SLASH; return (-1); } /* Update to the next component */ loc = end + 1; } } /* * mountpoint names must be of the following form: * * /[component][/]*[component][/] */ int mountpoint_namecheck(const char *path, namecheck_err_t *why) { const char *start, *end; /* * Make sure none of the mountpoint component names are too long. * If a component name is too long then the mkdir of the mountpoint * will fail but then the mountpoint property will be set to a value * that can never be mounted. Better to fail before setting the prop. * Extra slashes are OK, they will be tossed by the mountpoint mkdir. */ if (path == NULL || *path != '/') { if (why) *why = NAME_ERR_LEADING_SLASH; return (-1); } /* Skip leading slash */ start = &path[1]; do { end = start; while (*end != '/' && *end != '\0') end++; if (end - start >= MAXNAMELEN) { if (why) *why = NAME_ERR_TOOLONG; return (-1); } start = end + 1; } while (*end != '\0'); return (0); } /* * For pool names, we have the same set of valid characters as described in * dataset names, with the additional restriction that the pool name must begin * with a letter. The pool names 'raidz' and 'mirror' are also reserved names * that cannot be used. */ int pool_namecheck(const char *pool, namecheck_err_t *why, char *what) { const char *c; /* * Make sure the name is not too long. * * ZPOOL_MAXNAMELEN is the maximum pool length used in the userland * which is the same as MAXNAMELEN used in the kernel. * If ZPOOL_MAXNAMELEN value is changed, make sure to cleanup all * places using MAXNAMELEN. * * When HAVE_KOBJ_NAME_LEN is defined the maximum safe kobject name * length is 20 bytes. This 20 bytes is broken down as follows to * provide a maximum safe <pool>/<dataset>[@snapshot] length of only * 18 bytes. To ensure bytes are left for <dataset>[@snapshot] the * <pool> portition is futher limited to 8 bytes. For 2.6.27 and * newer kernels this limit is set to MAXNAMELEN. * * <pool>/<dataset> + <partition> + <newline> * (18) + (1) + (1) */ #ifdef HAVE_KOBJ_NAME_LEN if (strlen(pool) > 8) { #else if (strlen(pool) >= MAXNAMELEN) { #endif /* HAVE_KOBJ_NAME_LEN */ if (why) *why = NAME_ERR_TOOLONG; return (-1); } c = pool; while (*c != '\0') { if (!valid_char(*c)) { if (why) { *why = NAME_ERR_INVALCHAR; *what = *c; } return (-1); } c++; } if (!(*pool >= 'a' && *pool <= 'z') && !(*pool >= 'A' && *pool <= 'Z')) { if (why) *why = NAME_ERR_NOLETTER; return (-1); } if (strcmp(pool, "mirror") == 0 || strcmp(pool, "raidz") == 0) { if (why) *why = NAME_ERR_RESERVED; return (-1); } if (pool[0] == 'c' && (pool[1] >= '0' && pool[1] <= '9')) { if (why) *why = NAME_ERR_DISKLIKE; return (-1); } return (0); } #if defined(_KERNEL) && defined(HAVE_SPL) EXPORT_SYMBOL(pool_namecheck); EXPORT_SYMBOL(dataset_namecheck); EXPORT_SYMBOL(zfs_component_namecheck);
/* * Entity names must be of the following form: * * [component/]*[component][(@|#)component]? * * Where each component is made up of alphanumeric characters plus the following * characters: * * [-_.:%] * * We allow '%' here as we use that character internally to create unique * names for temporary clones (for online recv). */ int entity_namecheck(const char *path, namecheck_err_t *why, char *what) { const char *start, *end; int found_delim; /* * Make sure the name is not too long. */ if (strlen(path) >= ZFS_MAX_DATASET_NAME_LEN) { if (why) *why = NAME_ERR_TOOLONG; return (-1); } /* Explicitly check for a leading slash. */ if (path[0] == '/') { if (why) *why = NAME_ERR_LEADING_SLASH; return (-1); } if (path[0] == '\0') { if (why) *why = NAME_ERR_EMPTY_COMPONENT; return (-1); } start = path; found_delim = 0; for (;;) { /* Find the end of this component */ end = start; while (*end != '/' && *end != '@' && *end != '#' && *end != '\0') end++; if (*end == '\0' && end[-1] == '/') { /* trailing slashes are not allowed */ if (why) *why = NAME_ERR_TRAILING_SLASH; return (-1); } /* Validate the contents of this component */ for (const char *loc = start; loc != end; loc++) { if (!valid_char(*loc) && *loc != '%') { if (why) { *why = NAME_ERR_INVALCHAR; *what = *loc; } return (-1); } } /* Snapshot or bookmark delimiter found */ if (*end == '@' || *end == '#') { /* Multiple delimiters are not allowed */ if (found_delim != 0) { if (why) *why = NAME_ERR_MULTIPLE_DELIMITERS; return (-1); } found_delim = 1; } /* Zero-length components are not allowed */ if (start == end) { if (why) *why = NAME_ERR_EMPTY_COMPONENT; return (-1); } /* If we've reached the end of the string, we're OK */ if (*end == '\0') return (0); /* * If there is a '/' in a snapshot or bookmark name * then report an error */ if (*end == '/' && found_delim != 0) { if (why) *why = NAME_ERR_TRAILING_SLASH; return (-1); } /* Update to the next component */ start = end + 1; } }
int main(int argc, char **argv) { char program[PROGRAM_SIZE]; unsigned char program_data[DATA_SIZE]; char *filename; FILE *file = stdin; if(argc == 2) { filename = argv[1]; file = fopen(filename, "r"); } int i = 0; while(i < DATA_SIZE) { program_data[i++] = 0; } int idx = 0; int in; int comment = 0; while(1) { in = getc(file); if(in == EOF) { program[idx] = '&'; break; } else if(in == '\n') { comment = 0; } else if(in == '#') { comment = 1; } else if(!comment && valid_char(in)) { program[idx++] = in; } } //print_program_code(program); char *instruction_ptr = program; unsigned char *data_ptr = program_data; char cur_instruction; while(1) { cur_instruction = *instruction_ptr; if(cur_instruction == '>') { data_ptr++; } else if(cur_instruction == '<') { data_ptr--; } else if(cur_instruction == '+') { ++*data_ptr; } else if(cur_instruction == '-') { --*data_ptr; } else if(cur_instruction == '.') { putchar(*data_ptr); } else if(cur_instruction == ',') { *data_ptr = getchar(); } else if(cur_instruction == '[') { if(*data_ptr == 0) { // Find the matching closing brace instruction_ptr++; int opening_braces = 1; while(opening_braces) { if(*instruction_ptr == '[') { opening_braces++; } else if(*instruction_ptr == ']') { opening_braces--; } instruction_ptr++; } instruction_ptr--; } } else if(cur_instruction == ']') { if(*data_ptr != 0) { // Find the matching opening brace instruction_ptr--; int closing_braces = 1; while(closing_braces) { if(*instruction_ptr == '[') { closing_braces--; } else if(*instruction_ptr == ']') { closing_braces++; } instruction_ptr--; } // Command after the matching [ instruction_ptr++; } } else if(cur_instruction == '&') { break; } else { break; } instruction_ptr++; } return 0; }
/* * Dataset names must be of the following form: * * [component][/]*[component][@component] * * Where each component is made up of alphanumeric characters plus the following * characters: * * [-_.:%] * * We allow '%' here as we use that character internally to create unique * names for temporary clones (for online recv). */ int dataset_namecheck(const char *path, namecheck_err_t *why, char *what) { const char *loc, *end; int found_snapshot; /* * Make sure the name is not too long. * * ZFS_MAXNAMELEN is the maximum dataset length used in the userland * which is the same as MAXNAMELEN used in the kernel. * If ZFS_MAXNAMELEN value is changed, make sure to cleanup all * places using MAXNAMELEN. */ if (strlen(path) >= MAXNAMELEN) { if (why) *why = NAME_ERR_TOOLONG; return (-1); } /* Explicitly check for a leading slash. */ if (path[0] == '/') { if (why) *why = NAME_ERR_LEADING_SLASH; return (-1); } if (path[0] == '\0') { if (why) *why = NAME_ERR_EMPTY_COMPONENT; return (-1); } loc = path; found_snapshot = 0; for (;;) { /* Find the end of this component */ end = loc; while (*end != '/' && *end != '@' && *end != '\0') end++; if (*end == '\0' && end[-1] == '/') { /* trailing slashes are not allowed */ if (why) *why = NAME_ERR_TRAILING_SLASH; return (-1); } /* Zero-length components are not allowed */ if (loc == end) { if (why) { /* * Make sure this is really a zero-length * component and not a '@@'. */ if (*end == '@' && found_snapshot) { *why = NAME_ERR_MULTIPLE_AT; } else { *why = NAME_ERR_EMPTY_COMPONENT; } } return (-1); } /* Validate the contents of this component */ while (loc != end) { if (!valid_char(*loc) && *loc != '%') { if (why) { *why = NAME_ERR_INVALCHAR; *what = *loc; } return (-1); } loc++; } /* If we've reached the end of the string, we're OK */ if (*end == '\0') return (0); if (*end == '@') { /* * If we've found an @ symbol, indicate that we're in * the snapshot component, and report a second '@' * character as an error. */ if (found_snapshot) { if (why) *why = NAME_ERR_MULTIPLE_AT; return (-1); } found_snapshot = 1; } /* * If there is a '/' in a snapshot name * then report an error */ if (*end == '/' && found_snapshot) { if (why) *why = NAME_ERR_TRAILING_SLASH; return (-1); } /* Update to the next component */ loc = end + 1; } }