size_t fmt_httpdate(char* dest,time_t t) { static const char days[] = "SunMonTueWedThuFriSat"; static const char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; struct tm* x=gmtime(&t); size_t i; if (dest==0) return 29; /* "Sun, 06 Nov 1994 08:49:37 GMT" */ byte_copy(dest,3,days+3*x->tm_wday); i=3; i+=fmt_str(dest+i,", "); i+=fmt_2digits(dest+i,x->tm_mday); i+=fmt_str(dest+i," "); byte_copy(dest+i,3,months+3*x->tm_mon); i+=3; i+=fmt_str(dest+i," "); i+=fmt_2digits(dest+i,(x->tm_year+1900)/100); i+=fmt_2digits(dest+i,(x->tm_year+1900)%100); i+=fmt_str(dest+i," "); i+=fmt_2digits(dest+i,x->tm_hour); i+=fmt_str(dest+i,":"); i+=fmt_2digits(dest+i,x->tm_min); i+=fmt_str(dest+i,":"); i+=fmt_2digits(dest+i,x->tm_sec); i+=fmt_str(dest+i," GMT"); return i; }
static inline int copyfds (char *s, int const *fds, unsigned int n, unsigned char const *bits) { register unsigned int i = 0 ; for (; i < n ; i++) { int fd = fds[i] ; if (fd < 0) return (errno = EINVAL, -1) ; if (bitarray_peek(bits, i)) fd = - fd - 1 ; #ifdef SKALIBS_HASANCILAUTOCLOSE else { fd = dup(fd) ; if (fd < 0) { int e = errno ; while (i--) { s -= sizeof(int) ; byte_copy((char *)fd, sizeof(int), s) ; if (fd >= 0) fd_close(fd) ; } errno = e ; return 0 ; } } #else #endif byte_copy(s, sizeof(int), (char const *)&fd) ; s += sizeof(int) ; } return 1 ; }
void check_essential (int si) { if (rc == 0) { struct stat st; const char *name = aa_service_name (aa_service (si)); size_t l_name = strlen (name); char buf[l_name + 1 + sizeof (ESSENTIAL_FILENAME)]; byte_copy (buf, l_name, name); byte_copy (buf + l_name, 1 + sizeof (ESSENTIAL_FILENAME), "/" ESSENTIAL_FILENAME); if (stat (buf, &st) < 0) { if (errno != ENOENT) { int e = errno; put_warn (name, "Failed to stat " ESSENTIAL_FILENAME ": ", 0); add_warn (strerror (e)); end_warn (); } } else rc = 1; } }
int socket_accept6(int s,char ip[16],uint16 *port,uint32 *scope_id) { #ifdef LIBC_HAS_IP6 struct sockaddr_in6 sa; #else struct sockaddr_in sa; #endif unsigned int dummy = sizeof sa; int fd; fd = accept(s,(struct sockaddr *) &sa,&dummy); if (fd == -1) return -1; #ifdef LIBC_HAS_IP6 if (sa.sin6_family==AF_INET) { struct sockaddr_in *sa4=(struct sockaddr_in*)&sa; byte_copy(ip,12,V4mappedprefix); byte_copy(ip+12,4,(char *) &sa4->sin_addr); uint16_unpack_big((char *) &sa4->sin_port,port); return fd; } byte_copy(ip,16,(char *) &sa.sin6_addr); uint16_unpack_big((char *) &sa.sin6_port,port); if (scope_id) *scope_id=sa.sin6_scope_id; return fd; #else byte_copy(ip,12,V4mappedprefix); byte_copy(ip+12,4,(char *) &sa.sin_addr); uint16_unpack_big((char *) &sa.sin_port,port); if (scope_id) *scope_id=0; return fd; #endif }
int aa_service_status_write (aa_service_status *svst, const char *dir) { size_t len = strlen (dir); char file[len + 1 + sizeof (AA_SVST_FILENAME)]; mode_t mask; int r; int e; if (!stralloc_ready_tuned (&svst->sa, AA_SVST_FIXED_SIZE, 0, 0, 1)) return -1; tain_pack (svst->sa.s, &svst->stamp); uint32_pack (svst->sa.s + 12, (uint32_t) svst->event); uint32_pack (svst->sa.s + 16, (uint32_t) svst->code); if (svst->sa.len < AA_SVST_FIXED_SIZE) svst->sa.len = AA_SVST_FIXED_SIZE; byte_copy (file, len, dir); byte_copy (file + len, 1 + sizeof (AA_SVST_FILENAME), "/" AA_SVST_FILENAME); mask = umask (0033); if (!openwritenclose_suffix (file, svst->sa.s, svst->sa.len + ((svst->sa.len > AA_SVST_FIXED_SIZE) ? -1 : 0), ".new")) r = -1; else r = 0; e = errno; umask (mask); tain_now_g (); errno = e; return r; }
/* if the <path> is relative and <cwd> is non-null then it is prepended * to the path, so it will work like shell_canonicalize, except that * relative paths will be resolved to absolute ones. * ----------------------------------------------------------------------- */ int shell_realpath(const char *path, stralloc *sa, int symbolic, stralloc *cwd) { /* if its not absolute on the first recursion level then make it so */ if(*path != '/' && sa->len == 0) { char buf[PATH_MAX + 1]; /* check whether the name fits */ unsigned long n; n = str_len(path); if(cwd->len + n + 1 > PATH_MAX) { errno = ENAMETOOLONG; return 0; } /* copy current dir */ byte_copy(buf, cwd->len, cwd->s); buf[cwd->len] = '/'; byte_copy(&buf[cwd->len + 1], n + 1, path); /* run canonicalize with the concatenated path */ return shell_canonicalize(buf, sa, symbolic); } return shell_canonicalize(path, sa, symbolic); }
int socket_remote6(int s,char ip[16],uint16 *port,uint32 *scope_id) { #ifdef LIBC_HAS_IP6 struct sockaddr_in6 si; #else struct sockaddr_in si; #endif socklen_t len = sizeof si; if (getpeername(s,(struct sockaddr *) &si,&len) == -1) return -1; #ifdef LIBC_HAS_IP6 if (si.sin6_family==AF_INET) { struct sockaddr_in *si4=(struct sockaddr_in*)&si; byte_copy(ip,12,V4mappedprefix); byte_copy(ip+12,4,(char *) &si4->sin_addr); uint16_unpack_big((char *) &si4->sin_port,port); return 0; } byte_copy(ip,16,(char *) &si.sin6_addr); uint16_unpack_big((char *) &si.sin6_port,port); if (scope_id) *scope_id=si.sin6_scope_id; #else byte_copy(ip,12,V4mappedprefix); byte_copy(ip+12,4,(char *) &si.sin_addr); uint16_unpack_big((char *) &si.sin_port,port); if (scope_id) *scope_id=0; #endif return 0; }
int socket_recv6(int s,char *buf,unsigned int len,char ip[16],uint16 *port,uint32 *scope_id) { #ifdef LIBC_HAS_IP6 struct sockaddr_in6 sa; #else struct sockaddr_in sa; #endif unsigned int dummy = sizeof sa; int r; byte_zero(&sa,dummy); r = recvfrom(s,buf,len,0,(struct sockaddr *) &sa,&dummy); if (r == -1) return -1; #ifdef LIBC_HAS_IP6 if (noipv6) { struct sockaddr_in *sa4=(struct sockaddr_in *)&sa; byte_copy(ip,12,V4mappedprefix); byte_copy(ip+12,4,(char *) &sa4->sin_addr); uint16_unpack_big((char *) &sa4->sin_port,port); return r; } byte_copy(ip,16,(char *) &sa.sin6_addr); uint16_unpack_big((char *) &sa.sin6_port,port); if (scope_id) *scope_id=sa.sin6_scope_id; #else byte_copy(ip,12,(char *)V4mappedprefix); byte_copy(ip+12,4,(char *) &sa.sin_addr); uint16_unpack_big((char *) &sa.sin_port,port); if (scope_id) *scope_id=0; #endif return r; }
int s6_svc_main (int argc, char const *const *argv, char const *optstring, char const *usage, char const *controldir) { char data[DATASIZE] ; unsigned int datalen = 0 ; register int r ; for (;;) { register int opt = subgetopt(argc, argv, optstring) ; if (opt == -1) break ; if (opt == '?') strerr_dieusage(100, usage) ; if (datalen >= DATASIZE) strerr_dief1x(100, "too many commands") ; data[datalen++] = opt ; } argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ; if (!argc) strerr_dieusage(100, usage) ; { unsigned int arglen = str_len(*argv) ; unsigned int cdirlen = str_len(controldir) ; char tmp[arglen + cdirlen + 10] ; byte_copy(tmp, arglen, *argv) ; tmp[arglen] = '/' ; byte_copy(tmp + arglen + 1, cdirlen, controldir) ; byte_copy(tmp + arglen + 1 + cdirlen, 9, "/control") ; r = s6_svc_write(tmp, data, datalen) ; } if (r < 0) strerr_diefu2sys(111, "control ", *argv) ; else if (!r) strerr_diefu3x(100, "control ", *argv, ": supervisor not listening") ; return 0 ; }
static int doit(char *q,char qtype[2],char ip[4]) { int r; uint32 dlen; unsigned int qlen; qlen = dns_domain_length(q); if (qlen > 255) return 0; /* impossible */ if (byte_diff(qtype,2,DNS_T_A) && byte_diff(qtype,2,DNS_T_ANY)) goto REFUSE; key[0] = '%'; byte_copy(key + 1,4,ip); r = cdb_find(&c,key,5); if (!r) r = cdb_find(&c,key,4); if (!r) r = cdb_find(&c,key,3); if (!r) r = cdb_find(&c,key,2); if (r == -1) return 0; key[0] = '+'; byte_zero(key + 1,2); if (r && (cdb_datalen(&c) == 2)) if (cdb_read(&c,key + 1,2,cdb_datapos(&c)) == -1) return 0; byte_copy(key + 3,qlen,q); case_lowerb(key + 3,qlen + 3); r = cdb_find(&c,key,qlen + 3); if (!r) { byte_zero(key + 1,2); r = cdb_find(&c,key,qlen + 3); } if (!r) goto REFUSE; if (r == -1) return 0; dlen = cdb_datalen(&c); if (dlen > 512) dlen = 512; if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) return 0; dns_sortip(data,dlen); if (dlen > 12) dlen = 12; while (dlen >= 4) { dlen -= 4; if (!response_rstart(q,DNS_T_A,"\0\0\0\5")) return 0; if (!response_addbytes(data + dlen,4)) return 0; response_rfinish(RESPONSE_ANSWER); } return 1; REFUSE: response[2] &= ~4; response[3] &= ~15; response[3] |= 5; return 1; }
int dns_domain_fromdot_static(unsigned char *name,const unsigned char *buf,long long n) { unsigned char label[63]; long long labellen = 0; /* <= sizeof label */ long long namelen = 0; /* <= sizeof name */ unsigned char ch; errno = EPROTO; if (n < 0) return 0; byte_zero(name, 256); for (;;) { if (!n) break; ch = *buf++; --n; if (ch == '.') { if (labellen > 0) { if (namelen + labellen + 1 > 255) return 0; name[namelen++] = labellen; byte_copy(name + namelen,labellen,label); namelen += labellen; labellen = 0; } continue; } if (ch == '\\') { if (!n) break; ch = *buf++; --n; if ((ch >= '0') && (ch <= '7')) { ch -= '0'; if (n && (*buf >= '0') && (*buf <= '7')) { ch <<= 3; ch += *buf - '0'; ++buf; --n; if (n && (*buf >= '0') && (*buf <= '7')) { ch <<= 3; ch += *buf - '0'; ++buf; --n; } } } } if (labellen >= sizeof label) return 0; label[labellen++] = ch; } if (labellen > 0) { if (namelen + labellen + 1 > 255) return 0; name[namelen++] = labellen; byte_copy(name + namelen,labellen,label); namelen += labellen; labellen = 0; } if (namelen + 1 > 255) return 0; name[namelen++] = 0; return 1; }
int main(void) { unsigned char b1[32]; unsigned char b2[32]; long long i, j; const char *x = "abcdefgh"; char y[8]; /* byte_zero test */ for (i = 0; i < 32; ++i) { for (j = 0; j < sizeof b1; ++j) b1[j] = 0; for (j = 0; j < sizeof b2; ++j) b2[j] = 0; b1[i] = 0xff; b2[i] = 0xff; byte_zero(b1, sizeof b1); if (byte_isequal(b1, 32, b2) != 0) fail("byte_zero failure"); } /* byte_isequal test */ for (i = 0; i < sizeof b1; ++i) b1[i] = 0xff; for (i = 0; i < sizeof b2; ++i) b2[i] = 0xff; if (byte_isequal(b1, 32, b2) == 0) fail("byte_isequal failure"); for (i = 0; i < 32; ++i) { b1[i] = 0; if (byte_isequal(b1, 32, b2) != 0) fail("byte_isequal failure"); b1[i] = 0xff; } /* byte_copy test */ for (i = 0; i < sizeof b1; ++i) b1[i] = 0xff; for (i = 0; i < sizeof b2; ++i) b2[i] = 0x00; byte_copy(b1, 32, b2); if (byte_isequal(b1, 32, b2) == 0) fail("byte_copy failure"); for (i = 0; i < 32; ++i) { b1[i] = 0; byte_copy(b1, 32, b2); if (byte_isequal(b1, 32, b2) == 0) fail("byte_copy failure"); b1[i] = 0xff; } byte_zero(y, 8); if (!byte_isequal(y, 8, "\0\0\0\0\0\0\0\0")) fail("byte_zero/byte_isequal failure"); byte_copy(y, 8, x); if (!byte_isequal(y, 8, x)) fail("byte_copy/byte_isequal failure"); byte_copy(y, 7, y + 1); if (!byte_isequal(y, 8, "bcdefghh")) fail("byte_copy/byte_isequal failure"); byte_zero(y, 8); if (!byte_isequal(y, 8, "\0\0\0\0\0\0\0\0")) fail("byte_zero/byte_isequal failure"); return 0; }
int socket_bind(int fd,const unsigned char *ip,const unsigned char *port) { struct sockaddr_in sa; byte_zero(&sa,sizeof sa); sa.sin_family = PF_INET; byte_copy(&sa.sin_addr,4,ip); byte_copy(&sa.sin_port,2,port); return bind(fd,(struct sockaddr *) &sa,sizeof sa); }
static void swap(unsigned char *x, long long len, unsigned char *y) { unsigned char t[33]; byte_copy(t, len, x); byte_copy(x, len, y); byte_copy(y, len, t); }
void random_unsort (char *s, unsigned int n, unsigned int chunksize) { char tmp[chunksize] ; while (n--) { register unsigned int i = badrandom_int(n+1) ; byte_copy(tmp, chunksize, s + i * chunksize) ; byte_copy(s + i * chunksize, chunksize, s + n * chunksize) ; byte_copy(s + n * chunksize, chunksize, tmp) ; } }
int main (int argc, char const *const *argv) { s6_svstatus_t status ; char fmt[UINT_FMT] ; int isup, normallyup ; PROG = "s6-svstat" ; if (argc < 2) strerr_dieusage(100, USAGE) ; argv++ ; argc-- ; if (!s6_svstatus_read(*argv, &status)) strerr_diefu2sys(111, "read status for ", *argv) ; { struct stat st ; unsigned int dirlen = str_len(*argv) ; char fn[dirlen + 6] ; byte_copy(fn, dirlen, *argv) ; byte_copy(fn + dirlen, 6, "/down") ; if (stat(fn, &st) == -1) if (errno != ENOENT) strerr_diefu2sys(111, "stat ", fn) ; else normallyup = 1 ; else normallyup = 0 ; } taia_now_g() ; if (taia_future(&status.stamp)) taia_copynow(&status.stamp) ; taia_sub(&status.stamp, &STAMP, &status.stamp) ; isup = status.pid && !status.flagfinishing ; if (isup) { buffer_putnoflush(buffer_1small,"up (pid ", 8) ; buffer_putnoflush(buffer_1small, fmt, uint_fmt(fmt, status.pid)) ; buffer_putnoflush(buffer_1small, ") ", 2) ; } else buffer_putnoflush(buffer_1small, "down ", 5) ; buffer_putnoflush(buffer_1small, fmt, uint64_fmt(fmt, status.stamp.sec.x)) ; buffer_putnoflush(buffer_1small," seconds", 8) ; if (isup && !normallyup) buffer_putnoflush(buffer_1small, ", normally down", 15) ; if (!isup && normallyup) buffer_putnoflush(buffer_1small, ", normally up", 13) ; if (isup && status.flagpaused) buffer_putnoflush(buffer_1small, ", paused", 8) ; if (!isup && (status.flagwant == 'u')) buffer_putnoflush(buffer_1small, ", want up", 10) ; if (isup && (status.flagwant == 'd')) buffer_putnoflush(buffer_1small, ", want down", 12) ; if (buffer_putflush(buffer_1small, "\n", 1) == -1) strerr_diefu1sys(111, "write to stdout") ; return 0 ; }
/* * dAVLInsert: * Create a new node and insert an item there. * * Returns 0 on success, * -1 on malloc failure, * 3 if duplicate key. */ int dAVLInsert (dAVLTree *avltree, uint32 uid, char *ip4, char *ip6, char *loc) { dAVLNode *newnode; dAVLNode *node; dAVLNode *balnode; dAVLNode *nextbalnode; newnode = malloc(sizeof(dAVLNode)); if (newnode == NULL) return -1; newnode->key = uid; byte_copy(newnode->ip4, 4, ip4); byte_copy(newnode->ip6, 16, ip6); byte_copy(newnode->loc, 16, loc); newnode->depth = 1; newnode->left = NULL; newnode->right = NULL; newnode->parent = NULL; if (avltree->top != NULL) { node = dAVLCloseSearchNode(avltree, newnode->key); /* XXX: handle this more intelligent */ if (node->key == newnode->key) { free(newnode); return 3; } newnode->parent = node; if (newnode->key < node->key) { node->left = newnode; node->depth = CALC_DEPTH(node); } else { node->right = newnode; node->depth = CALC_DEPTH(node); } for (balnode = node->parent; balnode; balnode = nextbalnode) { nextbalnode = balnode->parent; dAVLRebalanceNode(avltree, balnode); } } else { avltree->top = newnode; } avltree->count++; return 0; }
int s6_svc_writectl (char const *service, char const *subdir, char const *s, unsigned int len) { unsigned int svlen = str_len(service) ; unsigned int sublen = str_len(subdir) ; char fn[svlen + sublen + 10] ; byte_copy(fn, svlen, service) ; fn[svlen] = '/' ; byte_copy(fn + svlen + 1, sublen, subdir) ; byte_copy(fn + svlen + 1 + sublen, 9, "/control") ; return s6_svc_write(fn, s, len) ; }
static int xsocket_connect4(int s, const unsigned char *ip, const unsigned char *port, long long id) { struct sockaddr_in sa; if (!byte_isequal("\0\0\0\0\0\0\0\0\0\0\377\377", 12, ip)) { errno = EPROTO; return -1; } byte_zero(&sa, sizeof sa); sa.sin_family = PF_INET; byte_copy(&sa.sin_addr, 4, ip + 12); byte_copy(&sa.sin_port, 2, port); return connect(s, (struct sockaddr *)&sa, sizeof sa); }
void stralloc_reverse_blocks (stralloc *sa, unsigned int size) { register unsigned int n = sa->len / (size << 1) ; register unsigned int i = 0 ; char tmp[size] ; for (; i < n ; i++) { byte_copy(tmp, size, sa->s + i * size) ; byte_copy(sa->s + i * size, size, sa->s + (2*n - 1 - i) * size) ; byte_copy(sa->s + (2*n - 1 - i) * size, size, tmp) ; } }
int buffer_putalign(buffer *s,const char *buf,unsigned int len) { unsigned int n; while (len > (n = s->n - s->p)) { byte_copy(s->x + s->p,n,buf); s->p += n; buf += n; len -= n; if (buffer_flush(s) == -1) return -1; } /* now len <= s->n - s->p */ byte_copy(s->x + s->p,len,buf); s->p += len; return 0; }
int substdio_bput(substdio *s,const char *buf,int len) { int n; while (len > (n = s->n - s->p)) { byte_copy(s->x + s->p,n,buf); s->p += n; buf += n; len -= n; if (substdio_flush(s) == -1) return -1; } /* now len <= s->n - s->p */ byte_copy(s->x + s->p,len,buf); s->p += len; return 0; }
unsigned int bu_fmt (char *s, uint32 const *x, unsigned int n) { unsigned int len = 0 ; while (n--) { char fmt[8] ; unsigned int i = uint32_xfmt(fmt, x[n]) ; byte_copy(s+len, 8-i, "00000000") ; byte_copy(s+len+8-i, i, fmt) ; len += 8 ; } return len ; }
int buffer_putalign(buffer* b,const char* buf,size_t len) { unsigned int tmp; while (len>(tmp=b->a-b->p)) { byte_copy(b->x+b->p, tmp, buf); b->p+=tmp; buf+=tmp; len-=tmp; if (buffer_flush(b)<0) return -1; } byte_copy(b->x+b->p, len, buf); b->p+=len; return 0; }
static int init(char ip[64]) { int i; unsigned int j; int iplen = 0; char *x; x = env_get("DNSCACHEIP"); if (x) while (iplen <= 60) { if (*x == '.') ++x; else { i = ip4_scan(x,ip + iplen); if (!i) break; x += i; iplen += 4; } } if (!iplen) { 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;j < data.len;++j) if (data.s[j] == '\n') { if (byte_equal("nameserver ",11,data.s + i) || byte_equal("nameserver\t",11,data.s + i)) { i += 10; while ((data.s[i] == ' ') || (data.s[i] == '\t')) ++i; if (iplen <= 60) if (ip4_scan(data.s + i,ip + iplen)) { if (byte_equal(ip + iplen,4,"\0\0\0\0")) byte_copy(ip + iplen,4,"\177\0\0\1"); iplen += 4; } } i = j + 1; } } } if (!iplen) { byte_copy(ip,4,"\177\0\0\1"); iplen = 4; } byte_zero(ip + iplen,64 - iplen); return 0; }
int ftrig1_make (ftrig1 *f, char const *path) { ftrig1 ff = FTRIG1_ZERO ; unsigned int pathlen = str_len(path) ; int e = 0 ; char tmp[pathlen + 46 + FTRIG1_PREFIXLEN] ; byte_copy(tmp, pathlen, path) ; tmp[pathlen] = '/' ; tmp[pathlen+1] = '.' ; byte_copy(tmp + pathlen + 2, FTRIG1_PREFIXLEN, FTRIG1_PREFIX) ; tmp[pathlen + 2 + FTRIG1_PREFIXLEN] = ':' ; if (!timestamp(tmp + pathlen + 3 + FTRIG1_PREFIXLEN)) return 0 ; tmp[pathlen + 28 + FTRIG1_PREFIXLEN] = ':' ; if (random_name(tmp + pathlen + 29 + FTRIG1_PREFIXLEN, 16) < 16) return 0 ; tmp[pathlen + 45 + FTRIG1_PREFIXLEN] = 0 ; { mode_t m = umask(0) ; if (fifo_make(tmp, S_IRUSR|S_IWUSR|S_IWGRP|S_IWOTH) == -1) { umask(m) ; return 0 ; } umask(m) ; } if (!stralloc_catb(&ff.name, tmp, pathlen+1)) { e = errno ; goto err0 ; } if (!stralloc_catb(&ff.name, tmp + pathlen + 2, FTRIG1_PREFIXLEN + 44)) { e = errno ; goto err1 ; } ff.fd = open_read(tmp) ; if (ff.fd == -1) { e = errno ; goto err1 ; } ff.fdw = open_write(tmp) ; if (ff.fdw == -1) { e = errno ; goto err2 ; } if (rename(tmp, ff.name.s) == -1) goto err3 ; *f = ff ; return 1 ; err3: e = errno ; fd_close(ff.fdw) ; err2: fd_close(ff.fd) ; err1: stralloc_free(&ff.name) ; err0: unlink(tmp) ; errno = e ; return 0 ; }
void dns_sortip6(char *s,unsigned int n) { unsigned int i; char tmp[16]; n >>= 4; while (n > 1) { i = dns_random(n); --n; byte_copy(tmp,16,s + (i << 4)); byte_copy(s + (i << 4),16,s + (n << 4)); byte_copy(s + (n << 4),16,tmp); } }
void dns_sortip(char *s,unsigned int n) { unsigned int i; char tmp[4]; n >>= 2; while (n > 1) { i = dns_random(n); --n; byte_copy(tmp,4,s + (i << 2)); byte_copy(s + (i << 2),4,s + (n << 2)); byte_copy(s + (n << 2),4,tmp); } }
ssize_t socket_send6(int s,const char *buf,size_t len,const char ip[16],uint16 port,uint32 scope_id) { #ifdef LIBC_HAS_IP6 struct sockaddr_in6 si; #else struct sockaddr_in si; #endif byte_zero(&si,sizeof si); #ifdef LIBC_HAS_IP6 if (noipv6) { #endif if (ip6_isv4mapped(ip)) return socket_send4(s,buf,len,ip+12,port); if (byte_equal(ip,16,V6loopback)) return socket_send4(s,buf,len,ip4loopback,port); #ifdef LIBC_HAS_IP6 errno=EPROTONOSUPPORT; return -1; } si.sin6_family = AF_INET6; uint16_pack_big((char *) &si.sin6_port,port); byte_copy((char *) &si.sin6_addr,16,ip); #ifdef LIBC_HAS_SCOPE_ID si.sin6_scope_id=scope_id; #else si.sin6_scope_id=0; #endif return winsock2errno(sendto(s,buf,len,0,(void*) &si,sizeof si)); #else errno=EPROTONOSUPPORT; return -1; #endif }
int response_addname(char *d) { unsigned int dlen; unsigned int i; char buf[2]; dlen = dns_domain_length(d); while (*d) { for (i = 0;i < name_num;++i) if (dns_domain_equal(d,name[i])) { uint16_pack_big(buf,49152 + name_ptr[i]); return response_addbytes(buf,2); } if (dlen <= 128) if (name_num < NAMES) { byte_copy(name[name_num],dlen,d); name_ptr[name_num] = response_len; ++name_num; } i = (unsigned char) *d; ++i; if (!response_addbytes(d,i)) return 0; d += i; dlen -= i; } return response_addbytes(d,1); }