static int isclean(char *addr, int flagaddr) /* 1 for addresses with '@', 0 for other args */ /* assures that addr has only letters, digits, "-_" */ /* also checks allows single '@' if flagaddr = 1 */ /* returns 1 if clean, 0 otherwise */ { unsigned int pos; char ch; char *cp; if (flagaddr) { /* shoud have one '@' */ pos = str_chr(addr,'@'); if (!pos || !addr[pos]) return 0; /* at least 1 char for local */ if (!addr[pos+1]) return 0; /* host must be at least 1 char */ pos++; case_lowerb(addr+pos,str_len(addr)-pos); } else pos = 0; pos += str_chr(addr + pos,'@'); if (addr[pos]) /* but no more */ return 0; cp = addr; while ((ch = *(cp++))) if (!(ch >= 'a' && ch <= 'z') && !(ch >= 'A' && ch <= 'Z') && !(ch >= '0' && ch <= '9') && ch != '.' && ch != '-' && ch != '_' && ch != '@') return 0; return 1; }
int main() { char buf[100]; strcpy(buf,"abcdefghijklmnopqrstuvwxyz"); size_t i; for (i=0; i<26; ++i) assert(str_chr(buf,buf[i])==i); assert(str_chr(buf,'X')==26); }
static void print_escape(char *x, int wall) { char ch, *y, *start, *from = "abefnrtv\\c", *to= "\a\b\033\f\n\r\t\v\\"; unsigned long len; start = alloca(str_len(x) + 3); for (y=start; (ch=*x); x++) { if (ch == '\\') { unsigned long u; len = scan_8ulong(x+1, &u); if (len) { /* 012...9 */ ch = u; x += len; } else { len = str_chr(from, x[1]); switch (from[len]) { case 0: break; case 'c': goto do_it; default: /* \a\b... */ ++x; ch = to[len]; } } } *y++ = ch; } *y++ = '\n'; do_it: len = y-start; if (wall==0) write(1, start, len); else { struct utmp u; int fd, r; char line[8 + sizeof(u.ut_line)]; fd = open(_PATH_UTMP, O_RDONLY | O_NOCTTY); if (fd < 0) return; while (utmp_io(fd, &u, F_RDLCK)) { if (u.ut_type != USER_PROCESS) continue; if (u.ut_user[0] == 0 || u.ut_pid < 2 || u.ut_line[0] == 0 || u.ut_line[0] == '/') continue; y = line; y += str_copyn(y, "/dev/", 8); y += str_copyn(y, u.ut_line, sizeof(u.ut_line)); y[0] = 0; if (line[str_chr(line, '.')]) continue; if (kill(u.ut_pid, 0) && errno == ESRCH) continue; r = open(line, O_WRONLY | O_NOCTTY | O_NDELAY); if (r < 0) continue; write(r, start, len); close(r); } close(fd); } }
/* [:]user[:group[:group]...] */ unsigned int uidgids_get(struct uidgid *u, char *ug) { char *g =0; struct passwd *pwd =0; struct group *gr =0; int i, d =0; if (*ug == ':') return(uidgids_set(u, ug +1)); if (ug[(d =str_chr(ug, ':'))] == ':') { ug[d] =0; g =ug +d +1; } if (! (pwd =getpwnam(ug))) { if (g) ug[d] =':'; return(0); } u->uid =pwd->pw_uid; if (! g) { u->gid[0] =pwd->pw_gid; u->gids =1; return(1); } ug[d] =':'; for (i =0; i < 60; ++i) { if (g[(d =str_chr(g, ':'))] == ':') { g[d] =0; if (! (gr =getgrnam(g))) { g[d] =':'; return(0); } g[d] =':'; u->gid[i] =gr->gr_gid; g +=d +1; } else { if (! (gr =getgrnam(g))) return(0); u->gid[i++] =gr->gr_gid; break; } } u->gid[i] =0; u->gids =i; return(1); }
static int canonicalize(stralloc* url,const char* baseurl) { /* for the comments, assume baseurl is "http://www.fefe.de/x/y.html" */ int l=strlen(baseurl); char* dest=alloca(url->len+l+2); char* x=dest; if (stralloc_0(url)==0) return 0; if (url->s[0]=='#') { /* "#bar" -> "http://www.fefe.de/x/y.html#bar" */ l=str_chr(baseurl,'#'); byte_copy(x,l,baseurl); byte_copy(x+l,url->len+1,url->s); } else if (url->s[0]=='?') { /* "?bar" -> "http://www.fefe.de/x/y.html?bar" */ for (l=0; baseurl[l]; ++l) if (baseurl[l]=='?' || baseurl[l]=='#') break; byte_copy(x,l,baseurl); byte_copy(x+l,url->len+1,url->s); } else if (url->s[0]=='/') { if (url->s[1]=='/') { /* "//fnord.fefe.de/bla.html" -> "http://fnord.fefe.de/bla.html" */ l=str_chr(baseurl,':'); if (baseurl[l]==':') ++l; byte_copy(x,l,baseurl); byte_copy(x+l,url->len+1,url->s); } else { /* "/bla.html" -> "http://www.fefe.de/bla.html" */ l=str_chr(baseurl,':'); if (baseurl[l]==':' && baseurl[l+1]=='/' && baseurl[l+2]=='/') l+=3; l+=str_chr(baseurl+l,'/'); byte_copy(x,l,baseurl); byte_copy(x+l,url->len+1,url->s); } } else if (strstr(url->s,"://")) { /* "http://foo/bar" -> "http://foo/bar" */ byte_copy(x,url->len+1,url->s); } else { /* "z.html" -> "http://www.fefe.de/x/z.html" */ int k; for (k=l=0; baseurl[k]; ++k) { if (baseurl[k]=='/') l=k+1; if (baseurl[k]=='?') break; } byte_copy(x,l,baseurl); byte_copy(x+l,url->len+1,url->s); } return stralloc_copys(url,x); }
int main(int argc,char **argv) { int i; char *x; char *y; unsigned int u; uint32 ttl; if (!cache_init(200)) _exit(111); if (*argv) ++argv; while (x = *argv++) { i = str_chr(x,':'); if (x[i]) cache_set(x,i,x + i + 1,str_len(x) - i - 1,86400,0); else { y = cache_get(x,i,&u,&ttl,0); if (y) buffer_put(buffer_1,y,u); buffer_puts(buffer_1,"\n"); } } buffer_flush(buffer_1); _exit(0); }
static int doit(stralloc *work,const char *rule) { char ch; unsigned int colon; unsigned int prefixlen; ch = *rule++; if ((ch != '?') && (ch != '=') && (ch != '*') && (ch != '-')) return 1; colon = str_chr(rule,':'); if (!rule[colon]) return 1; if (work->len < colon) return 1; prefixlen = work->len - colon; if ((ch == '=') && prefixlen) return 1; if (case_diffb(rule,colon,work->s + prefixlen)) return 1; if (ch == '?') { if (byte_chr(work->s,prefixlen,'.') < prefixlen) return 1; if (byte_chr(work->s,prefixlen,':') < prefixlen) return 1; if (byte_chr(work->s,prefixlen,'[') < prefixlen) return 1; if (byte_chr(work->s,prefixlen,']') < prefixlen) return 1; } work->len = prefixlen; if (ch == '-') work->len = 0; return stralloc_cats(work,rule + colon + 1); }
int main (int argc, char *const *argv, char const *const *envp) { char const *newargv[argc + 7] ; unsigned int m = 0 ; unsigned int pos ; PROG = "s6-setuidgid" ; if (argc < 3) dieusage() ; argv++ ; pos = str_chr(argv[0], ':') ; if (argv[0][pos]) { argv[0][pos] = 0 ; newargv[m++] = S6_BINPREFIX "s6-applyuidgid" ; newargv[m++] = "-u" ; newargv[m++] = argv[0] ; newargv[m++] = "-g" ; newargv[m++] = argv[0] + pos + 1 ; newargv[m++] = "-G" ; newargv[m++] = "" ; argv++ ; } else { newargv[m++] = S6_BINPREFIX "s6-envuidgid" ; newargv[m++] = *argv++ ; newargv[m++] = S6_BINPREFIX "s6-applyuidgid" ; newargv[m++] = "-Uz" ; } newargv[m++] = "--" ; while (*argv) newargv[m++] = *argv++ ; newargv[m++] = 0 ; pathexec_run(newargv[0], newargv, envp) ; strerr_dieexec(111, newargv[0]) ; }
static inline int issafe(unsigned char c) { const char safe[] = "$/.=~-_"; return ((c>='A' && c<='Z') || (c>='a' && c<='z') || (c>='0' && c<='9') || safe[str_chr(safe,c)]); }
void pop3_apop(char *arg) { char *space; space = arg + str_chr(arg,' '); if (!*space) { err_syntax(); return; } *space++ = 0; doanddie(arg,space - arg,space); }
int ip_fmt(stralloc *out, socket_address *in) { int rc; if (!stralloc_ready(out,512)) return EAI_MEMORY; if ((rc = getnameinfo((struct sockaddr *)in, sizeof *in, out->s, out->a, 0, 0, NI_NUMERICHOST))) return rc; out->len = str_chr(out->s, 0) + 1; return 0; }
int geton(const char *action) { const char *fl; int r; unsigned int i; unsigned char ch; fl = get_from(target.s,action); /* try to match up */ r = subscribe(workdir,target.s,1,fl,(*action == ACTION_RC[0]) ? "+mod" : "+",-1); if (flagdig == FLD_DENY || flagdig == FLD_ALLOW) strerr_die2x(0,INFO,MSG1(ERR_EXTRA_SUB,target.s)); switch (r) { case 1: qmail_puts(&qq,"List-Unsubscribe: <mailto:"); /*rfc2369 */ qmail_put(&qq,outlocal.s,outlocal.len); qmail_puts(&qq,"-unsubscribe-"); /* url-encode since verptarget is controlled by sender */ /* note &verptarget ends in '\0', hence len - 1! */ for (i = 0; i < verptarget.len - 1; i++) { ch = verptarget.s[i]; if (str_chr("\"?;<>&/:%+#",ch) < 10 || (ch <= ' ') || (ch & 0x80)) { urlstr[1] = hex[ch / 16]; urlstr[2] = hex[ch & 0xf]; qmail_put(&qq,urlstr,3); } else { qmail_put(&qq,verptarget.s + i, 1); } } qmail_puts(&qq,"@"); qmail_put(&qq,outhost.s,outhost.len); /* safe */ qmail_puts(&qq,">\n"); hdr_subject(MSG(SUB_WELCOME)); hdr_ctboundary(); stralloc_copy(&confirm,&outlocal); stralloc_cats(&confirm,"-unsubscribe-"); stralloc_cats(&confirm,verptarget.s); stralloc_append(&confirm,'@'); stralloc_cat(&confirm,&outhost); stralloc_0(&confirm); set_cpconfirm(confirm.s,outlocal.len); /* for !R in copy */ copy(&qq,"text/top",flagcd); copy_act("text/sub-ok"); break; default: if (str_start(action,ACTION_TC)) strerr_die2x(0,INFO,MSG(ERR_SUB_NOP)); hdr_subject(MSG(SUB_SUBSCRIBE_NOP)); hdr_ctboundary(); copy(&qq,"text/top",flagcd); copy_act("text/sub-nop"); break; } return r; }
int main(void) { const char *s = "ABCD1234EFGHXXXX"; const char *t = "ABCD1234EFGHXXXX"; const char *u = "AbCdEfGh"; const char *v = "aBcDeFgH"; char *x; long i; unsigned long pos; test_assert(str_chr(s, 'D') == 3); i = str_char(s, 'D', &pos); test_assert(i == 1); test_assert(pos == 3); test_assert(str_diff(s, t) == 0); test_assert(str_same(s, t)); test_assert(str_ndiff(s, t, 8) == 0); test_assert(str_nsame(s, t, 8) == 1); test_assert(str_casei_diff(u, v) == 0); test_assert(str_casei_same(u, v) == 1); test_assert(str_casei_ndiff(u, v, 8) == 0); test_assert(str_casei_nsame(u, v, 8) == 1);; test_assert(str_rchr(s, 'X') == 15); i = str_rchar(s, 'X', &pos); test_assert(i == 1); test_assert(pos == 15); test_assert(str_dup(s, &x)); test_assert(str_same(s, x) == 1); test_assert(str_nsame(s, x, 8) == 1); test_assert(str_starts(s, "ABCD") == 1); test_assert(str_starts(s, "XYZA") == 0); test_assert(str_starts(s, "1234EFGH1234EFGH1234EFGH") == 0); test_assert(str_ends(s, "XXXX") == 1); test_assert(str_ends(s, "ABCD") == 0); test_assert(str_ends(s, "GH1234EFGH123GH1234EFGH123") == 0); test_assert(str_len(s) == 16); str_toupper(x); test_assert(x[0] == 'A'); str_tolower(x); test_assert(x[0] == 'a'); return 0; }
void main(int argc,char **argv) { char *def; int opt; int dash; while ((opt = getopt(argc,argv,"vV")) != opteof) switch (opt) { case 'v': case 'V': strerr_die2x(0, "ezmlm-dispatch version: ",auto_version); default: die_usage(); } if (argv[optind] == 0) die_usage(); wrap_chdir(argv[optind]); if (!stralloc_copys(&basedir,argv[optind++])) die_nomem(); sender = env_get("SENDER"); if (!sender) strerr_die2x(100,FATAL,ERR_NOSENDER); def = env_get("DEFAULT"); if (argv[optind] != 0) { wrap_chdir(argv[optind]); dispatch(argv[optind],def); } else if (!def || !*def) strerr_die2x(100,FATAL,ERR_NODEFAULT); else { if (def[str_chr(def,'/')] != 0) strerr_die2x(100,FATAL,"Recipient address may not contain '/'"); if (chdir(def) == 0) dispatch(def,0); dash = str_len(def); for (;;) { while (--dash > 0) if (def[dash] == '-') break; if (dash <= 0) break; def[dash] = 0; if (chdir(def) == 0) dispatch(def,def+dash+1); def[dash] = '-'; } strerr_die3x(100,FATAL,"Could not match recipient name to any list: ",def); } }
static int pls_reader(playlist* pl) { int ret; static playlist_entry entry; buffer* inbuf = pl->ptr; stralloc line; stralloc_init(&line); if(( ret = buffer_getline_sa(inbuf, &line))) { size_t index2, index; index2 = index = 0; while(line.len > 1 && (line.s[line.len - 1] == '\r' || line.s[line.len - 1] == '\n')) line.len--; stralloc_0(&line); if(!str_diffn(&line.s[index], "Number", 6)) { } else if(line.s[index] == '[') { } else if((index2 = str_chr(&line.s[index], '=')) > 0) { unsigned long trackno = 0; index = index2; index2++; do { index--; } while(isdigit(line.s[index]) && index > 0); scan_ulong(&line.s[index], &trackno); if(!str_diffn(&line.s[index], "File", 4)) { stralloc_copys(&entry.path, &line.s[index2]); stralloc_0(&entry.path); } else if(!str_diffn(&line.s[index], "Title", 5)) { stralloc_copys(&entry.title, &line.s[index2]); stralloc_0(&entry.title); } else if(!str_diffn(&line.s[index], "Length", 6)) { unsigned long len; scan_ulong(&line.s[index2], &len); entry.length = len; } /* uint32 index = 8; index += scan_ulong(&line.s[index], &len); entry.length = len; index++; stralloc_copys(&entry.title, &line.s[index]); stralloc_0(&entry.title); */ } else { /* stralloc_copy(&entry.path, &line); stralloc_0(&entry.path); if(pl->callback) { pl->callback(pl, &entry.title, &entry.path, entry.length); }*/ } } return ret; }
void pathexec_run(const char *file,char **argv,char **envp) { char *path; unsigned int split; int savederrno; if (file[str_chr(file,'/')]) { execve(file,argv,envp); return; } path = env_get("PATH"); if (!path) path = "/bin:/usr/bin"; savederrno = 0; for (;;) { split = str_chr(path,':'); if (!stralloc_copyb(&tmp,path,split)) return; if (!split) if (!stralloc_cats(&tmp,".")) return; if (!stralloc_cats(&tmp,"/")) return; if (!stralloc_cats(&tmp,file)) return; if (!stralloc_0(&tmp)) return; execve(tmp.s,argv,envp); if (errno != error_noent) { savederrno = errno; if ((errno != error_acces) && (errno != error_perm) && (errno != error_isdir)) return; } if (!path[split]) { if (savederrno) errno = savederrno; return; } path += split; path += 1; } }
void makeacthash(stralloc *act) /* act is expected to be -reject-ddddd.ttttt or -accept-ddddd.ttttt and * has to be 0-terminated. */ /* The routine will add .hash@outhost to act. act will NOT be 0-terminated */ { int d; d = 2 + str_chr(act->s + 1,'-'); cookie(hash,key.s,key.len,act->s + d,"","a"); *(act->s + act->len - 1) = '.'; /* we put a '.' Bad, but works */ if (!stralloc_catb(act,hash,COOKIE)) die_nomem(); if (!stralloc_cats(act,"@")) die_nomem(); if (!stralloc_cat(act,&outhost)) die_nomem(); }
int el_popenv (stralloc *sa, char const *const *envp, unsigned int envlen, char const *const *list, unsigned int listlen) { unsigned int i = 0, salen = sa->len, count = 0 ; for (; i < envlen ; i++) { unsigned int equal, colon, n ; unsigned int j = 0 ; for (; j < listlen ; j++) if (str_start(envp[i], list[j])) break ; if (j == listlen) goto copyit ; j = str_len(list[j]) ; colon = j + str_chr(envp[i] + j, ':') ; equal = j + str_chr(envp[i] + j, '=') ; if (!envp[i][equal]) goto badenv ; if (colon >= equal) { count++ ; continue ; } if (colon + 1 + uint_scan(envp[i] + colon + 1, &n) != equal) goto copyit ; if (!n) goto copyit ; if (!stralloc_catb(sa, envp[i], colon)) goto err ; if (n > 1) { char fmt[UINT_FMT+1] = ":" ; n = 1 + uint_fmt(fmt+1, n-1) ; if (!stralloc_catb(sa, fmt, n)) goto err ; } if (!stralloc_catb(sa, envp[i] + equal, str_len(envp[i] + equal) + 1)) goto err ; continue ; copyit: if (!stralloc_catb(sa, envp[i], str_len(envp[i]) + 1)) goto err ; } return (int)count ; badenv : errno = EINVAL ; err: sa->len = salen ; return -1 ; }
size_t fmt_quotedprintable2(char* dest,const char* src,size_t len,const char* escapeme) { register const unsigned char* s=(const unsigned char*) src; size_t written=0,i; for (i=0; i<len; ++i) { if (s[i]&0x80 || s[i]<' ' || s[i]=='=' || escapeme[str_chr(escapeme,s[i])]==s[i]) { if (dest) { dest[written]='='; dest[written+1]=fmt_tohex(s[i]>>4); dest[written+2]=fmt_tohex(s[i]&15); } written+=3; } else { if (dest) dest[written]=s[i]; ++written; } /* in case someone gives us malicious input */ if (written>((size_t)-1)/2) return (size_t)-1; }
void pathexec_env_run(const char *file, const char *const *argv) { const char **e; unsigned int elen; unsigned int i; unsigned int j; unsigned int split; unsigned int t; if (!stralloc_cats(&plus,"")) return; elen = 0; for (i = 0;environ[i];++i) ++elen; for (i = 0;i < plus.len;++i) if (!plus.s[i]) ++elen; e = (const char **) alloc((elen + 1) * sizeof(char *)); if (!e) return; elen = 0; for (i = 0;environ[i];++i) e[elen++] = environ[i]; j = 0; for (i = 0;i < plus.len;++i) if (!plus.s[i]) { split = str_chr(plus.s + j,'='); for (t = 0;t < elen;++t) if (byte_equal(plus.s + j,split,e[t])) if (e[t][split] == '=') { --elen; e[t] = e[elen]; break; } if (plus.s[j + split]) e[elen++] = plus.s + j; j = i + 1; } e[elen] = 0; pathexec_run(file,argv,e); alloc_free(e); }
int main(void) { char str[10], *p; char uletter[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; printf("英大文字を入力してください:"); scanf("%s",str); p = str_chr(uletter,str[0]); if(p != NULL) { puts(p); } else { puts("入力された文字は英大文字ではありません"); } return(0); }
int main(int argc, char **argv) { char *name; char *env; char value[256]; int len; name = argv[1]; if (!name) _exit(100); env = argv[2]; if ((len = substdio_get(subfdin,value,sizeof value - 1)) <= 0) _exit(100); value[len] = 0; value[str_chr(value,'\n')] = 0; if (env) { subputs("#include \"env.h\"\n" "const char *"); subputs(name); subputs("(void)\n" "{\n" " const char *env;\n" " if ((env = env_get(\""); subputs(env); subputs("\")) == 0)\n" " env = \""); subputsbin(value); subputs("\";\n" " return env;\n" "}\n"); } else { subputs("const char "); subputs(name); subputs("[] = \""); subputsbin(value); subputs("\";\n"); } if (substdio_flush(subfdout) == -1) _exit(111); return 0; (void)argc; }
void main(int argc,char **argv) { char *def; int dash; optind = getconfopt(argc,argv,options,0,0); if (argv[optind] == 0) die_usage(); if (!stralloc_copys(&basedir,argv[optind++])) die_nomem(); sender = get_sender(); if (!sender) strerr_die2x(100,FATAL,MSG(ERR_NOSENDER)); def = env_get("DEFAULT"); if (argv[optind] != 0) { dispatch(argv[optind],def); strerr_die3x(100,FATAL,"Not a directory: ",path.s); } else if (!def || !*def) strerr_die2x(100,FATAL,MSG(ERR_NODEFAULT)); else { if (def[str_chr(def,'/')] != 0) strerr_die2x(100,FATAL,"Recipient address may not contain '/'"); dispatch(def,0); dash = str_len(def); for (;;) { while (--dash > 0) if (def[dash] == '-') break; if (dash <= 0) break; def[dash] = 0; dispatch(def,def+dash+1); def[dash] = '-'; } strerr_die3x(100,FATAL,"Could not match recipient name to any list: ",def); } }
void found(char *data,unsigned int datalen) { unsigned int next0; unsigned int split; while ((next0 = byte_chr(data,datalen,0)) < datalen) { switch(data[0]) { case 'D': flagdeny = 1; break; case '+': split = str_chr(data + 1,'='); if (data[1 + split] == '=') { data[1 + split] = 0; env(data + 1,data + 1 + split + 1); } break; } ++next0; data += next0; datalen -= next0; } }
unsigned long fmt_cescape2(char* dest,const char* src,unsigned long len,const char* escapeme) { register const unsigned char* s=(const unsigned char*) src; unsigned long written=0,i; char c; for (i=0; i<len; ++i) { switch (s[i]) { case '\a': c='a'; goto doescape; case '\b': c='b'; goto doescape; case 0x1b: c='e'; goto doescape; case '\f': c='f'; goto doescape; case '\n': c='n'; goto doescape; case '\r': c='r'; goto doescape; case '\t': c='t'; goto doescape; case '\v': c='v'; goto doescape; case '\\': c='\\'; doescape: if (dest) { dest[written]='\\'; dest[written+1]=c; } written+=2; break; default: if (s[i]<' ' || escapeme[str_chr(escapeme,s[i])]==s[i]) { if (dest) { dest[written]='\\'; dest[written+1]='x'; dest[written+2]=fmt_tohex(s[i]>>4); dest[written+3]=fmt_tohex(s[i]&0xf); } written+=4; } else { if (dest) dest[written]=s[i]; ++written; } break; } }
//-------- BEGIN OF FUNCTION Misc::str_shorten --------// // // Shorten the string with words exceed the dest. length cut. // // <char *> = destination string // <char *> = source string (source should be longer than dest) // <int> = max. no. of characters in the dest. string. // ( destStr should be allocated as destStr[destLen+1] ) // void Misc::str_shorten(char* destStr, const char* srcStr, int destLen) { strncpy( destStr, srcStr, destLen ); destStr[destLen]='\0'; //------ no need to cut characters if it fit preciously ----// // // e.g. "One Two Three" ---> "One Two" // (srcStr) (destStr, return it as the result) //----------------------------------------------------------// if( (int)strlen(srcStr) < destLen || srcStr[destLen] == ' ' ) return; //--- if there is only one word in the string, don't cut it ----// // // e.g. "VeryLongWord" --> "VeryLongWo" // //--------------------------------------------------------------// if( !str_chr( destStr, ' ' ) ) return; //------ if there is more than one word, cut it ------// // // e.g. "One Two Three" ----> "One Two Thr" ---> "One Two" // (srcStr) (destStr before) (destStr after) // //----------------------------------------------------// int i; for( i=destLen-1 ; i>0 && destStr[i] != ' ' ; i-- ) destStr[i] = '\0'; destStr[i] = '\0'; // trim the space also }
/** Find symbols that match the parameter forward and print them. * * @param name Search string * @param startpos Starting position, changes to found position * * @return Pointer to the part of string that should be completed or NULL. * */ static const char *symtab_search_one(const char *name, size_t *startpos) { size_t namelen = str_length(name); size_t pos; for (pos = *startpos; symbol_table[pos].address_le; pos++) { const char *curname = symbol_table[pos].symbol_name; /* Find a ':' in curname */ const char *colon = str_chr(curname, ':'); if (colon == NULL) continue; if (str_length(curname) < namelen) continue; if (str_lcmp(name, curname, namelen) == 0) { *startpos = pos; return (curname + str_lsize(curname, namelen)); } } return NULL; }
/* hashed command search routine * ----------------------------------------------------------------------- */ union command exec_hash(char *name, enum hash_id *idptr) { enum hash_id id; union command cmd; /* name contains slashes, its a path */ if(name[str_chr(name, '/')]) { /* do not hash this... */ id = H_PROGRAM; cmd.path = name; /* ...but validate the path */ if(access(cmd.path, X_OK) != 0) cmd.path = NULL; } /* otherwise try to find hashed entry */ else { struct exechash *entry; unsigned long hash; /* hash the name for possible re-use on exechash_create() */ hash = exec_hashstr(name); /* do we have a cache hit? */ if((entry = exec_search(name, hash))) { entry->hits++; id = entry->id; cmd = entry->cmd; } /* if we don't have a cache hit we're gonna search, special builtins first */ else { id = H_EXEC; cmd.builtin = builtin_search(name, B_EXEC); /* then search for functions */ if(cmd.builtin == NULL) { id = H_SBUILTIN; cmd.builtin = builtin_search(name, B_SPECIAL); } /* then search for functions */ if(cmd.builtin == NULL) { id = H_FUNCTION; cmd.fn = /* FIXME */ NULL; } /* then search for normal builtins */ if(cmd.fn == NULL) { id = H_BUILTIN; cmd.builtin = builtin_search(name, B_DEFAULT); } /* then search for external commands */ if(cmd.builtin == NULL) { id = H_PROGRAM; cmd.path = exec_path(name); } /* if we found something then create a new cache entry */ if(cmd.ptr) { entry = exec_create(name, hash); entry->hits++; entry->id = id; entry->cmd = cmd; } } } /* we have a command, set the id */ if(cmd.ptr && idptr) *idptr = id; return cmd; }
static int init(stralloc *rules) { char host[256]; const char *x; int i; int j; int k; if (!stralloc_copys(rules,"")) return -1; x = env_get("DNSREWRITEFILE"); if (!x) x = "/etc/dnsrewrite"; i = openreadclose(x,&data,64); if (i == -1) return -1; if (i) { if (!stralloc_append(&data,"\n")) return -1; i = 0; for (j = 0; (unsigned)j < data.len;++j) if (data.s[j] == '\n') { if (!stralloc_catb(rules,data.s + i,j - i)) return -1; while (rules->len) { if (rules->s[rules->len - 1] != ' ') if (rules->s[rules->len - 1] != '\t') if (rules->s[rules->len - 1] != '\r') break; --rules->len; } if (!stralloc_0(rules)) return -1; i = j + 1; } return 0; } x = env_get("LOCALDOMAIN"); if (x) { if (!stralloc_copys(&data,x)) return -1; if (!stralloc_append(&data," ")) return -1; if (!stralloc_copys(rules,"?:")) return -1; i = 0; for (j = 0; (unsigned)j < data.len;++j) if (data.s[j] == ' ') { if (!stralloc_cats(rules,"+.")) return -1; if (!stralloc_catb(rules,data.s + i,j - i)) return -1; i = j + 1; } if (!stralloc_0(rules)) return -1; if (!stralloc_cats(rules,"*.:")) return -1; if (!stralloc_0(rules)) return -1; return 0; } i = openreadclose("/etc/resolv.conf",&data,64); if (i == -1) return -1; if (i) { if (!stralloc_append(&data,"\n")) return -1; i = 0; for (j = 0; (unsigned)j < data.len;++j) if (data.s[j] == '\n') { if (byte_equal("search ",7,data.s + i) || byte_equal("search\t",7,data.s + i) || byte_equal("domain ",7,data.s + i) || byte_equal("domain\t",7,data.s + i)) { if (!stralloc_copys(rules,"?:")) return -1; i += 7; while (i < j) { k = byte_chr(data.s + i,j - i,' '); k = byte_chr(data.s + i,k,'\t'); if (!k) { ++i; continue; } if (!stralloc_cats(rules,"+.")) return -1; if (!stralloc_catb(rules,data.s + i,k)) return -1; i += k; } if (!stralloc_0(rules)) return -1; if (!stralloc_cats(rules,"*.:")) return -1; if (!stralloc_0(rules)) return -1; return 0; } i = j + 1; } } host[0] = 0; if (gethostname(host,sizeof host) == -1) return -1; host[(sizeof host) - 1] = 0; i = str_chr(host,'.'); if (host[i]) { if (!stralloc_copys(rules,"?:")) return -1; if (!stralloc_cats(rules,host + i)) return -1; if (!stralloc_0(rules)) return -1; } if (!stralloc_cats(rules,"*.:")) return -1; if (!stralloc_0(rules)) return -1; return 0; }
int main(int argc,char* argv[]) { char server[1024]; int* fds; int* avail; int* keepleft; long long* expected; unsigned long n=10000; /* requests */ unsigned long c=10; /* concurrency */ unsigned long t=0; /* time limit in seconds */ unsigned long k=0; /* keep-alive */ unsigned long K=1; /* keep-alive counter */ int report=0; unsigned long long errors=0; unsigned long long bytes=0; int v=0; unsigned long i,done; uint16 port=80; uint32 scope_id=0; stralloc ips={0}; char* request,* krequest; unsigned long rlen, krlen; tai6464 first,now,next,last; enum { SAME, REPLAY } mode; char* hostname; server[0]=0; errmsg_iam("bench"); #ifndef __MINGW32__ signal(SIGPIPE,SIG_IGN); #endif for (;;) { int i; int ch=getopt(argc,argv,"n:c:t:kvK:C:r"); if (ch==-1) break; switch (ch) { case 'r': report=1; break; case 'n': i=scan_ulong(optarg,&n); if (i==0) die(1,"could not parse -n argument \"",optarg,"\".\n"); break; case 'c': i=scan_ulong(optarg,&c); if (i==0) die(1,"could not parse -c argument \"",optarg,"\".\n"); break; case 't': i=scan_ulong(optarg,&t); if (i==0) die(1,"could not parse -t argument \"",optarg,"\".\n"); break; case 'k': k=1; break; case 'K': i=scan_ulong(optarg,&K); break; case 'v': v=1; break; case 'C': cookiefile(optarg); break; case '?': break; default: usage(); } } if (n<1 || c<1 || !argv[optind]) usage(); if (argv[optind][0]=='@') { mode=REPLAY; char* host; n=(unsigned long)-1; host=argv[optind]+1; { int tmp; tmp=str_chr(host,'/'); if (host[tmp]) { host[tmp]=0; if (!scan_ushort(host+tmp+1,&port)) usage(); } tmp=str_chr(host,'%'); if (host[tmp]) { host[tmp]=0; scope_id=socket_getifidx(host+tmp+1); if (scope_id==0) carp("warning: network interface \"",host+tmp+1,"\" not found."); } } { stralloc a={0}; stralloc_copys(&a,host); if (dns_ip6(&ips,&a)==-1) die(1,"could not find IP for \"",host,"\"!"); } hostname=host; request=krequest=0; rlen=krlen=0; } else { char* host=argv[optind]; int colon; int slash; char* c; mode=SAME; if (byte_equal(host,7,"http://")) host+=7; colon=str_chr(host,':'); slash=str_chr(host,'/'); if (host[0]=='[') { /* ipv6 IP notation */ int tmp; ++host; --colon; --slash; tmp=str_chr(host,']'); if (host[tmp]==']') host[tmp]=0; if (host[tmp+1]==':') colon=tmp+1; if (colon<tmp+1) colon=tmp+1+str_len(host+tmp+1); } if (colon<slash) { host[colon]=0; c=host+colon+1; if (c[scan_ushort(c,&port)]!='/') usage(); *c=0; } host[colon]=0; c=host+slash; *c=0; { char* tmp=alloca(str_len(host)+1); tmp[fmt_str(tmp,host)]=0; host=tmp; } *c='/'; { int tmp=str_chr(host,'%'); if (host[tmp]) { host[tmp]=0; scope_id=socket_getifidx(host+tmp+1); if (scope_id==0) carp("warning: network interface \"",host+tmp+1,"\" not found."); } } { stralloc a={0}; stralloc_copys(&a,host); if (dns_ip6(&ips,&a)==-1) die(1,"could not find IP for \"",host,"\"!"); } request=alloca(1300+str_len(host)+3*str_len(c)); krequest=alloca(1300+str_len(host)+3*str_len(c)); { int i,j; i=fmt_str(request,"GET "); i+=fmt_urlencoded(request+i,c,str_len(c)); i+=fmt_str(request+i," HTTP/1.0\r\nHost: "); i+=fmt_str(request+i,host); i+=fmt_str(request+i,":"); i+=fmt_ulong(request+i,port); i+=fmt_str(request+i,"\r\nUser-Agent: bench/1.0\r\nConnection: "); j=i; i+=fmt_str(request+i,"close\r\n\r\n"); rlen=i; request[rlen]=0; byte_copy(krequest,rlen,request); i=j+fmt_str(krequest+j,"keep-alive\r\n\r\n"); krlen=i; krequest[krlen]=0; } hostname=host; } fds=alloca(c*sizeof(*fds)); avail=alloca(c*sizeof(*avail)); expected=alloca(c*sizeof(*expected)); keepleft=alloca(c*sizeof(*keepleft)); last.sec.x=23; if (!k) K=1; for (i=0; i<c; ++i) { fds[i]=-1; avail[i]=1; keepleft[i]=K; } taia_now(&first); for (done=0; done<n; ) { if (t) { /* calculate timeout */ taia_now(&now); if (now.sec.x != last.sec.x) { byte_copy(&last,sizeof(now),&now); byte_copy(&next,sizeof(now),&now); next.sec.x += t; while ((i=io_timeouted())!=-1) { unsigned long j; char numbuf[FMT_ULONG]; numbuf[fmt_ulong(numbuf,i)]=0; carp("timeout on fd ",numbuf,"!"); j=(unsigned long)io_getcookie(i); io_close(i); avail[j]=1; fds[j]=-1; } } } /* first, fill available connections */ for (i=0; i<c; ++i) if (avail[i]==1 && fds[i]==-1) { fds[i]=make_connection(ips.s,port,scope_id,-1); if (fds[i]==-1) diesys(1,"socket/connect"); avail[i]=2; if (io_fd(fds[i])==0) diesys(1,"io_fd"); io_setcookie(fds[i],(void*)i); // io_wantread(fds[i]); io_wantwrite(fds[i]); } if (t) io_waituntil(next); else io_wait(); /* second, see if we can write on a connection */ while ((i=io_canwrite())!=-1) { int j; j=(unsigned long)io_getcookie(i); if (avail[j]==2) { if (make_connection(ips.s,port,scope_id,i)==-1) { ++errors; if (v) write(1,"!",1); io_close(i); avail[j]=1; fds[j]=-1; continue; } } { char* towrite; int writelen; if (mode==REPLAY) { static long lines; char line[1024]; char req[2048]; int len; int i; char* c; char* host; int hlen; if ((len=buffer_getline(buffer_0,line,sizeof(line)))) { ++lines; if (line[len]!='\n') die(0,"line too long: ",line); line[len]=0; c=line; if (str_start(line,"http://")) c+=7; if (c[0]=='/') { host=hostname; hlen=strlen(hostname); } else { host=c; c+=(hlen=str_chr(c,'/')); } if (!*c) c="/"; i=fmt_str(req,"GET "); i+=fmt_urlencoded(req+i,c,str_len(c)); i+=fmt_str(req+i," HTTP/1.0\r\nHost: "); byte_copy(req+i,hlen,host); i+=hlen; i+=fmt_str(req+i,":"); i+=fmt_ulong(req+i,port); if (cookies) { int j; i+=fmt_str(req+i,"\r\n"); j=nextcookie(req+i,sizeof(req)-i-100); if (j!=-1) i+=j; else i-=2; } i+=fmt_str(req+i,"\r\nUser-Agent: bench/1.0\r\nConnection: "); i+=fmt_str(req+i,keepleft[j]>1?"keep-alive\r\n\r\n":"close\r\n\r\n"); req[i]=0; towrite=req; writelen=i; } else { n=done; break; } } else { if (keepleft[j]>1) { towrite=krequest; writelen=krlen; } else { towrite=request; writelen=rlen; } if (cookies) { int i=writelen-2; int j=nextcookie(towrite+i,900); if (j!=-1) i+=j; i+=fmt_str(towrite+i,"\r\n\r\n"); writelen=i; } } if (io_trywrite(i,towrite,writelen)!=writelen) { ++errors; if (v) write(1,"-",1); io_close(i); avail[j]=1; fds[j]=-1; continue; } } io_dontwantwrite(i); io_wantread(i); expected[j]=-1; if (v) write(1,"+",1); } /* third, see if we got served */ while ((i=io_canread())!=-1) { char buf[8193]; int l,j; buf[8192]=0; j=(unsigned long)io_getcookie(i); if ((l=io_tryread(i,buf,sizeof(buf)-1))<=0) { if (l==0) { /* EOF. Mhh. */ if (expected[j]>0) { ++errors; if (v) write(1,"-",1); /* so whine a little */ } if (expected[j]==-2) ++done; io_close(i); avail[j]=1; fds[j]=-1; } else if (l==-3) { ++errors; if (v) write(1,"!",1); // carpsys("read"); } } else { bytes+=l; if (v) write(1,".",1); /* read something */ if (expected[j]==-1) { /* expecting header */ int k; /* OK, so this is a very simplistic header parser. No * buffering. At all. We expect the Content-Length header to * come in one piece. */ if (l>10 && !memcmp(buf,"HTTP/1.",7)) { if (buf[9]>='0' && buf[9]<='9') r[buf[9]-'0']++; else { write(1,buf,15); write(1,"\n",1); } } expected[j]=-2; if (!done) { for (k=0; k<l; ++k) if (str_start(buf+k,"\nServer: ")) { char* tmp=buf+(k+=9); for (; k<l; ++k) if (buf[k]=='\r') break; k=buf+k-tmp; if (k>sizeof(server)-1) k=sizeof(server)-1; byte_copy(server,k,tmp); server[k]=0; break; } } for (k=0; k<l; ++k) { if (str_start(buf+k,"\nContent-Length: ")) { k+=17; if (buf[k+scan_ulonglong(buf+k,(unsigned long long*)expected+j)] != '\r') die(1,"parse error in HTTP header!"); } else if (str_start(buf+k,"\r\n\r\n")) break; } if (expected[j]>0) { if (l-(k+4)>expected[j]) expected[j]=0; else expected[j]-=l-(k+4); } } else if (expected[j]==-2) { /* no content-length header, eat everything until EOF */ } else { if (l>expected[j]) { carp("got more than expected!"); expected[j]=0; } else expected[j]-=l; } if (expected[j]==0) { ++done; /* one down! */ avail[j]=1; // printf("fd %d: keepleft[%d]=%d\n",i,j,keepleft[j]); if (keepleft[j]>1) { --keepleft[j]; io_dontwantread(i); io_wantwrite(i); expected[j]=0; } else { keepleft[j]=K; io_close(i); fds[j]=-1; } } } } } taia_now(&now); taia_sub(&now,&now,&first); { char a[FMT_ULONG]; char b[FMT_ULONG]; char C[FMT_ULONG]; char d[FMT_ULONG]; char e[FMT_ULONG]; char f[FMT_ULONG]; char g[FMT_ULONG]; char h[FMT_ULONG]; char i[FMT_ULONG]; char j[FMT_ULONG]; unsigned long long l; a[fmt_ulong(a,now.sec.x)]=0; b[fmt_ulong0(b,(now.nano%1000000000)/100000,4)]=0; C[fmt_ulong(C,done)]=0; d[fmt_ulonglong(d,errors)]=0; e[fmt_ulonglong(e,bytes)]=0; /* let's say bytes = 10 MB, time = 1.2 sec. * then we want 10*1024*1024/1.2 == 8 MB/sec */ l = (now.sec.x * 1024) + now.nano/976562; if (l) { int i; l=bytes/l; if (report) i=fmt_ulong(f,l); else { i=fmt_humank(f,l*1024); i+=fmt_str(f+i,"iB/sec"); } f[i]=0; } else strcpy(f,"n/a"); l = (now.sec.x * 1000) + now.nano/1000000; l = l ? (done*10000) / l : 0; g[fmt_ulong(g,l/10)]=0; h[fmt_ulong(h,c)]=0; i[fmt_ulong(i,K)]=0; j[fmt_ulong(j,kaputt)]=0; if (server[0]) msg("Server: ",server); if (report) { errmsg_iam(0); msg("req\terr\tconcur\tkeep\tkbytes\tsec\ttput\tr/s\treset"); msg(C,"\t",d,"\t",h,"\t",i,"\t",e,"\t",a,".",b,"\t",f,"\t",g,"\t",j); } else { msg(C," requests, ",d," errors."); msg(e," bytes in ",a,".",b," seconds."); msg("Throughput: ",f); msg("Requests per second: ",g); msg("Connection refused/reset by peer: ",j); } { int i; for (i=0; i<9; ++i) { a[fmt_ulong(a,r[i])]=0; b[0]=i+'0'; b[1]=0; msg(b,"xx: ",a); } } } return 0; }