forked from deater/linux_logo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
linux_logo.c
1222 lines (1045 loc) · 34.9 KB
/
linux_logo.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*-------------------------------------------------------------------------*\
LINUX LOGO 6.01 - Creates Nifty Logo With System Info - 12 July 2022
by Vince Weaver ([email protected], http://www.deater.net/weave )
A program to display text/ansi logos with system information.
Thanks to many, many people who sent patches in.
See the CHANGES file for a list of all those who helped out.
\*-------------------------------------------------------------------------*/
#define VERSION "6.01"
#include <stdio.h>
#include <stdlib.h> /* calloc() */
#include <string.h> /* strdup() */
#include <sys/time.h> /* time() */
#include <locale.h>
#define ESCAPE "\033"
#include "sysinfo.h"
#include "linux_logo.h"
#include "logo_types.h"
#include "load_logo.h"
#if (USE_I18N==1)
#undef __OPTIMIZE__
#include <libintl.h>
#define _(String) gettext((String))
#else
#define _(String) (String)
#endif
/* Change the values in the below file to alter default behavior */
#include "defaults.h"
/* Some global variables. Possibly bad in practice, but it saves a lot *\
\* of paramater passing, which has caused bugs to develop before. */
struct logo_info *logo_info_head = NULL;
struct logo_info *logo_info_tail = NULL;
static char *vmw_strcat(char *dest, char *src, int space_remaining) {
if (strlen(src) >= space_remaining) {
fprintf(stderr,"Error! Not enough room in string!\n\n");
exit(1);
}
return strcat(dest,src);
}
/* Convert a number into an ordinal string */
static void strcat_ordinal(int value,char *string, int space) {
switch(value) {
case 0: vmw_strcat(string,_("Zero"),space); break;
case 1: vmw_strcat(string,_("One"),space); break;
case 2: vmw_strcat(string,_("Two"),space); break;
case 3: vmw_strcat(string,_("Three"),space); break;
case 4: vmw_strcat(string,_("Four"),space); break;
case 5: vmw_strcat(string,_("Five"),space); break;
case 6: vmw_strcat(string,_("Six"),space); break;
case 7: vmw_strcat(string,_("Seven"),space); break;
case 8: vmw_strcat(string,_("Eight"),space); break;
case 9: vmw_strcat(string,_("Nine"),space); break;
default: vmw_strcat(string,_("Many"),space); break;
}
}
/* setup the default logos, which are always present */
static void setup_default_logos() {
struct logo_info *new_logo;
#include "load_logos.h"
}
/* Setup the "settings" structure to some defaults */
/* Edit the "defaults.h" file to change these */
static void setup_info(struct linux_logo_info_type *settings) {
settings->width=DEFAULT_WIDTH; /* Defaults to 80 */
settings->no_periods=DEFAULT_NO_PERIODS; /* Defaults to None */
settings->preserve_xy=DEFAULT_PRESERVE_XY; /* Defaults to Off */
settings->skip_bogomips=DEFAULT_SKIP_BOGOMIPS; /* Defaults to No */
settings->offset=DEFAULT_OFFSET; /* Defaults to 0 */
settings->plain_ascii=DEFAULT_PLAIN_ASCII; /* Defaults to No */
settings->banner_mode=DEFAULT_BANNER_MODE; /* Defualts to Yes */
settings->wipe_screen=DEFAULT_WIPE_SCREEN; /* Defaults to No */
settings->show_uptime=DEFAULT_SHOW_UPTIME; /* Defaults to No */
settings->show_load=DEFAULT_SHOW_LOAD; /* Defaults to No */
settings->narrow_logo=DEFAULT_NARROW_LOGO; /* Defaults to No */
settings->pretty_output=DEFAULT_PRETTY_OUTPUT; /* Defaults to Yes */
set_pretty_printing(DEFAULT_PRETTY_OUTPUT);
settings->display_logo_only=0;
settings->display_sysinfo_only=0;
settings->display_usertext=0;
settings->custom_format=0;
settings->center_sysinfo=1;
settings->user_text[0]=0;
settings->format[0]=0;
}
/* Use ansi codes or spaces to shift the cursor to the right */
static void shift_right(int shift,int plain_ascii) {
int i;
if (shift<=0) return;
if (plain_ascii) {
for(i=0;i<shift;i++) {
putchar(' ');
}
}
else {
printf("\033[%iC",shift);
}
}
/* Prints a string, but stops at a newline or end of string */
static char *print_line(char *string) {
char *temp_st=string;
if (temp_st==NULL) return NULL;
while ((*temp_st!='\n') && (*temp_st!='\0')) {
putchar(*temp_st);
temp_st++;
}
if ((*temp_st)=='\n') {
return temp_st+1;
}
else return NULL;
}
/* print enough chars to center text of given size */
static void center(int size,int width,int plain_ascii) {
int i;
i=((width-size)/2);
shift_right(i,plain_ascii);
}
/* Uses escape codes to clear the screen */
static void clear_screen(int plain_ascii) {
if (!plain_ascii) {
printf("\033[2J\033[0;0H\n");
}
else {
/* clear the screen some other way? */
}
}
/* Change uptime seconds into time string */
static void strcat_uptime(int seconds,char *string, int space) {
int up_days,up_hrs,up_mins;
char temp_string[BUFSIZ],final_string[BUFSIZ];
up_days=seconds/86400;
up_hrs=(seconds-(up_days*86400))/3600;
up_mins=(seconds-(up_days*86400)-(up_hrs*3600))/60;
final_string[0]=0;
vmw_strcat(final_string,_("Uptime "),BUFSIZ);
if (up_days>0) {
snprintf(temp_string,BUFSIZ,"%d %s ",
up_days,(up_days==1 ? _("day"):_("days")));
vmw_strcat(final_string,temp_string,
BUFSIZ-strlen(final_string));
}
if (up_hrs>0) {
snprintf(temp_string,BUFSIZ,"%d %s ",
up_hrs,(up_hrs==1 ? _("hour"):_("hours")));
vmw_strcat(final_string,temp_string,
BUFSIZ-strlen(final_string));
}
if (up_mins>0) {
snprintf(temp_string,BUFSIZ,"%d %s",
up_mins,(up_mins==1 ? _("minute"):_("minutes")));
vmw_strcat(final_string,temp_string,
BUFSIZ-strlen(final_string));
}
vmw_strcat(string,final_string,space);
}
/* Prints the help */
static void help_message(char *binname, char full) {
char temp_version[BUFSIZ];
printf("\nLinux Logo Version %s using libsysinfo %s\n",VERSION,
get_sysinfo_version(temp_version));
printf("\tby Vince Weaver <[email protected]>\n");
printf(" Newest Versions at:\n");
printf(" http://www.deater.net/weave/vmwprod/linux_logo\n");
printf(" http://metalab.unc.edu/pub/Linux/logos/penguins\n\n");
if (!full) exit(0);
printf("Usage: %s [-a] [-b] [-c] [-d] [-D file] [-e file] [-f] "
"[-g]\n"
" [-h] [-i] [-k] [-l] [-n] [-o num] [-p] "
"[-s] [-t str] [-u] [-v]\n"
" [-w Num] [-x] [-y] [-F format] "
"[-L num | NAME | list | random_xy]\n",binname);
printf(" [-a] -- Display an ascii-only Logo\n");
printf(" [-b] -- Display a Banner Logo!\n");
printf(" [-c] -- Display a \"Classic\" type logo\n");
printf(" [-d] -- disable \"prettying\" of output\n");
printf(" [-D file]-- use custom logo from \"file\"\n");
printf(" [-e file]-- Use \"file\" instead of "
"/proc/cpuinfo [for debugging]\n");
printf(" [-f] -- force the screen clear before drawing\n");
printf(" [-F format] Format output. See README.\n");
printf(" B [-g] -- give system info only\n");
printf(" [-h] -- this help screen\n");
printf(" [-i] -- ignore ~/.linux_logo and "
"/etc/linux_logo.conf\n");
printf(" [-k] -- keep sysinfo flushed-left "
"(non-centered)\n");
printf(" B [-l] -- display logo only\n");
printf(" C [-o Num] -- offset output Num spaces to the right\n");
printf(" [-p] -- preserve cursor location\n");
printf(" [-s] -- skip Bogomips [speeds up on non-Linux "
"platforms]\n");
printf(" [-t str] -- display user-supplied string\n");
printf(" * [-u] -- show uptime\n");
printf(" [-v] -- version information\n");
printf(" [-w Num] -- set width of screen to Num "
"[default 80]\n");
printf(" * [-y] -- show load average\n");
printf(" [-L num | NAME | list | random_xy] -- "
"multiple Logo options. See README\n\n");
printf(" B=Banner mode only, C=Classic Mode Only "
"*=Works Only in Linux\n\n");
}
/* The nifty customizable sysinfo parser */
static int generate_sysinfo(
char ***string,
struct linux_logo_info_type *settings) {
struct os_info_type os_info;
struct cpu_info_type cpu_info;
int x=0,len,line=0;
char temp_string[BUFSIZ],hostname[BUFSIZ],domain[BUFSIZ];
char temp_line[BUFSIZ];
float load_1,load_5,load_15;
char **temp_sysinfo;
char char_string[2]={0,0};
int allocated_lines=10;
long long mem_size=0;
double megahertz=0.0;
/* Get the system info */
get_os_info(&os_info);
get_cpu_info(&cpu_info);
len=strlen(settings->format);
/* allocate 10 lines to start with */
temp_sysinfo=calloc(allocated_lines,sizeof(char *));
while (x<len) {
/* clear out our line */
temp_line[0]=0;
/* handle a line */
while (settings->format[x]!='\n') {
/* If not a #, then just print the character */
if (settings->format[x]!='#') {
char_string[0]=*((settings->format)+x);
vmw_strcat(temp_line,char_string,
BUFSIZ-strlen(temp_line));
}
else {
x++;
if (x>len) break;
switch(settings->format[x]) {
/* double # just prints a # */
case '#': vmw_strcat(temp_line,"#",BUFSIZ-strlen(temp_line)); break;
/* #B prints the bogomips */
/* If really high, don't print fractional part */
case 'B':
if ((cpu_info.bogomips==0) || (settings->skip_bogomips)) {
temp_string[0]=0;
}
else if (cpu_info.bogomips<100.0) {
snprintf(temp_string,BUFSIZ,"%.2f Bogomips",cpu_info.bogomips);
}
else if (cpu_info.bogomips>1000.0) {
snprintf(temp_string,BUFSIZ,"%.0fk Bogomips",cpu_info.bogomips/1000);
}
else {
snprintf(temp_string,BUFSIZ,"%.0f Bogomips",cpu_info.bogomips);
}
vmw_strcat(temp_line,temp_string,BUFSIZ-strlen(temp_line));
break;
/* #C prints OS revision */
case 'C': /* Note:limit to 40 if in banner mode */
/* longer strings wrap on 40-column displays */
/* FIXME: base this on width of screen and the */
/* relative widths of version and revision fields? */
if ((settings->banner_mode) &&
(strlen(os_info.os_revision)>40)) {
os_info.os_revision[40]=0;
}
vmw_strcat(temp_line,os_info.os_revision,
BUFSIZ-strlen(temp_line));
break;
/* #E prints user text */
case 'E': vmw_strcat(temp_line,settings->user_text,
BUFSIZ-strlen(temp_line));
break;
/* #H prints hostname */
case 'H': vmw_strcat(temp_line,get_host_name(hostname,domain),
BUFSIZ-strlen(temp_line));
break;
/* #L prints load average */
case 'L': get_load_average(&load_1,&load_5,&load_15);
snprintf(temp_string,BUFSIZ,"%s %.2f, %.2f, %.2f",
_("Load Average"),load_1,load_5,load_15);
vmw_strcat(temp_line,temp_string,BUFSIZ-strlen(temp_line));
break;
/* #M prints Megahertz */
case 'M': megahertz=get_cpu_mhz();
if (megahertz>0.0) {
if (megahertz>999.0) {
snprintf(temp_string,BUFSIZ,"%.3gGHz",
megahertz/1000.0);
}
else {
snprintf(temp_string,BUFSIZ,"%.3gMHz",
megahertz);
}
vmw_strcat(temp_line,temp_string,
BUFSIZ-strlen(temp_line));
}
else {
/* No megahertz. Back up the pointer. */
/* This is a hack to avoid extra spaces in the output */
if (strlen(temp_line)>0) {
temp_line[strlen(temp_line)-1]=0;
}
}
break;
/* #N prints number of CPUs */
/* Spelled out if it is less than 10 */
/* The actual number if less than 100,000 */
/* The word "Many" if more than 100,000 */
case 'N': if (cpu_info.num_cpus<=9) {
strcat_ordinal(cpu_info.num_cpus,temp_line,
BUFSIZ-strlen(temp_line));
}
else if (cpu_info.num_cpus<=99999) {
snprintf(temp_string,BUFSIZ,"%d",cpu_info.num_cpus);
vmw_strcat(temp_line,temp_string,
BUFSIZ-strlen(temp_line));
}
else {
strcat_ordinal(10,temp_line,
BUFSIZ-strlen(temp_line));
}
break;
/* #O prints the OS name */
case 'O': vmw_strcat(temp_line,os_info.os_name,
BUFSIZ-strlen(temp_line));
break;
/* #P prints "Processor" or its plural. Sort of a hack */
/* This probably doesn't work with all languages */
case 'P': if (cpu_info.num_cpus!=1) {
vmw_strcat(temp_line,_(PROCESSOR_PLURAL),
BUFSIZ-strlen(temp_line));
}
else {
vmw_strcat(temp_line,_(PROCESSOR_SINGULAR),
BUFSIZ-strlen(temp_line));
}
break;
/* #R prints the amount of memory */
case 'R': mem_size=get_mem_size();
if (mem_size>1023*1024*1024) {
snprintf(temp_string,BUFSIZ,"%.2gPB",
((double)mem_size)/(1024.0*1024.0*1024.0));
}
else if (mem_size>1023*1024*10) {
snprintf(temp_string,BUFSIZ,"%.3gTB",
((double)mem_size)/(1024.0*1024.0));
}
else if (mem_size>1023*1024) {
snprintf(temp_string,BUFSIZ,"%.2gTB",
((double)mem_size)/(1024.0*1024.0));
}
else if (mem_size>1023*10) {
snprintf(temp_string,BUFSIZ,"%.3gGB",
((double)mem_size/1024.0));
}
else if (mem_size>1023) {
snprintf(temp_string,BUFSIZ,"%.2gGB",
((double)mem_size/1024.0));
} else {
snprintf(temp_string,BUFSIZ,"%lldM",mem_size);
}
vmw_strcat(temp_line,temp_string,
BUFSIZ-strlen(temp_line));
break;
/* #S prints "s" if CPU's are more than 1. DEPRECATED */
case 'S': if (cpu_info.num_cpus!=1) {
vmw_strcat(temp_line,"s",BUFSIZ-strlen(temp_line));
}
break;
/* #T prints the CPU type */
case 'T': vmw_strcat(temp_line,cpu_info.chip_type,
BUFSIZ-strlen(temp_line));
break;
/* #U prints the uptime */
case 'U': strcat_uptime(get_uptime(),temp_line,
BUFSIZ-strlen(temp_line));
break;
/* #V prints the OS version */
case 'V': vmw_strcat(temp_line,os_info.os_version,
BUFSIZ-strlen(temp_line));
break;
/* #X Prints the CPU vendor */
case 'X': if (!strncmp(cpu_info.chip_vendor,"Unknown",7)) {
if (strlen(temp_line)>0) {
temp_line[strlen(temp_line)-1]=0;
}
}
else {
vmw_strcat(temp_line,cpu_info.chip_vendor,
BUFSIZ-strlen(temp_line));
}
break;
default: fprintf(stderr,"\nInvalid format '#%c'\n",
settings->format[x]);
}
}
x++;
if (x>=len) break;
}
temp_sysinfo[line]=strdup(temp_line);
line++;
/* If we are using more than the pre-allocated amount */
/* allocate more lines */
if (line>=allocated_lines) {
temp_sysinfo=realloc(temp_sysinfo,
sizeof(char *)*(line+1));
allocated_lines=line;
}
/* skip the newline */
x++;
}
*string=temp_sysinfo;
return line;
}
/* The Main Drawing Routine */
static void draw_logo(struct logo_info *logo_override,
struct linux_logo_info_type *settings) {
struct logo_info *our_logo_info;
char *string_point;
int i,ysize,sysinfo_length=0;
char **sysinfo_string;
sysinfo_length=generate_sysinfo(&sysinfo_string,settings);
if (logo_info_head==NULL) {
printf("\n\nNo logos available!!\n");
return;
}
if (logo_override!=NULL) {
our_logo_info=logo_override;
}
else { /* Search for a proper logo! */
our_logo_info=logo_info_head;
while (1) {
if (our_logo_info==NULL) {
printf("\nAppropriate logo not found!\n\n");
return;
}
if ((settings->banner_mode) &&
(our_logo_info->sysinfo_position==SYSINFO_BOTTOM)) {
if (settings->plain_ascii) {
if (our_logo_info->ascii_logo!=NULL) {
break;
}
}
else { /* Not ascii */
if (our_logo_info->logo!=NULL) {
break;
}
}
}
if ((!settings->banner_mode) &&
(our_logo_info->sysinfo_position==SYSINFO_RIGHT)) { /* Classic mode */
if (settings->plain_ascii) {
if (our_logo_info->ascii_logo!=NULL) {
break;
}
} else { /* Not ascii */
if (our_logo_info->logo!=NULL) {
break;
}
}
}
our_logo_info=our_logo_info->next_logo;
}
}
/* Adjust the width */
/* It doesn't always handle things well if width is less than 80 */
// if (settings->width<80) settings->width=80;
if (settings->width<=0) settings->width=80;
if (settings->wipe_screen) clear_screen(settings->plain_ascii);
/* Select the proper logo */
if (settings->plain_ascii) {
ysize=our_logo_info->ascii_ysize;
if (our_logo_info->ascii_logo==NULL) {
printf("\nSpecified logo has no ascii version!\n\n");
return;
}
else string_point=our_logo_info->ascii_logo;
}
else {
ysize=our_logo_info->ysize;
if (our_logo_info->logo==NULL) {
printf("\nSpecified logo has no non-ascii version!\n\n");
return;
}
else string_point=our_logo_info->logo;
}
/* Draw the logos */
if (!settings->display_sysinfo_only) {
if (settings->banner_mode) { /* Banner mode */
for(i=0;i<ysize;i++) {
shift_right((settings->width-80)/2,settings->plain_ascii);
string_point=print_line(string_point);
printf("\n");
}
if (!settings->display_logo_only) printf("\n");
}
else { /* Classic mode logo */
/* Print the first 7 lines of logo */
if (ysize<7) {
printf("\nError! Classic logos must be at least 7 lines long!\n");
}
if (!settings->plain_ascii) printf("\033[40m\033[40m\n");
for(i=0;i<7;i++) {
shift_right(settings->offset,settings->plain_ascii);
string_point=print_line(string_point);
printf("\n");
}
/* The next lines can have cpuinfo after them */
for(i=7;i<ysize;i++) {
shift_right(settings->offset,settings->plain_ascii);
string_point=print_line(string_point);
shift_right(2,settings->plain_ascii);
if (i-7<sysinfo_length) {
if (!settings->plain_ascii) printf("\033[1;37;40m");
printf("%s",sysinfo_string[i-7]);
if (!settings->plain_ascii) printf("\033[0m");
}
printf("\n");
}
}
}
/* Print the sysinfo if we haven't already */
if (!settings->display_logo_only) {
if (settings->banner_mode) {
for(i=0;i<sysinfo_length;i++) {
if (settings->center_sysinfo) {
center(strlen(sysinfo_string[i]),settings->width,
settings->plain_ascii);
}
if (!settings->plain_ascii) printf("\033[1;37;40m");
printf("%s",sysinfo_string[i]);
if (!settings->plain_ascii) printf("\033[0m");
printf("\n");
free(sysinfo_string[i]);
}
printf("\n");
}
}
free(sysinfo_string);
/* Restore cursor color to normal */
if (!settings->plain_ascii) {
printf("\033[0m\033[255D");
}
}
static char *get_arg(int *index,int argc,char **argv) {
char *argument;
if (argv[*index][2]=='\0') {
(*index)++;
if (*index>=argc) {
argument=NULL;
printf("Missing parameter to option -%c\n\n",argv[(*index)-1][1]);
exit(1);
}
else {
argument=argv[*index];
}
}
else {
argument=&(argv[*index][2]);
}
return argument;
}
/**************************/
/* logo support functions */
/**************************/
/* global variables, a bit of a hack, should find a better way */
int logo_num=0,random_logo=0,want_list_logos=0;
char random_banner='e',random_ascii='e',*logo_name=NULL,*logo_disk=NULL;
/* Find a logo by name */
static struct logo_info *get_logo_by_name(char *logo_name) {
static struct logo_info *custom_logo;
custom_logo=logo_info_head;
while(custom_logo!=NULL) {
if (!strcmp(custom_logo->name,logo_name)) {
return custom_logo;
}
custom_logo=custom_logo->next_logo;
}
fprintf(stderr,"Error! No logo with the name %s is available!\n",logo_name);
return NULL;
}
/* Find a logo by number */
static struct logo_info *get_logo_by_number(int logo_num) {
int i;
static struct logo_info *custom_logo;
custom_logo=logo_info_head;
i=1;
while (i<logo_num) {
if (custom_logo->next_logo==NULL) {
fprintf(stderr,"\nError! Logo %d is invalid! \"linux_logo -L list\""
" lists valid logo numbers.\n\n",logo_num);
custom_logo=logo_info_head;
break;
}
custom_logo=custom_logo->next_logo;
i++;
}
return custom_logo;
}
/* find a random logo */
static struct logo_info *get_random_logo(int random_banner,
int random_ascii,
struct linux_logo_info_type *settings) {
struct timeval time_time;
int i,logo_found;
static struct logo_info *custom_logo;
gettimeofday(&time_time,NULL);
srand(time_time.tv_usec); /* Not really random, but... */
i=rand()%1024; /* Hopefully we have less than 1024 logos FIXME */
custom_logo=logo_info_head;
while(i) {
if (custom_logo->next_logo==NULL) custom_logo=logo_info_head;
else custom_logo=custom_logo->next_logo;
i--;
}
i=0;
while (i<2) {
logo_found=1;
if (random_banner=='b') { /* Want banner mode */
if (!custom_logo->sysinfo_position) logo_found=0;
else settings->banner_mode=1;
}
if (random_banner=='c') { /* Want classic mode */
if (custom_logo->sysinfo_position) logo_found=0;
else settings->banner_mode=0;
}
if (random_banner=='e') { /* Want either */
/* we should be OK */
}
if (random_ascii=='e') { /* Any logo at all */
settings->plain_ascii=rand()%2;
if (custom_logo->ascii_logo==NULL) {
settings->plain_ascii=!settings->plain_ascii;
}
}
if (random_ascii=='a') { /* Want Ascii */
if (custom_logo->ascii_logo==NULL) logo_found=0;
else settings->plain_ascii=1;
}
if (random_ascii=='n') { /* Want non-ascii */
if (custom_logo->logo==NULL) logo_found=0;
else settings->plain_ascii=0;
break;
}
if (logo_found) break;
if (custom_logo->next_logo==NULL) {
custom_logo=logo_info_head;
i++;
}
else custom_logo=custom_logo->next_logo;
}
if (i>1) {
printf("\nSorry, can't generate random logo of that type.\n\n");
exit(1);
}
return custom_logo;
}
/* list the logos */
static void list_logos() {
int i;
struct logo_info *temp_logo;
printf("\nAvailable Built-in Logos:\n");
printf("\tNum\tType\tAscii\tName\t\tDescription\n");
temp_logo=logo_info_head;
i=1;
while (temp_logo!=NULL) {
printf("\t%d",i);
if (temp_logo->sysinfo_position) printf("\tBanner");
else printf("\tClassic");
if (temp_logo->ascii_logo!=NULL) printf("\tYes");
else printf("\tNo");
printf("\t%s",temp_logo->name);
if (strlen(temp_logo->name)<8) printf("\t");
printf("\t%s\n",temp_logo->description);
temp_logo=temp_logo->next_logo;
i++;
}
printf("\nDo \"linux_logo -L num\" where num is from "
"above to get the appropriate logo.\n");
printf("Remember to also use -a to get ascii version.\n\n");
exit(0);
}
/*******************************************************/
/* Parse options (from file or command line arguments) */
/*******************************************************/
static void parse_command_line(struct linux_logo_info_type *settings,
int argc, char **argv) {
int i,x,string_size;
char *endptr,*argument;
int index=1,option;
char *temp_st;
if (argc<2) return;
while (1) {
if (argv[index][0]!='-') {
printf("Unknown parameter %s\n",argv[index]);
exit(1);
}
option=argv[index][1];
switch (option) {
case 'a': settings->plain_ascii=1;
break;
case 'b': settings->banner_mode=1;
break;
case 'c': settings->banner_mode=0;
break;
case 'd': settings->pretty_output=0;
set_pretty_printing(0);
break;
case 'D': argument=get_arg(&index,argc,argv);
logo_disk=strdup(argument);
logo_name=NULL;
break;
case 'e': argument=get_arg(&index,argc,argv);
set_cpuinfo_file(argument);
break;
case 'f': settings->wipe_screen=1;
break;
case 'F': argument=get_arg(&index,argc,argv);
string_size=strlen(argument);
if (string_size==0) break;
settings->custom_format=1;
strncpy(settings->format,argument,BUFSIZ);
settings->format[BUFSIZ-1]=0;
/* Decode the \n's. */
/* Should I decode other \ codes? */
/* also, \ codes are always smaller, hence why */
/* we can overwrite our own buffer */
i=0; x=0;
while(i<strlen(settings->format)) {
if (settings->format[i]=='\\') {
switch(settings->format[i+1]) {
case 'n': settings->format[x]='\n'; i++; break;
default: settings->format[x]='\\'; break;
}
}
else {
settings->format[x]=settings->format[i];
}
i++; x++;
}
settings->format[x]='\0';
break;
case 'g': settings->display_sysinfo_only=1;
break;
case 'h':
case '?': help_message(argv[0], 1);
exit(0);
break;
/* FIXME */
case 'i': /* is it even possible to do this right? */
/* we'd have to do two passes, possibly */
/* resetting to defaults in between */
/*ignore_config_file=1; */
break;
case 'k': settings->center_sysinfo=0;
break;
case 'l': settings->display_logo_only=1;
break;
case 'L': argument=get_arg(&index,argc,argv);
/* Reset values in case we get this after reading */
/* the file */
logo_num = 1; random_logo = 0;
logo_num=strtol(argument,&endptr,10);
if ( endptr == argument ) {
/* we leak temp_st, need to fix */
temp_st=strdup(argument);
if (!strncmp(temp_st,"list",4)) {
want_list_logos=1;
}
else if (!strncmp(temp_st,"random",6)) {
random_logo=1;
if (strlen(temp_st)>7) {
random_banner=temp_st[7];
}
if (strlen(temp_st)>8) {
random_ascii=temp_st[8];
}
}
else {
logo_name=strdup(temp_st);
}
}
else { /* It's a number. Override any name */
logo_name=NULL;
}
break;
case 'n': settings->no_periods=1;
break;
case 'o': argument=get_arg(&index,argc,argv);
settings->offset=strtol(argument,&endptr,10);
if ( endptr == argument ) {
printf("Invalid offset length %s\n\n",argument);
exit(1);
}
break;
case 'p': settings->preserve_xy=1;
break;
case 's': settings->skip_bogomips=1;
break;
case 't': argument=get_arg(&index,argc,argv);
settings->display_usertext=1;
strncpy(settings->user_text,argument,BUFSIZ-1);
break;
case 'u': settings->show_uptime=1;
break;
case 'v': help_message(argv[0], 0);
exit(0);
break;
case 'w': argument=get_arg(&index,argc,argv);
settings->width=strtol(argument,&endptr,10);
if ( endptr == argument ) {
printf("Invalid width %s\n\n",argument);
exit(1);
}
break;
case 'y': settings->show_load=1;
break;
default: printf("Unknown option -%c\n",option);
exit(1);
}
index++;
if (index>=argc) break;
}
}
/* Look for ~/.linux_logo or /etc/linux_logo config files */
void read_config_file(struct linux_logo_info_type *settings) {
int string_size,total_size,valid_string=0,i,size=0,counter=0;
int fake_data_offset=0,ch,oldch,in_quote=0,fake_argc=0;
char *tempst,*fake_data,**fake_argv;
FILE *config_file=NULL;
char config_string[BUFSIZ];
char config_filename[]="/.linux_logo";
/* Check for the files */
/* look for ~/.linux_logo */
if (getenv("HOME")) {
string_size=strlen(getenv("HOME"));
total_size=strlen(config_filename)+string_size;
tempst=calloc(total_size+1,sizeof(char));
strncpy(tempst,getenv("HOME"),string_size);
memcpy(tempst+string_size,config_filename,strlen(config_filename));
config_file=fopen(tempst,"r");
free(tempst); /* free the callocs! */
}
/* if no ~/.linux_logo, check for /etc/linux_logo.conf */
if (config_file==NULL) {
config_file=fopen("/etc/linux_logo.conf","r");
}
/* If no config files, just make do with command-line arguments */
/* Note to Vince of 2000.. this was the most horrible */
/* atrocity of code ever. -- Vince of 2006 */
/* It should be a lot better now. -- Vince of 2007 */
if (config_file!=NULL) {
/* skip over whitespace and comments */
while(!valid_string) {
if (fgets(config_string,BUFSIZ,config_file)) {
for(i=0;i<strlen(config_string);i++) {
/* a comment */
if (config_string[i]=='#') break;
/* empty line */
else if (config_string[i]=='\n') break;
/* whitespace */
else if (config_string[i]==' ' ||
config_string[i]=='\t');