From 51b913eb2ff91adfe8cd5e417759a6057c5a8a21 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Thu, 13 Nov 2008 16:17:55 +0000 Subject: XBitTorrent --- tools.c | 230 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 tools.c (limited to 'tools.c') diff --git a/tools.c b/tools.c new file mode 100644 index 0000000..d9264f6 --- /dev/null +++ b/tools.c @@ -0,0 +1,230 @@ +/* $Id$ */ +/* + * Copyright (c) 2005 Dimitri Sokolyuk + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include /* struct timeval */ +#include +#include +#include +#include +#include /* setsockopt() */ + +#include +#include /* open() */ +#include +#include +#include /* strlcat() */ +#include /* sysconf() */ +#include "meta.h" /* SHA1LEN */ +#include "tools.h" +#include "version.h" + +#ifndef lint +static const char rcsid[] = "@(#)$Id$"; +#endif /* not lint */ + +int +raisenofile(void) +{ + struct rlimit rl; + + if (getrlimit(RLIMIT_NOFILE, &rl) == 0) { + rl.rlim_cur = rl.rlim_max; + return setrlimit(RLIMIT_NOFILE, &rl); + } + return -1; +} + +/* usable file desctriptors */ +int +nofile(void) +{ + struct rlimit rl; + struct stat st; + int i, ret; + + if (getrlimit(RLIMIT_NOFILE, &rl) == 0) { + ret = i = rl.rlim_cur; + while (i) + if (!fstat(--i, &st)) + --ret; + return ret; + } + return -1; +} + + +int +bthexdump(char *dst, u_char *src, int len) +{ + /* src is a SHA1 hash and is 20 bytes long + * dst should be at least 41 bytes long for a simple hexdump, + * and 61 bytes long for a quoted printable + * (including the terminating `\0' character) + */ + int i, done; + char *fmt; + + if (len <= 2 * SHA1LEN) + return -1; + + for (i = SHA1LEN, done = 0, *dst = NULL; i > 0; i--) { + if (len > 3 * SHA1LEN) { + if (isascii(*src) && (isalnum(*src) || + *src == '-' || *src == '.' || + *src == '_' || *src == '~')) + fmt = "%c"; + else + fmt = "%%%.2X"; + } else + fmt = "%.2x"; + done += snprintf(dst + done, len - done, fmt, *src++); + } + + return done; +} + +char * +btfreadall(char *name) +{ + FILE *fd; + char *buf; + off_t len; + + if ((fd = fopen(name, "r")) == NULL) + return NULL; + + fseek(fd, 0L, SEEK_END); + len = ftell(fd); + fseek(fd, 0L, SEEK_SET); + + if ((buf = calloc(len, sizeof(char))) != NULL) + if ((fread(buf, sizeof(char), len, fd)) == 0) { + free(buf); + return NULL; + } + + fclose(fd); + + return buf; +} + +#if MMAP +void * +btmmapfile(char *name, off_t *len) +{ + struct stat stat; + int fd; + off_t page; + void *buf; + + if ((fd = open(name, O_RDONLY)) == -1) { + perror("open"); + return NULL; + } + + if (fstat(fd, &stat) == -1) { + perror("fstat"); + close(fd); + return NULL; + } + + page = sysconf(_SC_PAGESIZE); + *len = stat.st_size; + if (*len == 0) + return NULL; + *len += page - (*len % page); + + if ((buf = mmap((void *) NULL, *len, PROT_READ, MAP_SHARED, fd, 0L)) == NULL) { + perror("mmap"); + close(fd); + return NULL; + } + + close(fd); + + return buf; +} + +void +btunmapfile(void *buf, off_t len) +{ + munmap(buf, len); +} +#endif /* MMAP */ + +void +btpeerid(u_char *str) +{ + const char hex[16] = "0123456789ABCDEF"; + int i; + + /* we only use unreserved characters (RFC 3986) as PEER_ID, + * so we don't need to percent-encode them and + * it's still random enough (16^12 possibilities) + * OBSOLETE since we use array to store that value + */ + snprintf((char *) str, 9, "-XB%.2d%.2d-", VERSION_MAJOR, VERSION_MINOR); + for (i = 8; i < SHA1LEN; i++) + str[i] = hex[arc4random() % sizeof(hex)]; +} + +__dead void +usage(const char *usagearg) +{ + extern char *__progname; + + fprintf(stderr, "usage: %s %s\n", __progname, usagearg); + exit(1); +} + +int +setrcvtimeo(int s, int msec) +{ + struct timeval tv; + + tv.tv_sec = msec / 1000; + tv.tv_usec = (msec % 1000) * 1000; + + return setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)); +} + +void +twiddle(void) +{ + static int pos; + + putchar("|/-\\"[pos++ & 3]); + putchar('\b'); +} + +char * +metric(double len) +{ + static char buf[16]; + char *units[] = { + "B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", NULL + }; + int n = 0; + + for (n = 0; len >= 1024 && n < sizeof(units) / sizeof(units[0]); n++) + len /= 1024; + + snprintf(buf, sizeof(buf), "%.2f %s", len, units[n]); + + return buf; +} -- cgit v1.2.3