Upload Tizen:Base source
[framework/base/util-linux-ng.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@pld.ORG.PL>
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 <termios.h>
54
55 #include "cyclades.h"
56
57 #if 0
58 #ifndef XMIT
59 # include <linux/version.h>
60 # if LINUX_VERSION_CODE > 66056
61 #  define XMIT
62 # endif
63 #endif
64 #endif
65
66 #include "nls.h"
67                                 /* Until it gets put in the kernel,
68                                    toggle by hand. */
69 #undef XMIT
70
71 struct cyclades_control {
72   struct cyclades_monitor c;
73   int cfile;
74   int maxmax;
75   double maxtran;
76   double maxxmit;
77   unsigned long threshold_value;
78   unsigned long timeout_value;
79 };
80 struct cyclades_control *cmon;
81 int cmon_index;
82
83 #define mvtime(tvpto, tvpfrom)  (((tvpto)->tv_sec = (tvpfrom)->tv_sec),(tvpto)->tv_usec = (tvpfrom)->tv_usec)
84
85
86 static inline double
87 dtime(struct timeval * tvpnew, struct timeval * tvpold) {
88   double diff;
89   diff = (double)tvpnew->tv_sec - (double)tvpold->tv_sec;
90   diff += ((double)tvpnew->tv_usec - (double)tvpold->tv_usec)/1000000;
91   return diff;
92 }
93
94 static int global_argc, global_optind;
95 static char ***global_argv;
96
97 static void
98 summary(int sig) {
99   struct cyclades_control *cc;
100
101   int argc, local_optind;
102   char **argv;
103
104   int i,j;
105
106   argc = global_argc;
107   argv = *global_argv;
108   local_optind = global_optind;
109
110   if (sig > 0) {
111     for(i = local_optind; i < argc; i ++) {
112       j = i - local_optind;
113       cc = &cmon[cmon_index];
114       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"), 
115               argv[i],
116               cc->threshold_value,
117               cc->maxmax,
118               cc->maxtran);
119     }
120     
121     exit(0);
122   }
123   cc = &cmon[cmon_index];
124   if (cc->threshold_value > 0 && sig != -1) {
125     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"),
126             argv[cmon_index+local_optind],
127             cc->threshold_value,
128             cc->timeout_value,
129             cc->maxmax,
130             cc->maxtran);
131   }
132   cc->maxmax = 0;
133   cc->maxtran = 0.0;
134   cc->threshold_value = 0;
135   cc->timeout_value = 0;
136 }
137
138 static int query   = 0;
139 static int interval = 1;
140
141 static int set     = 0;
142 static int set_val = -1;
143 static int get     = 0;
144
145 static int set_def     = 0;
146 static int set_def_val = -1;
147 static int get_def     = 0;
148
149 static int set_time = 0;
150 static int set_time_val = -1;
151
152 static int set_def_time = 0;
153 static int set_def_time_val = -1;
154
155
156 int main(int argc, char *argv[]) {
157
158   struct timeval lasttime, thistime;
159   struct timezone tz = {0,0};
160   double diff;
161   int errflg = 0;
162   int file;
163   int numfiles;
164   struct cyclades_monitor cywork;
165   
166   int i;
167   unsigned long threshold_value;
168   unsigned long timeout_value;
169   double xfer_rate;
170 #ifdef XMIT
171   double xmit_rate;
172 #endif
173   
174   global_argc = argc;           /* For signal routine. */
175   global_argv = &argv;          /* For signal routine. */
176
177   setlocale(LC_ALL, "");
178   bindtextdomain(PACKAGE, LOCALEDIR);
179   textdomain(PACKAGE);
180
181   while ((i = getopt(argc, argv, "qs:S:t:T:gGi:")) != -1) {
182     switch (i) {
183     case 'q':
184       query = 1;
185       break;
186     case 'i':
187       interval = atoi(optarg);
188       if(interval <= 0) {
189         fprintf(stderr, _("Invalid interval value: %s\n"),optarg);
190         errflg ++;
191       }
192       break;
193     case 's':
194       ++set;
195       set_val = atoi(optarg);
196       if(set_val <= 0 || set_val > 12) {
197         fprintf(stderr, _("Invalid set value: %s\n"),optarg);
198         errflg ++;
199       }
200       break;
201     case 'S':
202        ++set_def;
203       set_def_val = atoi(optarg);
204       if(set_def_val < 0 || set_def_val > 12) {
205         fprintf(stderr, _("Invalid default value: %s\n"),optarg);
206         errflg ++;
207       }
208       break;
209     case 't':
210       ++set_time;
211       set_time_val = atoi(optarg);
212       if(set_time_val <= 0 || set_time_val > 255) {
213         fprintf(stderr, _("Invalid set time value: %s\n"),optarg);
214         errflg ++;
215       }
216       break;
217     case 'T':
218        ++set_def_time;
219       set_def_time_val = atoi(optarg);
220       if(set_def_time_val < 0 || set_def_time_val > 255) {
221         fprintf(stderr, _("Invalid default time value: %s\n"),optarg);
222         errflg ++;
223       }
224       break;
225     case 'g': ++get;     break;
226     case 'G': ++get_def; break;
227     default:
228       errflg ++;
229     }
230   }
231   numfiles = argc - optind;
232   if(errflg || (numfiles == 0)
233      || (!query && !set && !set_def && 
234          !get && !get_def && !set_time && !set_def_time) || 
235      (set && set_def) || (set_time && set_def_time) || 
236      (get && get_def)) {
237     fprintf(stderr, 
238             _("Usage: %s [-q [-i interval]] ([-s value]|[-S value]) ([-t value]|[-T value]) [-g|-G] file [file...]\n"),
239             argv[0]);
240     exit(1);
241   }
242
243   global_optind = optind;       /* For signal routine. */
244
245   if (set || set_def) {
246     for(i = optind; i < argc; i++) {
247       file = open(argv[i],O_RDONLY);
248       if(file == -1) {
249         int errsv = errno;
250         fprintf(stderr, _("Can't open %s: %s\n"),argv[i],strerror(errsv));
251         exit(1);
252       }
253       if(ioctl(file,
254                set ? CYSETTHRESH : CYSETDEFTHRESH,
255                set ? set_val : set_def_val)) {
256         int errsv = errno;
257         fprintf(stderr, _("Can't set %s to threshold %d: %s\n"),
258                 argv[i],set?set_val:set_def_val,strerror(errsv));
259         exit(1);
260       }
261       close(file);
262     }
263   }
264   if (set_time || set_def_time) {
265     for(i = optind; i < argc; i++) {
266       file = open(argv[i],O_RDONLY);
267       if(file == -1) {
268         int errsv = errno;
269         fprintf(stderr, _("Can't open %s: %s\n"),argv[i],strerror(errsv));
270         exit(1);
271       }
272       if(ioctl(file,
273                set_time ? CYSETTIMEOUT : CYSETDEFTIMEOUT,
274                set_time ? set_time_val : set_def_time_val)) {
275         int errsv = errno;
276         fprintf(stderr, _("Can't set %s to time threshold %d: %s\n"),
277                 argv[i],set_time?set_time_val:set_def_time_val,strerror(errsv));
278         exit(1);
279       }
280       close(file);
281     }
282   }
283
284   if (get || get_def) {
285     for(i = optind; i < argc; i++) {
286       file = open(argv[i],O_RDONLY);
287       if(file == -1) {
288         int errsv = errno;
289         fprintf(stderr, _("Can't open %s: %s\n"),argv[i],strerror(errsv));
290         exit(1);
291       }
292       if(ioctl(file, get ? CYGETTHRESH : CYGETDEFTHRESH, &threshold_value)) {
293         int errsv = errno;
294         fprintf(stderr, _("Can't get threshold for %s: %s\n"),
295                 argv[i],strerror(errsv));
296         exit(1);
297       }
298       if(ioctl(file, get ? CYGETTIMEOUT : CYGETDEFTIMEOUT, &timeout_value)) {
299         int errsv = errno;
300         fprintf(stderr, _("Can't get timeout for %s: %s\n"),
301                 argv[i],strerror(errsv));
302         exit(1);
303       }
304       close(file);
305       if (get)
306               printf(_("%s: %ld current threshold and %ld current timeout\n"),
307                      argv[i], threshold_value, timeout_value);
308       else
309               printf(_("%s: %ld default threshold and %ld default timeout\n"),
310                      argv[i], threshold_value, timeout_value);
311     }
312   }
313
314   if(!query) return 0;          /* must have been something earlier */
315
316   /* query stuff after this line */
317   
318   cmon = (struct cyclades_control *) malloc(sizeof (struct cyclades_control)
319                                             * numfiles);
320   if(!cmon) {
321     perror(_("malloc failed"));
322     exit(1);
323   }
324   if(signal(SIGINT, summary)||
325      signal(SIGQUIT, summary)||
326      signal(SIGTERM, summary)) {
327     perror(_("Can't set signal handler"));
328     exit(1);
329   }
330   if(gettimeofday(&lasttime,&tz)) {
331     perror(_("gettimeofday failed"));
332     exit(1);
333   }
334   for(i = optind; i < argc; i ++) {
335     cmon_index = i - optind;
336     cmon[cmon_index].cfile = open(argv[i], O_RDONLY);
337     if(-1 == cmon[cmon_index].cfile) {
338       int errsv = errno;
339       fprintf(stderr, _("Can't open %s: %s\n"),argv[i],strerror(errsv));
340       exit(1);
341     }
342     if(ioctl(cmon[cmon_index].cfile, CYGETMON, &cmon[cmon_index].c)) {
343       int errsv = errno;
344       fprintf(stderr, _("Can't issue CYGETMON on %s: %s\n"),
345               argv[i],strerror(errsv));
346       exit(1);
347     }
348     summary(-1);
349     if(ioctl(cmon[cmon_index].cfile, CYGETTHRESH, &threshold_value)) {
350       int errsv = errno;
351       fprintf(stderr, _("Can't get threshold for %s: %s\n"),
352               argv[i],strerror(errsv));
353       exit(1);
354     }
355     if(ioctl(cmon[cmon_index].cfile, CYGETTIMEOUT, &timeout_value)) {
356       int errsv = errno;
357       fprintf(stderr, _("Can't get timeout for %s: %s\n"),
358               argv[i],strerror(errsv));
359       exit(1);
360     }
361   }
362   while(1) {
363     sleep(interval);
364     
365     if(gettimeofday(&thistime,&tz)) {
366       perror(_("gettimeofday failed"));
367       exit(1);
368     }
369     diff = dtime(&thistime, &lasttime);
370     mvtime(&lasttime, &thistime);
371
372     for(i = optind; i < argc; i ++) {
373       cmon_index = i - optind;
374       if(ioctl(cmon[cmon_index].cfile, CYGETMON, &cywork)) {
375         int errsv = errno;
376         fprintf(stderr, _("Can't issue CYGETMON on %s: %s\n"),
377                 argv[i],strerror(errsv));
378         exit(1);
379       }
380       if(ioctl(cmon[cmon_index].cfile, CYGETTHRESH, &threshold_value)) {
381         int errsv = errno;
382         fprintf(stderr, _("Can't get threshold for %s: %s\n"),
383                 argv[i],strerror(errsv));
384         exit(1);
385       }
386       if(ioctl(cmon[cmon_index].cfile, CYGETTIMEOUT, &timeout_value)) {
387         int errsv = errno;
388         fprintf(stderr, _("Can't get timeout for %s: %s\n"),
389                 argv[i],strerror(errsv));
390         exit(1);
391       }
392
393       xfer_rate = cywork.char_count/diff;
394 #ifdef XMIT
395       xmit_rate = cywork.send_count/diff;
396 #endif
397
398       if(threshold_value != cmon[cmon_index].threshold_value ||
399          timeout_value != cmon[cmon_index].timeout_value) {
400         summary(-2);
401         /* Note that the summary must come before the setting of */
402         /* threshold_value */
403         cmon[cmon_index].threshold_value = threshold_value;      
404         cmon[cmon_index].timeout_value = timeout_value;  
405       } else {
406         /* Don't record this first cycle after change */
407         if(xfer_rate > cmon[cmon_index].maxtran) 
408           cmon[cmon_index].maxtran = xfer_rate;
409 #ifdef XMIT
410         if(xmit_rate > cmon[cmon_index].maxxmit)
411           cmon[cmon_index].maxxmit = xmit_rate;
412 #endif
413         if(cywork.char_max > cmon[cmon_index].maxmax) 
414           cmon[cmon_index].maxmax = cywork.char_max;
415       }
416
417 #ifdef XMIT
418       printf(_("%s: %lu ints, %lu/%lu chars; fifo: %lu thresh, %lu tmout, "
419                "%lu max, %lu now\n"),
420              argv[i],
421              cywork.int_count,cywork.char_count,cywork.send_count,
422              threshold_value,timeout_value,
423              cywork.char_max,cywork.char_last);
424       printf(_("   %f int/sec; %f rec, %f send (char/sec)\n"),
425              cywork.int_count/diff,
426              xfer_rate,
427              xmit_rate);
428 #else
429       printf(_("%s: %lu ints, %lu chars; fifo: %lu thresh, %lu tmout, "
430                "%lu max, %lu now\n"),
431              argv[i],
432              cywork.int_count,cywork.char_count,
433              threshold_value,timeout_value,
434              cywork.char_max,cywork.char_last);
435       printf(_("   %f int/sec; %f rec (char/sec)\n"),
436              cywork.int_count/diff,
437              xfer_rate);
438 #endif
439       memcpy(&cmon[cmon_index].c, &cywork, sizeof (struct cyclades_monitor));
440     }
441   }
442
443   return 0;
444 }