static void saftyexit(int status) { setdefaultcolor(); newline(); if (uflag) { cursorunsave(); } cursorshow(); exit(status); }
int main(int argc, char *argv[]) { char *endptr; int ch, result, i, j, status, filemode; signal(SIGINT, interuppthandler); signal(SIGQUIT, interuppthandler); signal(SIGTERM, interuppthandler); signal(SIGFPE, interuppthandler); signal(SIGSEGV, interuppthandler); rval = 1; status = EXIT_SUCCESS; while ((ch = getopt(argc, argv, ":iqds:r:vLRCTBP!ecEuw:h:W:H:S:")) != -1) { switch (ch) { case 'i': iflag = 1; break; case 'q': qflag = 1; break; case 'd': dflag = 1; break; case 's': sflag = 1; sval = 0; PARSEARGD(sval); break; case 'r': rflag = 1; rval = 0; PARSEARGL(rval); break; case 'v': version(); break; /* exit */ case 'L': if (Pflag) { PLflag = 1; } else { Lflag = 1; } break; case 'R': if (Pflag) { PRflag = 1; } else { Rflag = 1; } break; case 'C': if (Pflag) { PCflag = 1; } else { Cflag = 1; } break; case 'T': if (Pflag) { PTflag = 1; PBflag = 0; } else { Tflag = 1; Bflag = 0; } break; case 'B': if (Pflag) { PBflag = 1; PTflag = 0; } else { Bflag = 1; Tflag = 0; } break; case 'P': Pflag = 1; break; case 'E': Eflag = 1; break; case '!': EXCflag = 1; break; case 'w': wflag = 1; PARSEARGL(wval); break; case 'h': hflag = 1; PARSEARGL(hval); break; case 'W': Wflag = 1; PARSEARGL(Wval); break; case 'H': Hflag = 1; PARSEARGL(Hval); break; case 'S': Sflag = 1; Sval = 1; PARSEARGD(Sval); break; case 'e': eflag = 1; break; case 'c': cflag = 1; break; /* * o: offset (%) * O: offset (character) 0,-20 */ case 'u': uflag = 1; break; /* TODO */ case ':': switch (optopt) { case 'w': wflag = 1; wval = 100; break; case 'h': hflag = 1; hval = 100; break; case 's': sflag = 1; sval = 0; break; case 'r': rflag = 1; rval = 0; break; case 'S': Sflag = 1; Sval = 1; break; default: usage(); } break; case '?': WARNX("illegal option -- %c", optopt); /* fall through */ default: usage(); /* exit */ } } argc -= optind; argv += optind; if (EXCflag) { position(); /* exit */ } /* we expect file as arguments here, but if nothing specified, use stdin */ if (argc <= 0) { /* but, if stdin has no data, display usage and finish process */ if (checkstdin() != 0) { usage(); } argc = 1; rval = 1; filemode = 0; } else { filemode = 1; } cursorhide(); if (uflag) { cursorsave(); } /* main process */ for (i = 0; i < rval || rval <= 0; ) { /* for all over the files */ for (j = 0; j < argc; j++) { /* deal an image file */ if (filemode) { result = dealfile(argv[j]); } else { result = deal(stdin, STDIN_PATH, 1); } /* if everything went well */ if (result == 0) { /* and in slideshow mode */ if (sflag && sval > 0) { usleep(sval * 1e6); } } else { /* fail and no error so far */ if (status == EXIT_SUCCESS) { status = EXIT_FAILURE; } } } if (rval > 0) { i++; } } if (uflag) { cursorunsave(); } cursorshow(); return status; }
static int deal(FILE *fp, char *filename, int pipemode) { color *image; void (*outputcolor)(); int width, height, comp, i, j, istep, jstep, ch, scale, scalew, scaleh, offset, imagewidth, imageheight, margintopbottom, marginleftright, marginleft, margintop, paddingtopbottom, paddingleftright, paddingleft, paddingright, paddingtop, paddingbottom, ipaddingleftright, ipaddingleft, ipaddingright; image = stbi_load_from_file(fp, &width, &height, &comp, 0); /* error handling */ if (image == NULL) { if ((!qflag) && (stbi_failure_reason() != NULL)) warnx("%s: %s", filename, stbi_failure_reason()); goto ERR_DEAL; } if (width <= 0 || height <= 0) { if (!qflag) warnx("%s %s (width: %d, height: %d)", filename, "is an invalid image", width, height); goto ERR_DEAL; } /* ok, it is surely a valid image */ /* get terminal size before processing each image */ terminalsize(); /* set scale parameters */ scale = 1; if (Sflag) { if (cflag) outputcolor = outputcolor_3; else outputcolor = outputcolor_1; scale = (int)Sval; /* TODO */ istep = 2 * (jstep = scale); imageheight = (int)ceil((double)height / (double)istep); imagewidth = (int)ceil((double)width / (double)jstep); } else if (2 * width <= outputwidth && height <= outputheight) { if (cflag) outputcolor = outputcolor_4; else outputcolor = outputcolor_2; istep = jstep = 1; imagewidth = width * 2; imageheight = height; } else { if (cflag) outputcolor = outputcolor_3; else outputcolor = outputcolor_1; scalew = (int)ceil((double)width / (double)outputwidth); scaleh = (int)ceil((double)height / 2.0 / (double)outputheight); if (Hval == 0 && hval == 0 && (wval > 0 || Wval > 0)) scale = scalew; else if ((hval > 0 || Hval > 0) && wval == 0 && Wval == 0) scale = scaleh; else scale = ((scalew) > (scaleh) ? (scalew) : (scaleh)); istep = 2 * (jstep = scale); imageheight = (int)ceil((double)height / (double)istep); imagewidth = (int)ceil((double)width / (double)jstep); } if (istep * jstep >= INT_MAX / 256 || width * height >= INT_MAX / 3) { if (!qflag) warnx("%s %s (width: %d, height: %d)", filename, "is too large", width, height); goto ERR_DEAL; } /* setting parameters */ margintopbottom = terminalheight - outputheight - iflag; marginleftright = terminalwidth - outputwidth; paddingtopbottom = outputheight - imageheight; paddingleftright = outputwidth - imagewidth; if (Rflag && !Lflag) { marginleft = marginleftright; } else if (Lflag && !Rflag) { marginleft = 0; } else if ((Lflag && Rflag) || Cflag || Tflag || Bflag) { marginleft = marginleftright / 2; } else { marginleft = 0; } if (PRflag && !PLflag) { paddingleft = paddingleftright; } else if (PLflag && !PRflag) { paddingleft = 0; } else if ((PLflag && PRflag) || PCflag || PTflag || PBflag) { paddingleft = paddingleftright / 2; } else if (Rflag && !Lflag) { paddingleft = paddingleftright; } else if (Lflag && !Rflag) { paddingleft = 0; } else if ((Lflag && Rflag) || Cflag || Tflag || Bflag) { paddingleft = paddingleftright / 2; } else { paddingleft = 0; } if (Bflag) { margintop = margintopbottom; } else if (Tflag) { margintop = 0; } else if (Cflag) { margintop = margintopbottom / 2; } else { margintop = 0; } if (PBflag) { paddingtop = paddingtopbottom; } else if (PTflag) { paddingtop = 0; } else if (PCflag) { paddingtop = paddingtopbottom / 2; } else if (Bflag) { paddingtop = paddingtopbottom; } else if (Tflag) { paddingtop = 0; } else if (Cflag) { paddingtop = paddingtopbottom / 2; } else { paddingtop = 0; } paddingright = paddingleftright - paddingleft; paddingbottom = paddingtopbottom - paddingtop; /* start up */ setdefaultcolor(); if (uflag) { cursorhide(); cursorsave(); } /* main process */ if (Eflag && filecount == 0) erasescreen(); if (Cflag || Tflag || Bflag) { if (!eflag) { if (margintop >= 0) cursormove(margintop + 1, 1); for (i = 0; i < paddingtop; i++) { if (marginleft > 0) cursorforward(marginleft); replicatespace(outputwidth); cursordown_cursorhorizontalabsolute(); } } if (margintop + paddingtop >= 0) cursormove(margintop + paddingtop + 1, 1); } if (iflag) { ipaddingleftright = outputwidth - strlen(filename); if (PRflag && !PLflag) { ipaddingleft = ipaddingleftright; } else if (PLflag && !PRflag) { ipaddingleft = 0; } else if ((PLflag && PRflag) || PCflag || PTflag || PBflag) { ipaddingleft = ipaddingleftright / 2; } else if (Rflag && !Lflag) { ipaddingleft = ipaddingleftright; } else if (Lflag && !Rflag) { ipaddingleft = 0; } else if ((Lflag && Rflag) || Cflag || Tflag || Bflag) { ipaddingleft = ipaddingleftright / 2; } else { ipaddingleft = 0; } ipaddingright = ipaddingleftright - ipaddingleft; if (Cflag || Lflag || Rflag || Tflag || Bflag || PCflag || PLflag || PRflag || PTflag || PBflag) { if (marginleft > 0) cursorforward(marginleft); if (ipaddingleft > 0) { if (eflag) { cursorforward(ipaddingleft); } else { replicatespace(ipaddingleft); } } else if (ipaddingleftright < 0) { filename[outputwidth] = '\0'; } } printf("%s", filename); if (Cflag || Tflag || Bflag || PCflag || PTflag || PBflag) { if (ipaddingright > 0) { if (!eflag) { replicatespace(ipaddingright); } } if (Cflag || Tflag || Bflag) { cursordown_cursorhorizontalabsolute(); } else { newline(); } } else { newline(); } } for (i = 0; i < height; i += istep) { if (Cflag || Lflag || Rflag || Tflag || Bflag || PCflag || PLflag || PRflag || PTflag || PBflag) { if (marginleft > 0) cursorforward(marginleft); if (paddingleft > 0) { if (eflag) { cursorforward(paddingleft); } else { replicatespace(paddingleft); } } } for (j = 0; j < width; j += jstep) { offset = (i * width + j) * comp; outputcolor(image, height, width, offset, i, j, (i + istep > height ? height - i : istep), (j + jstep > width ? width - j : jstep), comp); } setdefaultcolor(); if (Cflag || Tflag || Bflag || PCflag || PTflag || PBflag) { if (paddingright > 0) { if (!eflag) { replicatespace(paddingright); } } if (Cflag || Tflag || Bflag) { cursordown_cursorhorizontalabsolute(); } else { newline(); } } else { newline(); } } if (Cflag || Tflag) { if (!eflag) { for (i = 0; i < paddingbottom; i++) { if (marginleft > 0) cursorforward(marginleft); if (outputwidth > 0) replicatespace(outputwidth); cursordown_cursorhorizontalabsolute(); } } } /* clean up */ setdefaultcolor(); if (uflag) { cursorunsave(); cursorshow(); } fflush(stdout); stbi_image_free(image); ++filecount; /* debug mode */ if (dflag) { cursorsave(); cursormove(1, 1); printf(PACKAGE); if (iflag) printf(" -i"); if (qflag) printf(" -q"); if (sflag) printf(" -s %lf", sval); if (rflag) printf(" -r %ld", rval); if (Lflag) printf(" -L"); if (Rflag) printf(" -R"); if (Cflag) printf(" -C"); if (Tflag) printf(" -T"); if (Bflag) printf(" -B"); if (Eflag) printf(" -E"); if (hflag) printf(" -h %ld", hval); if (Hflag) printf(" -H %ld", Hval); if (wflag) printf(" -w %ld", wval); if (Wflag) printf(" -W %ld", Wval); printf(" %s\n", filename); printf("terminalwidth: %d\n", terminalwidth); printf("terminalheight: %d\n", terminalheight); printf("outputwidth: %d\n", outputwidth); printf("outputheight: %d\n", outputheight); printf("imagewidth: %d\n", imagewidth); printf("imageheight: %d\n", imageheight); printf("margintop: %d\n", margintop); printf("marginleft: %d\n", marginleft); printf("paddingtop: %d\n", paddingtop); printf("paddingleft: %d\n", paddingleft); printf("paddingbottom: %d\n", paddingbottom); printf("paddingright: %d\n", paddingright); fflush(stdout); cursorunsave(); } /* check next file if pipe or fifo */ if (pipemode) { ch = getc(fp); if (ch != EOF) { if (ch != '\0' && ch != '\n') { ungetc(ch, fp); } else if ((ch = getc(fp)) != '\0' && ch != '\n') { ungetc(ch, fp); } else if ((ch = getc(fp)) != '\0' && ch != '\n') { ungetc(ch, fp); } if (ch != EOF) { if (sflag && sval > 0) { usleep(sval * 1e6); } deal(fp, filename, pipemode); } } } return 0; ERR_DEAL: return 1; }
void livetrafficmeter(char iface[32], int mode) { /* received bytes packets errs drop fifo frame compressed multicast */ /* transmitted bytes packets errs drop fifo colls carrier compressed */ uint64_t rx, tx, rxp, txp, timespent, timeslept; uint64_t rxtotal, txtotal, rxptotal, txptotal; uint64_t rxpmin, txpmin, rxpmax, txpmax; uint64_t rxmin, txmin, rxmax, txmax; uint64_t index = 1; int ratewidth, ppswidth, paddingwidth, json = 0; char buffer[256], buffer2[256]; IFINFO previnfo; if (cfg.qmode == 10) { json = 1; } if (!json) { printf("Monitoring %s... (press CTRL-C to stop)\n\n", iface); if (cfg.ostyle != 4) { printf(" getting traffic..."); fflush(stdout); } } /* enable signal trap */ intsignal = 0; if (signal(SIGINT, sighandler) == SIG_ERR) { perror("signal"); exit(EXIT_FAILURE); } /* set some defaults */ rxtotal = txtotal = rxptotal = txptotal = rxpmax = txpmax = 0; rxpmin = txpmin = rxmin = txmin = MAX64; rxmax = txmax = 0; timeslept = 0; timespent = (uint64_t)time(NULL); /* read /proc/net/dev and get values to the first list */ if (!getifinfo(iface)) { printf("Error: Interface \"%s\" not available, exiting.\n", iface); exit(EXIT_FAILURE); } ratewidth = 15; ppswidth = 5; paddingwidth = 8; /* narrow output mode */ if (cfg.ostyle == 0) { ratewidth = 12; ppswidth = 3; paddingwidth = 4; } if (!json) { cursorhide(); } else { printf("{\"jsonversion\":\"%d\",", JSONVERSION_LIVE); printf("\"vnstatversion\":\"%s\",", getversion()); printf("\"interface\":\"%s\",", iface); printf("\"sampletime\":%d}\n", LIVETIME); } /* loop until user gets bored */ while (intsignal == 0) { timeslept = (uint64_t)time(NULL); /* wait 2 seconds for more traffic */ sleep(LIVETIME); timeslept = (uint64_t)time(NULL) - timeslept; /* break loop without calculations because sleep was probably interrupted */ if (intsignal) { break; } /* use values from previous loop if this isn't the first time */ previnfo.rx = ifinfo.rx; previnfo.tx = ifinfo.tx; previnfo.rxp = ifinfo.rxp; previnfo.txp = ifinfo.txp; /* read those values again... */ if (!getifinfo(iface)) { cursorshow(); printf("Error: Interface \"%s\" not available, exiting.\n", iface); exit(EXIT_FAILURE); } /* calculate traffic and packets seen between updates */ rx = countercalc(&previnfo.rx, &ifinfo.rx, ifinfo.is64bit); tx = countercalc(&previnfo.tx, &ifinfo.tx, ifinfo.is64bit); rxp = countercalc(&previnfo.rxp, &ifinfo.rxp, ifinfo.is64bit); txp = countercalc(&previnfo.txp, &ifinfo.txp, ifinfo.is64bit); /* update totals */ rxtotal += rx; txtotal += tx; rxptotal += rxp; txptotal += txp; /* update min & max */ if (rxmin > rx) { rxmin = rx; } if (txmin > tx) { txmin = tx; } if (rxmax < rx) { rxmax = rx; } if (txmax < tx) { txmax = tx; } if (rxpmin > rxp) { rxpmin = rxp; } if (txpmin > txp) { txpmin = txp; } if (rxpmax < rxp) { rxpmax = rxp; } if (txpmax < txp) { txpmax = txp; } /* show the difference in a readable format or json */ if (!json) { if (mode == 0) { /* packets per second visible */ snprintf(buffer, 128, " rx: %s %*" PRIu64 " p/s", gettrafficrate(rx, LIVETIME, ratewidth), ppswidth, (uint64_t)rxp / LIVETIME); snprintf(buffer2, 128, " %*s tx: %s %*" PRIu64 " p/s", paddingwidth, " ", gettrafficrate(tx, LIVETIME, ratewidth), ppswidth, (uint64_t)txp / LIVETIME); } else { /* total transfer amount visible */ snprintf(buffer, 128, " rx: %s %s", gettrafficrate(rx, LIVETIME, ratewidth), getvalue(rxtotal, 1, RT_Normal)); snprintf(buffer2, 128, " %*s tx: %s %s", paddingwidth, " ", gettrafficrate(tx, LIVETIME, ratewidth), getvalue(txtotal, 1, RT_Normal)); } strcat(buffer, buffer2); if (cfg.ostyle != 4 || !debug) { cursortocolumn(1); eraseline(); } if (cfg.ostyle != 4) { printf("%s", buffer); fflush(stdout); } else { printf("%s\n", buffer); } } else { printf("{\"index\":%" PRIu64 ",", index); printf("\"seconds\":%" PRIu64 ",", (uint64_t)time(NULL) - timespent); printf("\"rx\":{"); printf("\"ratestring\":\"%s\",", gettrafficrate(rx, LIVETIME, 0)); printf("\"bytespersecond\":%" PRIu64 ",", (uint64_t)(rx / LIVETIME)); printf("\"packetspersecond\":%" PRIu64 ",", (uint64_t)(rxp / LIVETIME)); printf("\"bytes\":%" PRIu64 ",", rx); printf("\"packets\":%" PRIu64 ",", rxp); printf("\"totalbytes\":%" PRIu64 ",", rxtotal); printf("\"totalpackets\":%" PRIu64 "", rxptotal); printf("},"); printf("\"tx\":{"); printf("\"ratestring\":\"%s\",", gettrafficrate(tx, LIVETIME, 0)); printf("\"bytespersecond\":%" PRIu64 ",", (uint64_t)(tx / LIVETIME)); printf("\"packetspersecond\":%" PRIu64 ",", (uint64_t)(txp / LIVETIME)); printf("\"bytes\":%" PRIu64 ",", tx); printf("\"packets\":%" PRIu64 ",", txp); printf("\"totalbytes\":%" PRIu64 ",", txtotal); printf("\"totalpackets\":%" PRIu64 "", txptotal); printf("}}\n"); index++; } } timespent = (uint64_t)time(NULL) - timespent - timeslept; if (!json) { cursorshow(); printf("\n\n"); } /* print some statistics if enough time did pass */ if (!json && timespent >= 10) { printf("\n %s / traffic statistics\n\n", iface); printf(" rx | tx\n"); printf("--------------------------------------+------------------\n"); printf(" bytes %s", getvalue(rxtotal, 15, RT_Normal)); printf(" | %s", getvalue(txtotal, 15, RT_Normal)); printf("\n"); printf("--------------------------------------+------------------\n"); printf(" max %s", gettrafficrate(rxmax, LIVETIME, 15)); printf(" | %s\n", gettrafficrate(txmax, LIVETIME, 15)); printf(" average %s", gettrafficrate(rxtotal, (time_t)timespent, 15)); printf(" | %s\n", gettrafficrate(txtotal, (time_t)timespent, 15)); printf(" min %s", gettrafficrate(rxmin, LIVETIME, 15)); printf(" | %s\n", gettrafficrate(txmin, LIVETIME, 15)); printf("--------------------------------------+------------------\n"); printf(" packets %12" PRIu64 " | %12" PRIu64 "\n", rxptotal, txptotal); printf("--------------------------------------+------------------\n"); printf(" max %9" PRIu64 " p/s | %9" PRIu64 " p/s\n", rxpmax / LIVETIME, txpmax / LIVETIME); printf(" average %9" PRIu64 " p/s | %9" PRIu64 " p/s\n", rxptotal / timespent, txptotal / timespent); printf(" min %9" PRIu64 " p/s | %9" PRIu64 " p/s\n", rxpmin / LIVETIME, txpmin / LIVETIME); printf("--------------------------------------+------------------\n"); if (timespent <= 60) { printf(" time %9" PRIu64 " seconds\n", timespent); } else { printf(" time %7.2f minutes\n", timespent / (double)60); } printf("\n"); } else if (json) { printf("{\"seconds\":%" PRIu64 ",", timespent); printf("\"rx\":{"); printf("\"maxratestring\":\"%s\",", gettrafficrate(rxmax, LIVETIME, 0)); printf("\"averageratestring\":\"%s\",", gettrafficrate(rxtotal, (time_t)timespent, 0)); printf("\"minratestring\":\"%s\",", gettrafficrate(rxmin, LIVETIME, 0)); printf("\"totalbytes\":%" PRIu64 ",", rxtotal); printf("\"maxbytes\":%" PRIu64 ",", rxmax); printf("\"minbytes\":%" PRIu64 ",", rxmin); printf("\"totalpackets\":%" PRIu64 ",", rxptotal); printf("\"maxpackets\":%" PRIu64 ",", rxpmax); printf("\"minpackets\":%" PRIu64 "", rxpmin); printf("},"); printf("\"tx\":{"); printf("\"maxratestring\":\"%s\",", gettrafficrate(txmax, LIVETIME, 0)); printf("\"averageratestring\":\"%s\",", gettrafficrate(txtotal, (time_t)timespent, 0)); printf("\"minratestring\":\"%s\",", gettrafficrate(txmin, LIVETIME, 0)); printf("\"totalbytes\":%" PRIu64 ",", txtotal); printf("\"maxbytes\":%" PRIu64 ",", txmax); printf("\"minbytes\":%" PRIu64 ",", txmin); printf("\"totalpackets\":%" PRIu64 ",", txptotal); printf("\"maxpackets\":%" PRIu64 ",", txpmax); printf("\"minpackets\":%" PRIu64 "", txpmin); printf("}}\n"); } }