void sigchld() { int wstat; int pid; while ((pid = wait_nohang(&wstat)) > 0) { if (verbosity >= 2) { errlog(0,NOTICE,B("end ",fmtnum(pid)," status ",fmtnum(wstat))); } if (numchildren) { --numchildren; } printstatus(); } }
/* xprange: calcuate the amount of xp between the levels in args */ static int xprange(char *out, struct command *c) { int64_t x, y; char *a, *b; char num[RSN_BUF]; if (l_optind == c->argc || l_optind < c->argc - 2) { USAGEMSG(out, CMDNAME, RUSAGE); return EXIT_FAILURE; } a = c->argv[l_optind]; if (l_optind == c->argc - 1) { if (!(b = strchr(a, '-')) || !b[1]) { snprintf(out, MAX_MSG, "%s: must provide two levels", c->argv[0]); return EXIT_FAILURE; } *b++ = '\0'; } else { b = c->argv[l_optind + 1]; } if (!parsenum_mult(a, &x)) { snprintf(out, MAX_MSG, "%s: invalid number: %s", c->argv[0], a); return EXIT_FAILURE; } if (x < 1 || x > 126) { snprintf(out, MAX_MSG, "%s: level must be between 1-126", c->argv[0]); return EXIT_FAILURE; } if (!parsenum_mult(b, &y)) { snprintf(out, MAX_MSG, "%s: invalid number: %s", c->argv[0], b); return EXIT_FAILURE; } if (y < 1 || y > 126) { snprintf(out, MAX_MSG, "%s: level must be between 1-126", c->argv[0]); return EXIT_FAILURE; } if (x > y) { snprintf(out, MAX_MSG, "%s: invalid range", c->argv[0]); return EXIT_FAILURE; } x = lvltoxp(x); y = lvltoxp(y); snprintf(out, MAX_MSG, "%ld", y - x); fmtnum(num, RSN_BUF, out); snprintf(out, MAX_MSG, "[XP] level %s-%s: %s xp", a, b, num); return EXIT_SUCCESS; }
/* lookup_player: look up rsn on cml, write EHP data to out */ static int lookup_player(char *out, const char *rsn, const char *fil, const char *type) { cpr::Response resp; char buf[MAX_URL]; char num[MAX_URL]; char *name, *rank, *ehp, *week, *s; snprintf(buf, MAX_URL, "%s%s%s&player=%s", CML_HOST, EHP_API, fil, rsn); resp = cpr::Get(cpr::Url(buf)); strcpy(buf, resp.text.c_str()); if (strlen(buf) == 0 || strcmp(buf, "-3") == 0 || strcmp(buf, "-4") == 0) { snprintf(out, MAX_MSG, "%s: could not reach CML API, try again", CMDNAME); return EXIT_FAILURE; } if (strcmp(buf, "-1") == 0) { if (*fil) { fil = strchr(fil, '=') + 1; snprintf(out, MAX_MSG, "%s: player '%s' not found under" " %s filter", CMDNAME, rsn, fil); } else { snprintf(out, MAX_MSG, "%s: player '%s' does not exist " "or has not been tracked on CML", CMDNAME, rsn); } return EXIT_FAILURE; } /* extract and format data from buf */ rank = buf; name = strchr(rank, ','); *name++ = '\0'; ehp = strchr(name, ','); *ehp++ = '\0'; if ((week = strchr(ehp, ','))) *week++ = '\0'; if ((s = strchr(ehp, '.'))) s[3] = '\0'; fmtnum(num, MAX_URL, ehp); snprintf(out, MAX_MSG, "[EHP%s] Name: %s, Rank: %s, EHP: %s", type, name, rank, num); if (!*type) { out = strchr(out, '\0'); snprintf(out, MAX_MSG, " (+%s this week)", *week ? week : "0.00"); } return EXIT_SUCCESS; }
static void dopr(char *buffer, const char *format, va_list args) { int ch; long value; int longflag = 0; char *strvalue; int ljust; int len; int zpad; int precision; int set_precision; double dval; output = buffer; while ((ch = *format++)) { switch (ch) { case '%': ljust = len = zpad = 0; precision = -1; set_precision = 0; nextch: ch = *format++; switch (ch) { case 0: dostr("**end of format**"); return; case '-': ljust = 1; goto nextch; case '.': set_precision = 1; precision = 0; goto nextch; case '*': len = va_arg(args, int); goto nextch; case '0': /* set zero padding if len not set */ if (len == 0 && set_precision == 0) zpad = '0'; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (set_precision) { precision = precision * 10 + ch - '0'; } else { len = len * 10 + ch - '0'; } goto nextch; case 'l': longflag = 1; goto nextch; case 'u': case 'U': /*fmtnum(value,base,dosign,ljust,len, zpad, precision) */ if (longflag) { value = va_arg(args, long); } else { value = va_arg(args, int); } fmtnum(value, 10, 0, ljust, len, zpad, precision); break; case 'o': case 'O': /*fmtnum(value,base,dosign,ljust,len, zpad, precision) */ if (longflag) { value = va_arg(args, long); } else { value = va_arg(args, int); } fmtnum(value, 8, 0, ljust, len, zpad, precision); break; case 'd': case 'i': case 'D': if (longflag) { value = va_arg(args, long); } else { value = va_arg(args, int); } fmtnum(value, 10, 1, ljust, len, zpad, precision); break; case 'x': if (longflag) { value = va_arg(args, long); } else {
static void dopr(char *buffer, const char *format, va_list args) { int ch; long_long value; double fvalue; int longlongflag = 0; int longflag = 0; int pointflag = 0; int maxwidth = 0; char *strvalue; int ljust; int len; int zpad; output = buffer; while ((ch = *format++)) { switch (ch) { case '%': ljust = len = zpad = maxwidth = 0; longflag = longlongflag = pointflag = 0; nextch: ch = *format++; switch (ch) { case 0: dostr("**end of format**", 0); *output = '\0'; return; case '-': ljust = 1; goto nextch; case '0': /* set zero padding if len not set */ if (len == 0 && !pointflag) zpad = '0'; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (pointflag) maxwidth = maxwidth * 10 + ch - '0'; else len = len * 10 + ch - '0'; goto nextch; case '*': if (pointflag) maxwidth = va_arg(args, int); else len = va_arg(args, int); goto nextch; case '.': pointflag = 1; goto nextch; case 'l': if (longflag) longlongflag = 1; else longflag = 1; goto nextch; case 'u': case 'U': /* fmtnum(value,base,dosign,ljust,len,zpad) */ if (longflag) { if (longlongflag) value = va_arg(args, ulong_long); else value = va_arg(args, unsigned long); } else value = va_arg(args, unsigned int); fmtnum(value, 10, 0, ljust, len, zpad); break; case 'o': case 'O': /* fmtnum(value,base,dosign,ljust,len,zpad) */ if (longflag) { if (longlongflag) value = va_arg(args, ulong_long); else value = va_arg(args, unsigned long); } else value = va_arg(args, unsigned int); fmtnum(value, 8, 0, ljust, len, zpad); break; case 'd': case 'i': case 'D': if (longflag) { if (longlongflag) value = va_arg(args, long_long); else value = va_arg(args, long); } else
int vsnprintf(char *buf, int size, const char *fmt, va_list va) { pstream_t s; s.buffer = buf; s.remain = size - 1; s.added = 0; while (*fmt) { char f = *fmt++; int nlong = 0; strprops_t props; memset(&props, 0, sizeof(props)); props.pad = ' '; if (f != '%') { addchar(&s, f); continue; } morefmt: f = *fmt++; switch (f) { case '%': addchar(&s, '%'); break; case 'c': addchar(&s, va_arg(va, int)); break; case '\0': --fmt; break; case '0': props.pad = '0'; ++fmt; /* fall through */ case '1'...'9': case '-': --fmt; props.npad = fmtnum(&fmt); goto morefmt; case 'l': ++nlong; goto morefmt; case 'd': switch (nlong) { case 0: print_int(&s, va_arg(va, int), 10, props); break; case 1: print_int(&s, va_arg(va, long), 10, props); break; default: print_int(&s, va_arg(va, long long), 10, props); break; } break; case 'u': switch (nlong) { case 0: print_unsigned(&s, va_arg(va, unsigned), 10, props); break; case 1: print_unsigned(&s, va_arg(va, unsigned long), 10, props); break; default: print_unsigned(&s, va_arg(va, unsigned long long), 10, props); break; } break; case 'x': switch (nlong) { case 0: print_unsigned(&s, va_arg(va, unsigned), 16, props); break; case 1: print_unsigned(&s, va_arg(va, unsigned long), 16, props); break; default: print_unsigned(&s, va_arg(va, unsigned long long), 16, props); break; } break; case 'p': print_str(&s, "0x", props); print_unsigned(&s, (unsigned long)va_arg(va, void *), 16, props); break; case 's': print_str(&s, va_arg(va, const char *), props); break; default: addchar(&s, f); break; } } *s.buffer = 0; ++s.added; return s.added; }
void printstatus(void) { if (verbosity < 2) return; log(B("status: ",fmtnum(numchildren),"/",fmtnum(limit))); }
/* xp: query experience information */ int CmdHandler::xp(char *out, struct command *c) { int inv, range, status; int64_t x; char num[RSN_BUF]; int opt; static struct l_option long_opts[] = { { "help", NO_ARG, 'h' }, { "inverse", NO_ARG, 'i' }, { "range", NO_ARG, 'r' }, { 0, 0, 0 } }; inv = range = 0; status = EXIT_SUCCESS; opt_init(); while ((opt = l_getopt_long(c->argc, c->argv, "ir", long_opts)) != EOF) { switch (opt) { case 'h': HELPMSG(out, CMDNAME, CMDUSAGE, CMDDESCR); return EXIT_SUCCESS; case 'i': inv = 1; break; case 'r': range = 1; break; case '?': snprintf(out, MAX_MSG, "%s", l_opterr()); return EXIT_FAILURE; default: return EXIT_FAILURE; } } if (range) { if (inv) { snprintf(out, MAX_MSG, "%s: cannot use -i with -r", c->argv[0]); status = EXIT_FAILURE; } else { status = xprange(out, c); } return status; } if (l_optind != c->argc - 1) { USAGEMSG(out, CMDNAME, CMDUSAGE); return EXIT_FAILURE; } if (!parsenum_mult(c->argv[l_optind], &x)) { snprintf(out, MAX_MSG, "%s: invalid number: %s", c->argv[0], c->argv[l_optind]); return EXIT_FAILURE; } if (x < 0) { snprintf(out, MAX_MSG, "%s: number cannot be " "negative", c->argv[0]); return EXIT_FAILURE; } if (inv) { if (x > MAX_XP) { snprintf(out, MAX_MSG, "%s: xp cannot exceed 200m", c->argv[0]); status = EXIT_FAILURE; } else { snprintf(out, MAX_MSG, "%ld", x); fmtnum(num, RSN_BUF, out); snprintf(out, MAX_MSG, "[XP] %s xp: level %d", num, xptolvl(x)); } return status; } if (x < 1 || x > 126) { snprintf(out, MAX_MSG, "%s: level must be between 1-126", c->argv[0]); status = EXIT_FAILURE; } else { snprintf(out, MAX_MSG, "%d", lvltoxp(x)); fmtnum(num, RSN_BUF, out); snprintf(out, MAX_MSG, "[XP] level %ld: ", x); strcat(out, num); strcat(out, " xp"); } return status; }