]> git.ipfire.org Git - thirdparty/util-linux.git/blob - sys-utils/cytune.c
63ca0e4e222c242e478b7cf489174633893985ed
[thirdparty/util-linux.git] / sys-utils / cytune.c
1 /* cytune.c -- Tune Cyclades driver
2 *
3 * Copyright 1995 Nick Simicich (njs@scifi.emi.net)
4 *
5 * Modifications by Rik Faith (faith@cs.unc.edu)
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the Nick Simicich
18 * 4. Neither the name of the Nick Simicich nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY NICK SIMICICH AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL NICK SIMICICH OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 */
35
36 /*
37 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
38 * - added Native Language Support
39 * Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
40 * - fixed strerr(errno) in gettext calls
41 */
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <sys/types.h>
46 #include <sys/time.h>
47 #include <sys/ioctl.h>
48 #include <unistd.h>
49 #include <string.h>
50 #include <fcntl.h>
51 #include <errno.h>
52 #include <signal.h>
53 #include <linux/tty.h>
54 #include <termios.h>
55
56 #include "../defines.h" /* for NEED_tqueue_h */
57 #ifdef NEED_tqueue_h
58 #include <linux/tqueue.h> /* required for old kernels (for struct tq_struct) */
59 /* compilation errors on other kernels */
60 #endif
61 #include <linux/cyclades.h>
62
63 #if 0
64 #ifndef XMIT
65 # include <linux/version.h>
66 # if LINUX_VERSION_CODE > 66056
67 # define XMIT
68 # endif
69 #endif
70 #endif
71
72 #include "nls.h"
73 /* Until it gets put in the kernel,
74 toggle by hand. */
75 #undef XMIT
76
77 struct cyclades_control {
78 struct cyclades_monitor c;
79 int cfile;
80 int maxmax;
81 double maxtran;
82 double maxxmit;
83 unsigned long threshold_value;
84 unsigned long timeout_value;
85 };
86 struct cyclades_control *cmon;
87 int cmon_index;
88
89 #define mvtime(tvpto, tvpfrom) (((tvpto)->tv_sec = (tvpfrom)->tv_sec),(tvpto)->tv_usec = (tvpfrom)->tv_usec)
90
91
92 static inline double
93 dtime(struct timeval * tvpnew, struct timeval * tvpold) {
94 double diff;
95 diff = (double)tvpnew->tv_sec - (double)tvpold->tv_sec;
96 diff += ((double)tvpnew->tv_usec - (double)tvpold->tv_usec)/1000000;
97 return diff;
98 }
99
100 static int global_argc, global_optind;
101 static char ***global_argv;
102
103 static void
104 summary(int sig) {
105 struct cyclades_control *cc;
106
107 int argc, local_optind;
108 char **argv;
109
110 int i,j;
111
112 argc = global_argc;
113 argv = *global_argv;
114 local_optind = global_optind;
115
116 if (sig > 0) {
117 for(i = local_optind; i < argc; i ++) {
118 j = i - local_optind;
119 cc = &cmon[cmon_index];
120 fprintf(stderr, _("File %s, For threshold value %lu, Maximum characters in fifo were %d,\nand the maximum transfer rate in characters/second was %f\n"),
121 argv[i],
122 cc->threshold_value,
123 cc->maxmax,
124 cc->maxtran);
125 }
126
127 exit(0);
128 }
129 cc = &cmon[cmon_index];
130 if (cc->threshold_value > 0 && sig != -1) {
131 fprintf(stderr, _("File %s, For threshold value %lu and timrout value %lu, Maximum characters in fifo were %d,\nand the maximum transfer rate in characters/second was %f\n"),
132 argv[cmon_index+local_optind],
133 cc->threshold_value,
134 cc->timeout_value,
135 cc->maxmax,
136 cc->maxtran);
137 }
138 cc->maxmax = 0;
139 cc->maxtran = 0.0;
140 cc->threshold_value = 0;
141 cc->timeout_value = 0;
142 }
143
144 static int query = 0;
145 static int interval = 1;
146
147 static int set = 0;
148 static int set_val = -1;
149 static int get = 0;
150
151 static int set_def = 0;
152 static int set_def_val = -1;
153 static int get_def = 0;
154
155 static int set_time = 0;
156 static int set_time_val = -1;
157
158 static int set_def_time = 0;
159 static int set_def_time_val = -1;
160
161
162 int main(int argc, char *argv[]) {
163
164 struct timeval lasttime, thistime;
165 struct timezone tz = {0,0};
166 double diff;
167 int errflg = 0;
168 int file;
169 int numfiles;
170 struct cyclades_monitor cywork;
171
172 int i;
173 unsigned long threshold_value;
174 unsigned long timeout_value;
175 double xfer_rate;
176 #ifdef XMIT
177 double xmit_rate;
178 #endif
179
180 global_argc = argc; /* For signal routine. */
181 global_argv = &argv; /* For signal routine. */
182
183 setlocale(LC_ALL, "");
184 bindtextdomain(PACKAGE, LOCALEDIR);
185 textdomain(PACKAGE);
186
187 while (EOF != (i = getopt(argc, argv,
188 "qs:S:t:T:gGi:"))) {
189 switch (i) {
190 case 'q':
191 query = 1;
192 break;
193 case 'i':
194 interval = atoi(optarg);
195 if(interval <= 0) {
196 fprintf(stderr, _("Invalid interval value: %s\n"),optarg);
197 errflg ++;
198 }
199 break;
200 case 's':
201 ++set;
202 set_val = atoi(optarg);
203 if(set_val <= 0 || set_val > 12) {
204 fprintf(stderr, _("Invalid set value: %s\n"),optarg);
205 errflg ++;
206 }
207 break;
208 case 'S':
209 ++set_def;
210 set_def_val = atoi(optarg);
211 if(set_def_val < 0 || set_def_val > 12) {
212 fprintf(stderr, _("Invalid default value: %s\n"),optarg);
213 errflg ++;
214 }
215 break;
216 case 't':
217 ++set_time;
218 set_time_val = atoi(optarg);
219 if(set_time_val <= 0 || set_time_val > 255) {
220 fprintf(stderr, _("Invalid set time value: %s\n"),optarg);
221 errflg ++;
222 }
223 break;
224 case 'T':
225 ++set_def_time;
226 set_def_time_val = atoi(optarg);
227 if(set_def_time_val < 0 || set_def_time_val > 255) {
228 fprintf(stderr, _("Invalid default time value: %s\n"),optarg);
229 errflg ++;
230 }
231 break;
232 case 'g': ++get; break;
233 case 'G': ++get_def; break;
234 default:
235 errflg ++;
236 }
237 }
238 numfiles = argc - optind;
239 if(errflg || (numfiles == 0)
240 || (!query && !set && !set_def &&
241 !get && !get_def && !set_time && !set_def_time) ||
242 (set && set_def) || (set_time && set_def_time) ||
243 (get && get_def)) {
244 fprintf(stderr,
245 _("Usage: %s [-q [-i interval]] ([-s value]|[-S value]) ([-t value]|[-T value]) [-g|-G] file [file...]\n"),
246 argv[0]);
247 exit(1);
248 }
249
250 global_optind = optind; /* For signal routine. */
251
252 if (set || set_def) {
253 for(i = optind;i < argc;i ++) {
254 file = open(argv[i],O_RDONLY);
255 if(file == -1) {
256 int errsv = errno;
257 fprintf(stderr, _("Can't open %s: %s\n"),argv[i],strerror(errsv));
258 exit(1);
259 }
260 if(ioctl(file,
261 set ? CYSETTHRESH : CYSETDEFTHRESH,
262 set ? set_val : set_def_val)) {
263 int errsv = errno;
264 fprintf(stderr, _("Can't set %s to threshold %d: %s\n"),
265 argv[i],set?set_val:set_def_val,strerror(errsv));
266 exit(1);
267 }
268 }
269 }
270 if (set_time || set_def_time) {
271 for(i = optind;i < argc;i ++) {
272 file = open(argv[i],O_RDONLY);
273 if(file == -1) {
274 int errsv = errno;
275 fprintf(stderr, _("Can't open %s: %s\n"),argv[i],strerror(errsv));
276 exit(1);
277 }
278 if(ioctl(file,
279 set_time ? CYSETTIMEOUT : CYSETDEFTIMEOUT,
280 set_time ? set_time_val : set_def_time_val)) {
281 int errsv = errno;
282 fprintf(stderr, _("Can't set %s to time threshold %d: %s\n"),
283 argv[i],set_time?set_time_val:set_def_time_val,strerror(errsv));
284 exit(1);
285 }
286 }
287 }
288
289 if (get || get_def) {
290 for(i = optind;i < argc;i ++) {
291 file = open(argv[i],O_RDONLY);
292 if(file == -1) {
293 int errsv = errno;
294 fprintf(stderr, _("Can't open %s: %s\n"),argv[i],strerror(errsv));
295 exit(1);
296 }
297 if(ioctl(file, get ? CYGETTHRESH : CYGETDEFTHRESH, &threshold_value)) {
298 int errsv = errno;
299 fprintf(stderr, _("Can't get threshold for %s: %s\n"),
300 argv[i],strerror(errsv));
301 exit(1);
302 }
303 if(ioctl(file, get ? CYGETTIMEOUT : CYGETDEFTIMEOUT, &timeout_value)) {
304 int errsv = errno;
305 fprintf(stderr, _("Can't get timeout for %s: %s\n"),
306 argv[i],strerror(errsv));
307 exit(1);
308 }
309 printf(_("%s: %ld %s threshold and %ld %s timeout\n"),
310 argv[i], threshold_value,
311 get?_("current"):_("default"),
312 timeout_value,
313 get?_("current"):_("default"));
314 }
315 }
316
317 if(!query) return 0; /* must have been something earlier */
318
319 /* query stuff after this line */
320
321 cmon = (struct cyclades_control *) malloc(sizeof (struct cyclades_control)
322 * numfiles);
323 if(!cmon) {
324 perror(_("malloc failed"));
325 exit(1);
326 }
327 if(signal(SIGINT, summary)||
328 signal(SIGQUIT, summary)||
329 signal(SIGTERM, summary)) {
330 perror(_("Can't set signal handler"));
331 exit(1);
332 }
333 if(gettimeofday(&lasttime,&tz)) {
334 perror(_("gettimeofday failed"));
335 exit(1);
336 }
337 for(i = optind; i < argc; i ++) {
338 cmon_index = i - optind;
339 cmon[cmon_index].cfile = open(argv[i], O_RDONLY);
340 if(-1 == cmon[cmon_index].cfile) {
341 int errsv = errno;
342 fprintf(stderr, _("Can't open %s: %s\n"),argv[i],strerror(errsv));
343 exit(1);
344 }
345 if(ioctl(cmon[cmon_index].cfile, CYGETMON, &cmon[cmon_index].c)) {
346 int errsv = errno;
347 fprintf(stderr, _("Can't issue CYGETMON on %s: %s\n"),
348 argv[i],strerror(errsv));
349 exit(1);
350 }
351 summary(-1);
352 if(ioctl(cmon[cmon_index].cfile, CYGETTHRESH, &threshold_value)) {
353 int errsv = errno;
354 fprintf(stderr, _("Can't get threshold for %s: %s\n"),
355 argv[i],strerror(errsv));
356 exit(1);
357 }
358 if(ioctl(cmon[cmon_index].cfile, CYGETTIMEOUT, &timeout_value)) {
359 int errsv = errno;
360 fprintf(stderr, _("Can't get timeout for %s: %s\n"),
361 argv[i],strerror(errsv));
362 exit(1);
363 }
364 }
365 while(1) {
366 sleep(interval);
367
368 if(gettimeofday(&thistime,&tz)) {
369 perror(_("gettimeofday failed"));
370 exit(1);
371 }
372 diff = dtime(&thistime, &lasttime);
373 mvtime(&lasttime, &thistime);
374
375 for(i = optind; i < argc; i ++) {
376 cmon_index = i - optind;
377 if(ioctl(cmon[cmon_index].cfile, CYGETMON, &cywork)) {
378 int errsv = errno;
379 fprintf(stderr, _("Can't issue CYGETMON on %s: %s\n"),
380 argv[i],strerror(errsv));
381 exit(1);
382 }
383 if(ioctl(cmon[cmon_index].cfile, CYGETTHRESH, &threshold_value)) {
384 int errsv = errno;
385 fprintf(stderr, _("Can't get threshold for %s: %s\n"),
386 argv[i],strerror(errsv));
387 exit(1);
388 }
389 if(ioctl(cmon[cmon_index].cfile, CYGETTIMEOUT, &timeout_value)) {
390 int errsv = errno;
391 fprintf(stderr, _("Can't get timeout for %s: %s\n"),
392 argv[i],strerror(errsv));
393 exit(1);
394 }
395
396 xfer_rate = cywork.char_count/diff;
397 #ifdef XMIT
398 xmit_rate = cywork.send_count/diff;
399 #endif
400
401 if(threshold_value != cmon[cmon_index].threshold_value ||
402 timeout_value != cmon[cmon_index].timeout_value) {
403 summary(-2);
404 /* Note that the summary must come before the setting of */
405 /* threshold_value */
406 cmon[cmon_index].threshold_value = threshold_value;
407 cmon[cmon_index].timeout_value = timeout_value;
408 } else {
409 /* Don't record this first cycle after change */
410 if(xfer_rate > cmon[cmon_index].maxtran)
411 cmon[cmon_index].maxtran = xfer_rate;
412 #ifdef XMIT
413 if(xmit_rate > cmon[cmon_index].maxxmit)
414 cmon[cmon_index].maxxmit = xmit_rate;
415 #endif
416 if(cywork.char_max > cmon[cmon_index].maxmax)
417 cmon[cmon_index].maxmax = cywork.char_max;
418 }
419
420 #ifdef XMIT
421 printf(_("%s: %lu ints, %lu/%lu chars; ")
422 _("fifo: %lu thresh, %lu tmout, ")
423 _("%lu max, %lu now\n"),
424 argv[i],
425 cywork.int_count,cywork.char_count,cywork.send_count,
426 threshold_value,timeout_value,
427 cywork.char_max,cywork.char_last);
428 printf(_(" %f int/sec; %f rec, %f send (char/sec)\n"),
429 cywork.int_count/diff,
430 xfer_rate,
431 xmit_rate);
432 #else
433 printf(_("%s: %lu ints, %lu chars; fifo: %lu thresh, %lu tmout, %lu max, %lu now\n"),
434 argv[i],
435 cywork.int_count,cywork.char_count,
436 threshold_value,timeout_value,
437 cywork.char_max,cywork.char_last);
438 printf(_(" %f int/sec; %f rec (char/sec)\n"),
439 cywork.int_count/diff,
440 xfer_rate);
441 #endif
442 memcpy(&cmon[cmon_index].c, &cywork, sizeof (struct cyclades_monitor));
443 }
444 }
445
446 return 0;
447 }