fprintf(stderr, "[ overhead BYTES ] [ linklayer TYPE ]\n");
}
-static void explain1(char *arg)
+static void explain1(const char *arg, const char *val)
{
- fprintf(stderr, "Illegal \"%s\"\n", arg);
+ fprintf(stderr, "tbf: illegal value for \"%s\": \"%s\"\n", arg, val);
}
while (argc > 0) {
if (matches(*argv, "limit") == 0) {
NEXT_ARG();
- if (opt.limit || latency) {
- fprintf(stderr, "Double \"limit/latency\" spec\n");
+ if (opt.limit) {
+ fprintf(stderr, "tbf: duplicate \"limit\" specification\n");
+ return -1;
+ }
+ if (latency) {
+ fprintf(stderr, "tbf: specifying both \"latency\" and \"limit\" is not allowed\n");
return -1;
}
if (get_size(&opt.limit, *argv)) {
- explain1("limit");
+ explain1("limit", *argv);
return -1;
}
ok++;
} else if (matches(*argv, "latency") == 0) {
NEXT_ARG();
- if (opt.limit || latency) {
- fprintf(stderr, "Double \"limit/latency\" spec\n");
+ if (latency) {
+ fprintf(stderr, "tbf: duplicate \"latency\" specification\n");
+ return -1;
+ }
+ if (opt.limit) {
+ fprintf(stderr, "tbf: specifying both \"limit\" and \"/latency\" is not allowed\n");
return -1;
}
if (get_time(&latency, *argv)) {
- explain1("latency");
+ explain1("latency", *argv);
return -1;
}
ok++;
} else if (matches(*argv, "burst") == 0 ||
strcmp(*argv, "buffer") == 0 ||
strcmp(*argv, "maxburst") == 0) {
+ const char *parm_name = *argv;
NEXT_ARG();
if (buffer) {
- fprintf(stderr, "Double \"buffer/burst\" spec\n");
+ fprintf(stderr, "tbf: duplicate \"buffer/burst/maxburst\" specification\n");
return -1;
}
if (get_size_and_cell(&buffer, &Rcell_log, *argv) < 0) {
- explain1("buffer");
+ explain1(parm_name, *argv);
return -1;
}
ok++;
} else if (strcmp(*argv, "mtu") == 0 ||
strcmp(*argv, "minburst") == 0) {
+ const char *parm_name = *argv;
NEXT_ARG();
if (mtu) {
- fprintf(stderr, "Double \"mtu/minburst\" spec\n");
+ fprintf(stderr, "tbf: duplicate \"mtu/minburst\" specification\n");
return -1;
}
if (get_size_and_cell(&mtu, &Pcell_log, *argv) < 0) {
- explain1("mtu");
+ explain1(parm_name, *argv);
return -1;
}
ok++;
} else if (strcmp(*argv, "mpu") == 0) {
NEXT_ARG();
if (mpu) {
- fprintf(stderr, "Double \"mpu\" spec\n");
+ fprintf(stderr, "tbf: duplicate \"mpu\" specification\n");
return -1;
}
if (get_size(&mpu, *argv)) {
- explain1("mpu");
+ explain1("mpu", *argv);
return -1;
}
ok++;
} else if (strcmp(*argv, "rate") == 0) {
NEXT_ARG();
if (opt.rate.rate) {
- fprintf(stderr, "Double \"rate\" spec\n");
+ fprintf(stderr, "tbf: duplicate \"rate\" specification\n");
return -1;
}
if (get_rate(&opt.rate.rate, *argv)) {
- explain1("rate");
+ explain1("rate", *argv);
return -1;
}
ok++;
} else if (matches(*argv, "peakrate") == 0) {
NEXT_ARG();
if (opt.peakrate.rate) {
- fprintf(stderr, "Double \"peakrate\" spec\n");
+ fprintf(stderr, "tbf: duplicate \"peakrate\" specification\n");
return -1;
}
if (get_rate(&opt.peakrate.rate, *argv)) {
- explain1("peakrate");
+ explain1("peakrate", *argv);
return -1;
}
ok++;
} else if (matches(*argv, "overhead") == 0) {
NEXT_ARG();
if (overhead) {
- fprintf(stderr, "Double \"overhead\" spec\n");
+ fprintf(stderr, "tbf: duplicate \"overhead\" specification\n");
return -1;
}
if (get_u16(&overhead, *argv, 10)) {
- explain1("overhead"); return -1;
+ explain1("overhead", *argv); return -1;
}
} else if (matches(*argv, "linklayer") == 0) {
NEXT_ARG();
if (get_linklayer(&linklayer, *argv)) {
- explain1("linklayer"); return -1;
+ explain1("linklayer", *argv); return -1;
}
} else if (strcmp(*argv, "help") == 0) {
explain();
return -1;
} else {
- fprintf(stderr, "What is \"%s\"?\n", *argv);
+ fprintf(stderr, "tbf: unknown parameter \"%s\"\n", *argv);
explain();
return -1;
}
argc--; argv++;
}
- if (!ok) {
- explain();
- return -1;
- }
+ int verdict = 0;
- if (opt.rate.rate == 0 || !buffer) {
- fprintf(stderr, "Both \"rate\" and \"burst\" are required.\n");
- return -1;
+ /* Be nice to the user: try to emit all error messages in
+ * one go rather than reveal one more problem when a
+ * previous one has been fixed.
+ */
+ if (opt.rate.rate == 0) {
+ fprintf(stderr, "tbf: the \"rate\" parameter is mandatory.\n");
+ verdict = -1;
+ }
+ if (!buffer) {
+ fprintf(stderr, "tbf: the \"burst\" parameter is mandatory.\n");
+ verdict = -1;
}
if (opt.peakrate.rate) {
if (!mtu) {
- fprintf(stderr, "\"mtu\" is required, if \"peakrate\" is requested.\n");
- return -1;
+ fprintf(stderr, "tbf: when \"peakrate\" is specified, \"mtu\" must also be specified.\n");
+ verdict = -1;
}
}
if (opt.limit == 0 && latency == 0) {
- fprintf(stderr, "Either \"limit\" or \"latency\" are required.\n");
- return -1;
+ fprintf(stderr, "tbf: either \"limit\" or \"latency\" is required.\n");
+ verdict = -1;
}
+ if (verdict != 0) {
+ explain();
+ return verdict;
+ }
+
if (opt.limit == 0) {
double lim = opt.rate.rate*(double)latency/TIME_UNITS_PER_SEC + buffer;
if (opt.peakrate.rate) {
opt.rate.mpu = mpu;
opt.rate.overhead = overhead;
if (tc_calc_rtable(&opt.rate, rtab, Rcell_log, mtu, linklayer) < 0) {
- fprintf(stderr, "TBF: failed to calculate rate table.\n");
+ fprintf(stderr, "tbf: failed to calculate rate table.\n");
return -1;
}
opt.buffer = tc_calc_xmittime(opt.rate.rate, buffer);
opt.peakrate.mpu = mpu;
opt.peakrate.overhead = overhead;
if (tc_calc_rtable(&opt.peakrate, ptab, Pcell_log, mtu, linklayer) < 0) {
- fprintf(stderr, "TBF: failed to calculate peak rate table.\n");
+ fprintf(stderr, "tbf: failed to calculate peak rate table.\n");
return -1;
}
opt.mtu = tc_calc_xmittime(opt.peakrate.rate, mtu);