nsType rpmnsArch(const char * str) { nsType rc = RPMNS_TYPE_UNKNOWN; const char ** av; #if defined(RPM_VENDOR_WINDRIVER) const char * known_arch = rpmExpand("%{?_known_arch}", NULL); const char *p, *pe, *t; for (p = pe = known_arch ; rc == RPMNS_TYPE_UNKNOWN && pe && *pe ; ) { while (*p && xisspace(*p)) p++; pe = p ; while (*pe && !xisspace(*pe)) pe++; if (p == pe) break; t = strndup(p, (pe - p)); p = pe; if (!strcmp(str, t)) rc = RPMNS_TYPE_ARCH; t = _free(t); } known_arch = _free(known_arch); #endif if (rc == RPMNS_TYPE_UNKNOWN) for (av = rpmnsArches; *av != NULL; av++) { if (strcmp(str, *av)) continue; rc = RPMNS_TYPE_ARCH; break; } return rc; }
static int parseBits(const char * s, const tokenBits tokbits, /*@out@*/ rpmsenseFlags * bp) /*@modifies *bp @*/ { tokenBits tb; const char * se; rpmsenseFlags bits = RPMSENSE_ANY; int c = 0; if (s) { while (*s != '\0') { while ((c = *s) && xisspace(c)) s++; se = s; while ((c = *se) && xisalpha(c)) se++; if (s == se) break; for (tb = tokbits; tb->name; tb++) { if (tb->name != NULL && strlen(tb->name) == (size_t)(se-s) && !strncmp(tb->name, s, (se-s))) /*@innerbreak@*/ break; } if (tb->name == NULL) break; bits |= tb->bits; while ((c = *se) && xisspace(c)) se++; if (c != ',') break; s = ++se; } } if (c == 0 && bp) *bp = bits; return (c ? RPMRC_FAIL : RPMRC_OK); }
/* Build argv, argc from string passed from Windows. */ static void WIN32_build_argv(char *cmd) { int argvlen = 0; char *word; WIN32_argc = 1; WIN32_argv = (char **) xmalloc((WIN32_argc + 1) * sizeof(char *)); WIN32_argv[0] = xstrdup(WIN32_module_name); /* Scan command line until there is nothing left. */ while (*cmd) { /* Ignore spaces */ if (xisspace(*cmd)) { cmd++; continue; } /* Found the beginning of an argument. */ word = cmd; while (*cmd) { cmd++; /* Skip over this character */ if (xisspace(*cmd)) /* End of argument if space */ break; } if (*cmd) *cmd++ = '\0'; /* Terminate `word' */ /* See if we need to allocate more space for argv */ if (WIN32_argc >= argvlen) { argvlen = WIN32_argc + 1; WIN32_argv = (char **) xrealloc(WIN32_argv, (1 + argvlen) * sizeof(char *)); } /* Add word to argv file. */ WIN32_argv[WIN32_argc++] = word; } WIN32_argv[WIN32_argc] = NULL; }
/* look for name in chunk. returns RET_NOTHING if not found */ retvalue chunk_getvalue(const char *chunk, const char *name, char **value) { const char *field; char *val; const char *b, *e; assert(value != NULL); field = chunk_getfield(name, chunk); if (field == NULL) return RET_NOTHING; b = field; /* jump over spaces at the beginning */ while (*b != '\0' && (*b == ' ' || *b == '\t')) b++; /* search for the end */ e = b; while (*e != '\n' && *e != '\0') e++; /* remove trailing spaces */ while (e > b && xisspace(*e)) e--; if (!xisspace(*e)) val = strndup(b, e - b + 1); else val = strdup(""); if (FAILEDTOALLOC(val)) return RET_ERROR_OOM; *value = val; return RET_OK; }
void #line 366 "./cwebdir/ctang-w2c.ch" skip_limbo P1H(void) #line 1481 "./cwebdir/ctangle.w" { char c; while(1){ if(loc> limit&&get_line()==0)return; *(limit+1)= '@'; while(*loc!='@')loc++; if(loc++<=limit){ c= *loc++; if(ccode[(eight_bits)c]==new_section)break; switch(ccode[(eight_bits)c]){ case translit_code:/*93:*/ #line 1507 "./cwebdir/ctangle.w" while(xisspace(*loc)&&loc<limit)loc++; loc+= 3; if(loc> limit||!xisxdigit(*(loc-3))||!xisxdigit(*(loc-2)) ||(*(loc-3)>='0'&&*(loc-3)<='7')||!xisspace(*(loc-1))) err_print("! Improper hex number following @l"); else{ unsigned i; char*beg; sscanf(loc-3,"%x",&i); while(xisspace(*loc)&&loc<limit)loc++; beg= loc; while(loc<limit&&(xisalpha(*loc)||xisdigit(*loc)||*loc=='_'))loc++; if(loc-beg>=translit_length) err_print("! Replacement string in @l too long"); else{ strncpy(translit[i-0200],beg,loc-beg); translit[i-0200][loc-beg]= '\0'; } } /*:93*/ #line 1491 "./cwebdir/ctangle.w" ;break; case format_code:case'@':break; case control_text:if(c=='q'||c=='Q'){ while((c= skip_ahead())=='@'); if(*(loc-1)!='>') err_print("! Double @ should be used in control text"); break; } default:err_print("! Double @ should be used in limbo"); } } } }
/* Parse a package/source-field: ' *value( ?\(version\))? *' */ retvalue chunk_getname(const char *chunk, const char *name, char **pkgname, bool allowversion) { const char *field, *name_end, *p; field = chunk_getfield(name, chunk); if (field == NULL) return RET_NOTHING; while (*field != '\0' && *field != '\n' && xisspace(*field)) field++; name_end = field; /* this has now checked somewhere else for correctness and * is only a pure separation process: * (as package(version) is possible, '(' must be checked) */ while (*name_end != '\0' && *name_end != '\n' && *name_end != '(' && !xisspace(*name_end)) name_end++; p = name_end; while (*p != '\0' && *p != '\n' && xisspace(*p)) p++; if (name_end == field || (*p != '\0' && *p != '\n' && (!allowversion || *p != '('))) { if (*field == '\n' || *field == '\0') { fprintf(stderr, "Error: Field '%s' is empty!\n", name); } else { fprintf(stderr, "Error: Field '%s' contains unexpected character '%c'!\n", name, *p); } return RET_ERROR; } if (*p == '(') { while (*p != '\0' && *p != '\n' && *p != ')') // TODO: perhaps check for wellformed version p++; if (*p != ')') { fprintf(stderr, "Error: Field '%s' misses closing parenthesis!\n", name); return RET_ERROR; } p++; } while (*p != '\0' && *p != '\n' && xisspace(*p)) p++; if (*p != '\0' && *p != '\n') { fprintf(stderr, "Error: Field '%s' contains trailing junk starting with '%c'!\n", name, *p); return RET_ERROR; } *pkgname = strndup(field, name_end - field); if (FAILEDTOALLOC(*pkgname)) return RET_ERROR_OOM; return RET_OK; }
static retvalue parse_architectures(/*@out@*/struct atomlist *atoms, const char **pp, const struct filebeingparsed *fbp, int column) { const char *p = *pp; retvalue r; atomlist_init(atoms); do { const char *startp, *endp; atom_t atom; while (*p != '\0' && xisspace(*p)) p++; if (*p != '\'') { errorcol(fbp, column + (int)(p - *pp), "starting \"'\" expected!"); return RET_ERROR; } p++; startp = p; while (*p != '\0' && *p != '\'' && *p != '*' && *p != '?') p++; if (*p == '*' || *p == '?') { errorcol(fbp, column + (int)(p - *pp), "Wildcards are not allowed in architectures!"); return RET_ERROR; } if (*p == '\0') { errorcol(fbp, column + (int)(p - *pp), "closing \"'\" expected!"); return RET_ERROR; } assert (*p == '\''); endp = p; p++; atom = architecture_find_l(startp, endp - startp); if (!atom_defined(atom)) { errorcol(fbp, column + (int)(startp-*pp), "Unknown architecture '%.*s'! (Did you mistype?)", (int)(endp-startp), startp); return RET_ERROR; } r = atomlist_add_uniq(atoms, atom); if (RET_WAS_ERROR(r)) return r; while (*p != '\0' && xisspace(*p)) p++; column += (p - *pp); *pp = p; if (**pp == '|') { p++; } } while (**pp == '|'); *pp = p; return RET_OK; }
/* * returns a pointer to a field-value of the first matching field-name where * field-value matches prefix if any */ char * mime_get_header_field(const char *mime, const char *name, const char *prefix) { LOCAL_ARRAY(char, header, GET_HDR_SZ); const char *p = NULL; char *q = NULL; char got = 0; const int namelen = name ? strlen(name) : 0; const int preflen = prefix ? strlen(prefix) : 0; int l; if (NULL == mime) return NULL; assert(NULL != name); debug(25, 5) ("mime_get_header: looking for '%s'\n", name); for (p = mime; *p; p += strcspn(p, "\n\r")) { if (strcmp(p, "\r\n\r\n") == 0 || strcmp(p, "\n\n") == 0) return NULL; while (xisspace(*p)) p++; if (strncasecmp(p, name, namelen)) continue; if (!xisspace(p[namelen]) && p[namelen] != ':') continue; l = strcspn(p, "\n\r") + 1; if (l > GET_HDR_SZ) l = GET_HDR_SZ; xstrncpy(header, p, l); debug(25, 5) ("mime_get_header: checking '%s'\n", header); q = header; q += namelen; if (*q == ':') q++, got = 1; while (xisspace(*q)) q++, got = 1; if (got && prefix) { /* we could process list entries here if we had strcasestr(). */ /* make sure we did not match a part of another field-value */ got = !strncasecmp(q, prefix, preflen) && !xisalpha(q[preflen]); } if (got) { debug(25, 5) ("mime_get_header: returning '%s'\n", q); return q; } } return NULL; }
static void identReadReply(int fd, void *data) { IdentStateData *state = data; LOCAL_ARRAY(char, buf, BUFSIZ); char *ident = NULL; char *t = NULL; int len = -1; buf[0] = '\0'; statCounter.syscalls.sock.reads++; len = FD_READ_METHOD(fd, buf, BUFSIZ - 1); fd_bytes(fd, len, FD_READ); if (len <= 0) { comm_close(fd); return; } /* * XXX This isn't really very tolerant. It should read until EOL * or EOF and then decode the answer... If the reply is fragmented * then this will fail */ buf[len] = '\0'; if ((t = strchr(buf, '\r'))) *t = '\0'; if ((t = strchr(buf, '\n'))) *t = '\0'; debug(30, 5) ("identReadReply: FD %d: Read '%s'\n", fd, buf); if (strstr(buf, "USERID")) { if ((ident = strrchr(buf, ':'))) { while (xisspace(*++ident)); identCallback(state, ident); } } comm_close(fd); }
bool safe_strtoull(const char *str, uint64_t *out) { // [branch 008b] switch to safe asserts tm_assert(out != NULL); errno = 0; *out = 0; char *endptr; // [branch 009b] Switch to safe strtoull unsigned long long ull = tm_strtoull(str, &endptr, 10); if ((errno == ERANGE) || (str == endptr)) { return false; } if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) { if ((long long) ull < 0) { /* only check for negative signs in the uncommon case when * the unsigned number is so big that it's negative as a * signed number. */ // [branch 009b] Switch to safe strchr if (tm_strchr(str, '-') != NULL) { return false; } } *out = ull; return true; } return false; }
/* * iterates through a 0-terminated string of items separated by 'del's. * white space around 'del' is considered to be a part of 'del' * like strtok, but preserves the source, and can iterate several strings at once * * returns true if next item is found. * init pos with NULL to start iteration. */ int strListGetItem(const String * str, char del, const char **item, int *ilen, const char **pos) { size_t len; assert(str && item && pos); if (*pos) { if (!**pos) /* end of string */ return 0; else (*pos)++; } else { *pos = strBuf(*str); if (!*pos) return 0; } /* skip leading ws (ltrim) */ *pos += xcountws(*pos); *item = *pos; /* remember item's start */ /* find next delimiter */ *pos = strchr(*item, del); if (!*pos) /* last item */ *pos = *item + strlen(*item); len = *pos - *item; /* *pos points to del or '\0' */ /* rtrim */ while (len > 0 && xisspace((*item)[len - 1])) len--; if (ilen) *ilen = len; return len > 0; }
bool safe_strtoull(const char *begin, const char *end, uint64_t *out) { assert(out != NULL); errno = 0; *out = 0; char *endptr; unsigned long long ull = strtoull(begin, &endptr, 10); if ((errno == ERANGE) || (begin == endptr) || (endptr != end)) return false; if (xisspace(*endptr) || (*endptr == '\0' && endptr != begin) || endptr == end) { if ((long long) ull < 0) { /* only check for negative signs in the uncommon * case when the unsigned number is so big that * it's negative as a signed number. */ if (strchr(begin, '-') != NULL) return false; } *out = ull; return true; } return false; }
bool safe_strtoull(const char *str, uint64_t *out) { char *endptr; uint64_t ull; cb_assert(out != NULL); errno = 0; *out = 0; ull = strtoull(str, &endptr, 10); if (errno == ERANGE) { return false; } if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) { if ((int64_t)ull < 0) { /* only check for negative signs in the uncommon case when * the unsigned number is so big that it's negative as a * signed number. */ if (strchr(str, '-') != NULL) { return false; } } *out = ull; return true; } return false; }
bool safe_strtoul(const char *str, uint32_t *out) { char *endptr = NULL; unsigned long l = 0; assert(out); assert(str); *out = 0; errno = 0; l = strtoul(str, &endptr, 10); if (errno == ERANGE) { return false; } if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) { if ((long) l < 0) { /* only check for negative signs in the uncommon case when * the unsigned number is so big that it's negative as a * signed number. */ if (strchr(str, '-') != NULL) { return false; } } *out = l; return true; } return false; }
static retvalue parse_stringpart(/*@out@*/struct strlist *strings, const char **pp, const struct filebeingparsed *fbp, int column) { const char *p = *pp; retvalue r; strlist_init(strings); do { const char *startp, *endp; char *n; while (*p != '\0' && xisspace(*p)) p++; if (*p != '\'') { errorcol(fbp, column + (int)(p - *pp), "starting \"'\" expected!"); return RET_ERROR; } p++; startp = p; while (*p != '\0' && *p != '\'') p++; if (*p == '\0') { errorcol(fbp, column + (int)(p - *pp), "closing \"'\" expected!"); return RET_ERROR; } assert (*p == '\''); endp = p; p++; n = strndup(startp, endp - startp); if (FAILEDTOALLOC(n)) return RET_ERROR_OOM; r = strlist_adduniq(strings, n); if (RET_WAS_ERROR(r)) return r; while (*p != '\0' && xisspace(*p)) p++; column += (p - *pp); *pp = p; if (**pp == '|') { p++; } } while (**pp == '|'); *pp = p; return RET_OK; }
retvalue chunk_getextralinelist(const char *chunk, const char *name, struct strlist *strlist) { retvalue r; const char *f, *b, *e; char *v; f = chunk_getfield(name, chunk); if (f == NULL) return RET_NOTHING; strlist_init(strlist); /* walk over the first line */ while (*f != '\0' && *f != '\n') f++; /* nothing there is an empty list */ if (*f == '\0') return RET_OK; f++; /* while lines begin with ' ' or '\t', add them */ while (*f == ' ' || *f == '\t') { while (*f != '\0' && xisblank(*f)) f++; b = f; while (*f != '\0' && *f != '\n') f++; e = f; while (e > b && *e != '\0' && xisspace(*e)) e--; if (!xisspace(*e)) v = strndup(b, e - b + 1); else v = strdup(""); if (FAILEDTOALLOC(v)) { strlist_done(strlist); return RET_ERROR_OOM; } r = strlist_add(strlist, v); if (!RET_IS_OK(r)) { strlist_done(strlist); return r; } if (*f == '\0') return RET_OK; f++; } return RET_OK; }
static char *cleanstr(char *path, const char sep) { if (path && *path) { char *e = path + strlen(path) - 1; while (e >= path && (*e == sep || xisspace(*e))) *e-- = '\0'; } return path; }
rpmiob rpmiobRTrim(rpmiob iob) { assert(iob != NULL); while (iob->blen > 0 && xisspace((int)iob->b[iob->blen-1])) iob->b[--iob->blen] = (rpmuint8_t) '\0'; if (_rpmiob_debug) fprintf(stderr, "<-- %s(%p) %p[%u:%u]\n", __FUNCTION__, iob, iob->b, (unsigned)iob->blen, (unsigned)iob->allocated); return iob; }
/* parses and inits header entry, returns new entry on success */ static HttpHeaderEntry * httpHeaderEntryParseCreate(const char *field_start, const char *field_end) { HttpHeaderEntry *e; int id; /* note: name_start == field_start */ const char *name_end = strchr(field_start, ':'); const int name_len = name_end ? name_end - field_start : 0; const char *value_start = field_start + name_len + 1; /* skip ':' */ /* note: value_end == field_end */ HeaderEntryParsedCount++; /* do we have a valid field name within this field? */ if (!name_len || name_end > field_end) return NULL; if (name_len > 65536) { /* String has a 64K limit */ debug(55, 1) ("WARNING: ignoring header name of %d bytes\n", name_len); return NULL; } /* now we know we can parse it */ e = memAllocate(MEM_HTTP_HDR_ENTRY); debug(55, 9) ("creating entry %p: near '%s'\n", e, getStringPrefix(field_start, field_end)); /* is it a "known" field? */ id = httpHeaderIdByName(field_start, name_len, Headers, HDR_ENUM_END); if (id < 0) id = HDR_OTHER; assert_eid(id); e->id = id; /* set field name */ if (id == HDR_OTHER) stringLimitInit(&e->name, field_start, name_len); else e->name = Headers[id].name; /* trim field value */ while (value_start < field_end && xisspace(*value_start)) value_start++; if (field_end - value_start > 65536) { /* String has a 64K limit */ debug(55, 1) ("WARNING: ignoring '%s' header of %d bytes\n", strBuf(e->name), (int) (field_end - value_start)); if (e->id == HDR_OTHER) stringClean(&e->name); memFree(e, MEM_HTTP_HDR_ENTRY); return NULL; } /* set field value */ stringLimitInit(&e->value, value_start, field_end - value_start); Headers[id].stat.seenCount++; Headers[id].stat.aliveCount++; debug(55, 9) ("created entry %p: '%s: %s'\n", e, strBuf(e->name), strBuf(e->value)); return e; }
/* in-place */ static /*@null@*/ /*@exposed@*/ char *ltrim(/*@null@*/ char *s) { if (s == NULL || *s == '\0') { /* Empty string, returns unmodified */ return s; } while (xisspace(*s)) { s++; } return s; }
/* returns the number of leading white spaces in str; handy in skipping ws */ size_t xcountws(const char *str) { size_t count = 0; if (str) { while (xisspace(*str)) { str++; count++; } } return count; }
static char * xstrtok(char **str, char del) { if (*str) { char *p = strchr(*str, del); char *tok = *str; int len; if (p) { *str = p + 1; *p = '\0'; } else *str = NULL; /* trim */ len = strlen(tok); while (len && xisspace(tok[len - 1])) tok[--len] = '\0'; while (xisspace(*tok)) tok++; return tok; } else return ""; }
retvalue chunk_getuniqwordlist(const char *chunk, const char *name, struct strlist *strlist) { retvalue r; const char *f, *b; char *v; f = chunk_getfield(name, chunk); if (f == NULL) return RET_NOTHING; strlist_init(strlist); while (*f != '\0') { /* walk over spaces */ while (*f != '\0' && xisspace(*f)) { if (*f == '\n') { f++; if (*f != ' ' && *f != '\t') return RET_OK; } else f++; } if (*f == '\0') return RET_OK; b = f; /* search for end of word */ while (*f != '\0' && !xisspace(*f)) f++; v = strndup(b, f - b); if (FAILEDTOALLOC(v)) { strlist_done(strlist); return RET_ERROR_OOM; } r = strlist_adduniq(strlist, v); if (!RET_IS_OK(r)) { strlist_done(strlist); return r; } } return RET_OK; }
bool safe_strtol(const char *str, int32_t *out) { assert(out != NULL); errno = 0; *out = 0; char *endptr; long l = strtol(str, &endptr, 10); if (errno == ERANGE) return false; if (xisspace(*endptr) || (*endptr == '\0' && endptr != str)) { *out = l; return true; } return false; }
void CFileReader::_toNextToken() { FDASSERT(m_pos != NULL); while (xisspace(*m_pos)) { ++m_pos; } if (getOption(opt_comments)) { _skipComments(); } }
/* * parses a given string then packs compiled headers and compares the result * with the original, reports discrepancies */ void httpHeaderTestParser(const char *hstr) { static int bug_count = 0; int hstr_len; int parse_success; HttpHeader hdr; int pos; Packer p; MemBuf mb; assert(hstr); /* skip start line if any */ if (!strncasecmp(hstr, "HTTP/", 5)) { const char *p = strchr(hstr, '\n'); if (p) hstr = p + 1; } /* skip invalid first line if any */ if (xisspace(*hstr)) { const char *p = strchr(hstr, '\n'); if (p) hstr = p + 1; } hstr_len = strlen(hstr); /* skip terminator if any */ if (strstr(hstr, "\n\r\n")) hstr_len -= 2; else if (strstr(hstr, "\n\n")) hstr_len -= 1; httpHeaderInit(&hdr, hoReply); /* debugLevels[55] = 8; */ parse_success = httpHeaderParse(&hdr, hstr, hstr + hstr_len); /* debugLevels[55] = 2; */ if (!parse_success) { debug(66, 2) ("TEST (%d): failed to parsed a header: {\n%s}\n", bug_count, hstr); return; } /* we think that we parsed it, veryfy */ memBufDefInit(&mb); packerToMemInit(&p, &mb); httpHeaderPackInto(&hdr, &p); if ((pos = abs(httpHeaderStrCmp(hstr, mb.buf, hstr_len)))) { bug_count++; debug(66, 2) ("TEST (%d): hdr parsing bug (pos: %d near '%s'): expected: {\n%s} got: {\n%s}\n", bug_count, pos, hstr + pos, hstr, mb.buf); } httpHeaderClean(&hdr); packerClean(&p); memBufClean(&mb); }
static BINDING_FUNCTION(binding_word_rubout) { CHAR_T *p; int eaten = 0; if (!line_index) return; xfree(yanked); p = line + line_index; if (xisspace(*(p - 1))) { while (p > line && xisspace(*(p - 1))) { p--; eaten++; } } else { while (p > line && ! xisalpha(*(p - 1)) && ! xisspace(*(p - 1))) { p--; eaten++; } } if (p > line) { while (p > line && ! xisspace(*(p - 1)) && xisalpha(*(p - 1))) { p--; eaten++; } } yanked = xcalloc(eaten + 1, sizeof(CHAR_T)); xwcslcpy(yanked, p, eaten + 1); memmove(p, line + line_index, (xwcslen(line) - line_index + 1) * sizeof(CHAR_T)); line_index -= eaten; }
/* * iterates through a 0-terminated string of items separated by 'del's. * white space around 'del' is considered to be a part of 'del' * like strtok, but preserves the source, and can iterate several strings at once * * returns true if next item is found. * init pos with NULL to start iteration. */ int strListGetItem(const String * str, char del, const char **item, int *ilen, const char **pos) { size_t len; /* ',' is always enabled as field delimiter as this is required for * processing merged header values properly, even if Cookie normally * uses ';' as delimiter. */ static char delim[3][8] = { "\"?,", "\"\\", " ?,\t\r\n" }; int quoted = 0; delim[0][1] = del; delim[2][1] = del; assert(str && item && pos); if (!*pos) { *pos = strBuf(*str); if (!*pos) return 0; } /* skip leading whitespace and delimiters */ *pos += strspn(*pos, delim[2]); *item = *pos; /* remember item's start */ /* find next delimiter */ do { *pos += strcspn(*pos, delim[quoted]); if (**pos == '"') { quoted = !quoted; *pos += 1; } else if (quoted && **pos == '\\') { *pos += 1; if (**pos) *pos += 1; } else { break; /* Delimiter found, marking the end of this value */ } } while (**pos); len = *pos - *item; /* *pos points to del or '\0' */ /* rtrim */ while (len > 0 && xisspace((*item)[len - 1])) len--; if (ilen) *ilen = len; return len > 0; }
/* returns http status extracted from status line or -1 on parsing failure */ static int parse_status_line(const char *sline, const char **statusStr) { const char *sp = strchr(sline, ' '); if (statusStr) *statusStr = NULL; if (strncasecmp(sline, "HTTP/", 5) || !sp) return -1; while (xisspace(*++sp)); if (!xisdigit(*sp)) return -1; if (statusStr) *statusStr = sp; return atoi(sp); }
ulong strtochan(char *s) { char *p, *q; ulong c; int t, n; c = 0; p=s; while(*p && xisspace(*p)) p++; while(*p && !xisspace(*p)){ if((q = strchr(channames, p[0])) == nil) return 0; t = q-channames; if(p[1] < '0' || p[1] > '9') return 0; n = p[1]-'0'; c = (c<<8) | __DC(t, n); p += 2; } return c; }