1
/*-------------------------------------------------------------------------*\
2
LINUX LOGO 4.14 - Creates Nifty Logo With System Info - 20 July 2006
4
by Vince Weaver (vince@deater.net, http://www.deater.net/weave )
6
A program to display text/ansi logos with system information.
8
Thanks to many, many people who sent patches in. See the CHANGES file for
9
a list of all those who helped out.
11
\*-------------------------------------------------------------------------*/
18
#include <sys/utsname.h>
25
#define VERSION "4.14"
28
#include "linux_logo.h"
29
#include "logo_types.h"
30
#include "vmw_string.h"
32
/* Change the values in the below file to alter default behavior */
35
/* See defaults.h when setting this */
38
#define _(string) string
42
#define SAVE_GETOPT {old_optind=optind; old_opterr=opterr; old_optopt=optopt;}
43
#define RESET_GETOPT {optind=old_optind; opterr=old_opterr; optopt=old_optopt;}
45
#define FILE_OPTIONS_PASS 0
46
#define COMMAND_OPTIONS_PASS 1
47
#define WANT_DEFAULT_OPTIONS_PASS 2
49
char *ordinal(int value) {
53
case 0: strncpy(text,_("Zero"),19); break;
54
case 1: strncpy(text,_("One"),19); break;
55
case 2: strncpy(text,_("Two"),19); break;
56
case 3: strncpy(text,_("Three"),19); break;
57
case 4: strncpy(text,_("Four"),19); break;
58
case 5: strncpy(text,_("Five"),19); break;
59
case 6: strncpy(text,_("Six"),19); break;
60
case 7: strncpy(text,_("Seven"),19); break;
61
case 8: strncpy(text,_("Eight"),19); break;
62
case 9: strncpy(text,_("Nine"),19); break;
63
default: strncpy(text,_("Many"),19);break;
70
/* Some global variables. Possibly bad in practice, but it saves a lot *\
71
\* of paramater passing, which has caused bugs to develop before. */
73
struct logo_info *logo_info_head = NULL;
74
struct logo_info *logo_info_tail = NULL;
76
void draw_banner_logo(struct logo_info *the_logo, struct linux_logo_info_type *settings);
78
struct logo_info *load_logo_from_disk(char *filename) {
80
struct logo_info *new_logo;
81
int logo_start=0,ascii_logo_start=0;
82
int ascii_size=0,size=0;
86
new_logo=calloc(1,sizeof(struct logo_info));
89
printf("Error allocating memory!\n");
93
fff=fopen(filename,"r");
95
printf("Error loading logo: %s\n",filename);
100
new_logo->ascii_logo=NULL;
103
read_string_from_disk_exact(fff,temp_st);
104
if (!strncmp(temp_st,"END_LOGO",8)) logo_start=0;
105
if (!strncmp(temp_st,"END_ASCII_LOGO",14)) ascii_logo_start=0;
107
size+=strlen(temp_st);
108
if (new_logo->logo==NULL) {
109
new_logo->logo=strdup(temp_st);
112
new_logo->logo=realloc(new_logo->logo,size+1);
113
strncat( new_logo->logo,temp_st,strlen(temp_st));
117
if (ascii_logo_start) {
118
ascii_size+=strlen(temp_st);
119
if (new_logo->ascii_logo==NULL) {
120
new_logo->ascii_logo=strdup(temp_st);
123
new_logo->ascii_logo=realloc(new_logo->ascii_logo,ascii_size+1);
124
strncat( new_logo->ascii_logo,temp_st,strlen(temp_st));
126
new_logo->ascii_ysize++;
128
if (!strncmp(temp_st,"BEGIN_ASCII_LOGO",16)) ascii_logo_start=1;
129
if (!strncmp(temp_st,"BEGIN_LOGO",10)) logo_start=1;
130
if ( (!ascii_logo_start) && (!logo_start) ) {
131
if (!strncmp(temp_st,"SYSINFO_POSITION",16)) {
132
if (!strncmp(temp_st+17,"bottom",6)) {
133
new_logo->sysinfo_position=SYSINFO_BOTTOM;
135
if (!strncmp(temp_st+17,"right",5)) {
136
new_logo->sysinfo_position=SYSINFO_RIGHT;
139
if (!strncmp(temp_st,"DESCRIPTION_STRING",18)) {
140
new_logo->description=strdup(temp_st+19);
145
new_logo->next_logo=NULL;
147
logo_info_tail=new_logo;
155
struct logo_info *logo;
156
struct logo_info *prev_logo;
161
if (logo->description) free(logo->description);
162
if (logo->logo) free(logo->logo);
163
if (logo->ascii_logo) free(logo->ascii_logo);
165
logo=logo->next_logo;
175
struct logo_info *new_logo;
177
#include "load_logos.h"
179
// logo_info_head=load_logo_from_disk("./logos/banner.logo");
180
// logo_info_tail->next_logo=load_logo_from_disk("./logos/classic.logo");
183
/* Setup the "settings" structure to some defaults */
184
/* Edit the "defaults.h" file to change these */
185
void setup_info(struct linux_logo_info_type *settings) {
187
settings->width=DEFAULT_WIDTH; /* Defaults to 80 */
188
settings->no_periods=DEFAULT_NO_PERIODS; /* Defaults to None */
189
settings->preserve_xy=DEFAULT_PRESERVE_XY; /* Defaults to Off */
190
settings->skip_bogomips=DEFAULT_SKIP_BOGOMIPS; /* Defaults to No */
191
settings->offset=DEFAULT_OFFSET; /* Defaults to 0 */
192
settings->plain_ascii=DEFAULT_PLAIN_ASCII; /* Defaults to No */
193
settings->banner_mode=DEFAULT_BANNER_MODE; /* Defualts to Yes */
194
settings->wipe_screen=DEFAULT_WIPE_SCREEN; /* Defaults to No */
195
settings->show_uptime=DEFAULT_SHOW_UPTIME; /* Defaults to No */
196
settings->show_load=DEFAULT_SHOW_LOAD; /* Defaults to No */
197
settings->narrow_logo=DEFAULT_NARROW_LOGO; /* Defaults to No */
198
settings->pretty_output=DEFAULT_PRETTY_OUTPUT; /* Defaults to Yes */
199
set_pretty_printing(DEFAULT_PRETTY_OUTPUT);
200
settings->display_logo_only=0;
201
settings->display_sysinfo_only=0;
202
settings->display_usertext=0;
203
settings->custom_format=0;
204
settings->center_sysinfo=1;
205
settings->user_text = NULL; /* Change this and display_usertext to *\
206
\* have a default message */
207
settings->format=NULL;
210
/* Use ansi codes or spaces to shift the cursor to the right */
211
void shift_right(int shift,int plain_ascii)
215
if (shift<=0) return;
217
if (plain_ascii) for(i=0;i<shift;i++) putchar(' ');
218
else printf("%c[%iC",ESCAPE,shift);
221
/* Prints an ansi string, changing "^[" to the ESCAPE charachter '\033' *\
222
\* And also enables easier parsing of the output */
223
/* The name doesn't indicate any sort of ANSI standard; it is left over *\
224
\* from years gone by when I used to make "ansi art" for a WWIV BBS */
225
int ansi_print(const char *string)
233
case '^' : if (string[i+1]=='[') {putchar(ESCAPE); i++;} break;
234
case '\\': if (string[i+1]=='n') {printf("\n"); i++;}
235
default : putchar(string[i]);
244
char *print_line(char *string)
247
char *temp_st=string;
249
while ((*temp_st!='\n') && (*temp_st!='\0')) {
253
if ((*temp_st)=='\n') {
260
/* print some centered text */
261
void center_and_print(char *string,int size,int width,
262
struct linux_logo_info_type *settings)
266
if (settings->center_sysinfo) {
268
shift_right(i,settings->plain_ascii);
271
/* Why was I setting the colors here? */
272
if (!settings->plain_ascii) ansi_print("^[[1;37;40m");
274
if (!settings->plain_ascii) ansi_print("^[[0m");
278
/* Uses escape codes to clear the screen */
279
void clear_screen(struct linux_logo_info_type *settings)
281
if (!settings->plain_ascii) ansi_print("^[[2J^[[0;0H\n");
284
/* Change uptime seconds into time string */
285
char *uptime_string(int seconds) {
287
int up_days,up_hrs,up_mins;
288
char temp_string[BUFSIZ];
290
up_days=seconds/86400;
291
up_hrs=(seconds-(up_days*86400))/3600;
292
up_mins=(seconds-(up_days*86400)-(up_hrs*3600))/60;
295
sprintf(temp_string,"Uptime %d %s %d %s",
296
up_hrs,(up_hrs==1 ? "hour":"hours"),
297
up_mins,(up_mins==1 ? "minute":"minutes"));
299
sprintf(temp_string,"Uptime %d %s %d %s %d %s",
300
up_days,(up_days==1 ? "day":"days"),
301
up_hrs,(up_hrs==1 ? "hour":"hours"),
302
up_mins,(up_mins==1 ? "minute":"minutes"));
303
return strdup(temp_string);
306
/* Prints the help */
307
void help_message(char *binname, char full)
309
char temp_version[256];
310
printf("\nLinux Logo Version %s using libsysinfo %s\n",VERSION,
311
get_sysinfo_version(temp_version));
312
printf("\tby Vince Weaver <vince@deater.net>\n");
313
printf(" Newest Versions at:\n");
314
printf(" http://www.deater.net/weave/vmwprod/linux_logo\n");
315
printf(" http://metalab.unc.edu/pub/Linux/logos/penguins\n\n");
317
printf("Usage: %s [-a] [-b] [-c] [-d] [-D file] [-e file] [-f] "
319
" [-h] [-i] [-k] [-l] [-n] [-o num] [-p] [-s] [-t str] "
321
" [-w Num] [-x] [-y] [-F format] "
322
"[-L num | list | random_xy]\n",binname);
323
printf(" [-a] -- Display an ascii-only Logo\n");
324
printf(" [-b] -- Display a Banner Logo!\n");
325
printf(" [-c] -- Display a \"Classic\" type logo\n");
326
printf(" [-d] -- disable \"prettying\" of output\n");
327
printf(" [-D file]-- use custom logo from \"file\"\n");
328
printf(" [-e file]-- Use \"file\" instead of /proc/cpuinfo [for "
330
printf(" [-f] -- force the screen clear before drawing\n");
331
printf(" [-F format] Format output. See README.\n");
332
printf(" B [-g] -- give system info only\n");
333
printf(" [-h] -- this help screen\n");
334
printf(" [-i] -- ignore ~/.linux_logo and /etc/linux_logo.conf\n");
335
printf(" [-k] -- keep sysinfo flushed-left (non-centered)\n");
336
printf(" B [-l] -- display logo only\n");
337
printf(" C [-o Num] -- offset output Num spaces to the right\n");
338
printf(" [-p] -- preserve cursor location\n");
339
printf(" [-s] -- skip Bogomips [speeds up on non-Linux "
341
printf(" [-t str] -- display user-supplied string\n");
342
printf(" * [-u] -- show uptime\n");
343
printf(" [-v] -- version information\n");
344
printf(" [-w Num] -- set width of screen to Num [default 80]\n");
345
printf(" * [-y] -- show load average\n");
346
printf(" [-L ...] -- multiple Logo options. See README\n\n");
347
printf(" B=Banner mode only, C=Classic Mode Only *=Works Only in Linux"
351
/* The nifty customizable sysinfo parser */
352
int print_sysinfo(int line, char *string,
353
struct linux_logo_info_type *settings) {
355
static os_info_t os_info;
356
static cpu_info_t cpu_info;
358
static int sysinfo_already_run=0;
362
char temp_string[255],hostname[65],domain[65];
363
float load_1,load_5,load_15;
365
/* We only need to fetch the system info once */
366
if (!sysinfo_already_run) {
367
get_os_info(&os_info);
368
get_cpu_info(&cpu_info);
369
sysinfo_already_run=1;
372
len=strlen(settings->format);
375
string[string_ptr]='\000';
378
if (settings->format[x]=='\n') y++;
383
while (settings->format[x]!='\n') {
384
if (settings->format[x]!='#') {
385
string[string_ptr]=settings->format[x];
389
string[string_ptr]='\000';
392
switch(settings->format[x]) {
393
case '#': string_ptr+=vmw_strcat(string,"#"); break;
394
case 'B': if (cpu_info.bogomips<10000.0) {
395
sprintf(temp_string,"%.2f",cpu_info.bogomips);
398
sprintf(temp_string,"%.0f",cpu_info.bogomips);
400
string_ptr+=vmw_strcat(string,temp_string); break;
401
case 'C': string_ptr+=vmw_strcat(string,os_info.os_revision); break;
402
case 'E': string_ptr+=vmw_strcat(string,settings->user_text); break;
403
case 'H': string_ptr+=vmw_strcat(string,get_host_name(hostname,domain)); break;
404
case 'L': get_load_average(&load_1,&load_5,&load_15);
405
sprintf(temp_string,"Load Average %.2f, %.2f, %.2f",load_1,load_5,load_15);
406
string_ptr+=vmw_strcat(string,temp_string);
408
case 'M': if (cpu_info.megahertz>0.0) {
409
if (cpu_info.megahertz>999.0) {
410
sprintf(temp_string,"%.3gGHz",cpu_info.megahertz/1000.0);
413
sprintf(temp_string,"%.3gMHz",cpu_info.megahertz);
415
string_ptr+=vmw_strcat(string,temp_string);
418
/* No megahertz. Back up the pointer. This is a hack */
419
if (string_ptr>0) string_ptr--;
422
case 'N': if (cpu_info.num_cpus<=9)
423
string_ptr+=vmw_strcat(string,ordinal(cpu_info.num_cpus));
424
else if (cpu_info.num_cpus<=99999) {
425
sprintf(temp_string,"%d",cpu_info.num_cpus);
426
string_ptr+=vmw_strcat(string,temp_string);
428
else string_ptr+=vmw_strcat(string,ordinal(10));
430
case 'O': string_ptr+=vmw_strcat(string,os_info.os_name); break;
431
case 'P': if (cpu_info.num_cpus!=1)
432
string_ptr+=vmw_strcat(string,_(PROCESSOR_PLURAL));
433
else string_ptr+=vmw_strcat(string,_(PROCESSOR_SINGULAR));
435
case 'R': if (get_mem_size()>1000000) {
436
sprintf(temp_string,"%.2gTB",
437
((float)get_mem_size())/(1024.0*1024.0));
439
else if (get_mem_size()>1000) {
440
sprintf(temp_string,"%.2gGB",
441
((float)get_mem_size())/1024.0);
442
} else sprintf(temp_string,"%ldM",get_mem_size());
443
string_ptr+=vmw_strcat(string,temp_string);
445
case 'S': if (cpu_info.num_cpus!=1)
446
string_ptr+=vmw_strcat(string,"s"); break;
447
case 'T': string_ptr+=vmw_strcat(string,cpu_info.chip_type); break;
448
case 'U': string_ptr+=vmw_strcat(string,uptime_string(get_uptime()));
450
case 'V': string_ptr+=vmw_strcat(string,os_info.os_version); break;
451
case 'X': if (!strncmp(cpu_info.chip_vendor,"Unknown",7)) {
452
if (string_ptr>0) string_ptr--;
455
string_ptr+=vmw_strcat(string,cpu_info.chip_vendor);
458
default: printf("\nInvalid format '#%c'\n",settings->format[x]);
465
string[string_ptr]='\000';
469
/* The Main Drawing Routine */
470
void draw_logo(struct logo_info *logo_override,
471
struct linux_logo_info_type *settings)
473
struct logo_info *our_logo_info;
474
char temp_string[BUFSIZ];
478
if (logo_info_head==NULL) {
479
printf("\n\nNo logos available!!\n");
483
if (logo_override!=NULL) {
484
our_logo_info=logo_override;
487
else { /* Search for a proper logo! */
489
our_logo_info=logo_info_head;
491
if (our_logo_info==NULL) {
492
printf("\nAppropriate logo not found!\n\n");
495
if ((settings->banner_mode) && (our_logo_info->sysinfo_position==SYSINFO_BOTTOM)) {
496
if (settings->plain_ascii) {
497
if (our_logo_info->ascii_logo!=NULL) {
501
else { /* Not ascii */
502
if (our_logo_info->logo!=NULL) {
507
if ((!settings->banner_mode) && (our_logo_info->sysinfo_position==SYSINFO_RIGHT)) { /* Classic mode */
508
if (settings->plain_ascii) {
509
if (our_logo_info->ascii_logo!=NULL) {
512
} else { /* Not ascii */
513
if (our_logo_info->logo!=NULL) {
518
our_logo_info=our_logo_info->next_logo;
522
if (settings->width<80) settings->width=80; /* Right now we don't */
523
/* handle width < 80 */
525
if (settings->wipe_screen) clear_screen(settings);
527
/* Select the proper logo */
528
if (settings->plain_ascii) {
529
ysize=our_logo_info->ascii_ysize;
530
if (our_logo_info->ascii_logo==NULL) {
531
printf("\nSpecified logo has no ascii version!\n\n");
534
else string_point=our_logo_info->ascii_logo;
537
ysize=our_logo_info->ysize;
538
if (our_logo_info->logo==NULL) {
539
printf("\nSpecified logo has no non-ascii version!\n\n");
542
else string_point=our_logo_info->logo;
546
if (!settings->display_sysinfo_only) {
547
if (settings->banner_mode) { /* Banner mode */
548
for(i=0;i<ysize;i++) {
549
shift_right((settings->width-80)/2,settings->plain_ascii);
550
string_point=print_line(string_point);
553
if (!settings->display_logo_only) printf("\n");
555
else { /* Classic mode logo */
557
/* Print the first 7 lines of logo */
560
printf("\nError! Classic logos must be at least 7 lines long!\n");
563
if (!settings->plain_ascii) ansi_print("^[[40m^[[40m\n");
566
shift_right(settings->offset,settings->plain_ascii);
567
string_point=print_line(string_point);
571
/* The next lines can have cpuinfo after them */
572
for(i=7;i<ysize;i++) {
573
shift_right(settings->offset,settings->plain_ascii);
574
string_point=print_line(string_point);
575
shift_right(2,settings->plain_ascii);
576
if (print_sysinfo(i-7,temp_string,settings)!=1) {
577
if (!settings->plain_ascii) ansi_print("^[[1;37;40m");
578
printf("%s",temp_string);
579
if (!settings->plain_ascii) ansi_print("^[[0m");
586
/* Print the sysinfo if we haven't already */
587
if (!settings->display_logo_only) {
588
if (settings->banner_mode) {
590
while (print_sysinfo(i,temp_string,settings)!=1) {
591
center_and_print(temp_string,strlen(temp_string),settings->width,
598
/* Restore cursor color to normal */
599
if (!settings->plain_ascii)
600
ansi_print("^[[0m^[[255D");
604
int main(int argc,char **argv)
606
char *endptr,*temp_st;
607
int c,i,x,logo_num=1,random_logo=0,do_listing=0,logo_override=0;
609
char temp_string[BUFSIZ],random_type='e',random_type2='e';
610
struct linux_logo_info_type settings;
611
struct logo_info *temp_logo,*custom_logo=NULL;
612
struct timeval time_time;
613
FILE *config_file=NULL;
615
char **fake_argv=NULL;
616
int file_size=0,ch=0,in_quote=0,fake_data_offset=0,fake_argc=0,counter=0;
617
int oldch=0,arguments_pass=0,read_from_file=0;
618
int *custom_argc=NULL;
619
char **custom_argv=NULL;
620
int ignore_config_file=0;
621
int old_optind,old_opterr,old_optopt,string_size;
623
char config_string[BUFSIZ];
628
setlocale(LC_ALL, "");
629
textdomain("linux_logo");
630
bindtextdomain("linux_logo", "/usr/lib/locale");
632
/* Set some defaults */
633
setup_info(&settings);
635
/* ****************************************************** */
636
/* Look for ~/.linux_logo or /etc/linux_logo config files */
637
/* ****************************************************** */
639
/* Check for the files */
641
/* look for ~/.linux_logo */
642
if (getenv("HOME")) {
643
string_size=strlen(getenv("HOME"));
644
tempst=calloc(strlen("/.linux_logo")+string_size+1,sizeof(char));
645
strncpy(tempst,getenv("HOME"),string_size);
646
strncat(tempst,"/.linux_logo",strlen("/.linux_logo"));
647
config_file=fopen(tempst,"r");
648
free(tempst); /* free the calloc's! */
651
/* if no ~/.linux_logo, check for /etc/linux_logo.conf */
652
if (config_file==NULL) {
653
config_file=fopen("/etc/linux_logo.conf","r");
656
/* If no config files, just make do with command-line arguments */
657
/* Note to Vince of 2000.. this is the most horrible */
658
/* atrocity of code ever. -- Vince of 2006 */
660
if (config_file==NULL) {
666
/* Create "fake" argc and argv */
669
while(!valid_string) {
670
fgets(config_string,BUFSIZ,config_file);
671
for(i=0;i<strlen(config_string);i++) {
672
if (config_string[i]=='#') break; /* a comment */
673
else if (config_string[i]=='\n') break; /* empty line */
674
else if (config_string[i]==' ' || config_string[i]=='\t'); /* whitespace */
680
if (feof(config_file)) break;
685
file_size=strlen(config_string);
688
config_string[file_size-1]='\0'; /* get rid of trailing \n */
690
/* create room for the fake command-line */
691
fake_data=calloc(file_size+12,sizeof(char));
692
/* stick "linux_logo" as argv[0] */
693
strncpy(fake_data,"linux_logo ",11);
695
strncat(fake_data,config_string,file_size);
698
for(i=0;i<file_size;i++) {
701
ch=config_string[i]; /* start after linux_logo */
703
/* if after a space, and not in a quote, begin a new token */
704
if ((oldch==' ') && (!in_quote) && (ch!=' ')) {
705
if (fake_data_offset>0) fake_data[fake_data_offset]='\0';
710
/* The shell strips quotes and excess whitespace */
711
/* thought for now we just strip spaces outside of quotations */
712
if ((ch!='\"') && ((ch!=' ') || ((ch==' ') && (in_quote)))) {
713
fake_data[fake_data_offset]=ch;
717
/* start/end a quotation */
718
if (ch=='\"') in_quote= !in_quote;
724
fake_argc+=1; /* plus the last one */
726
/* Allocate room for the fake argv[] list of pointers */
727
/* +1 cause NULL at the end */
728
fake_argv=calloc(fake_argc+1,sizeof(char *));
730
fake_argv[0]=fake_data;
732
/* Actually find the tokens based on the NULLs put before */
733
for(i=0;i<fake_data_offset;i++) {
734
if (fake_data[i]=='\0') {
735
if (counter<fake_argc) {
736
fake_argv[counter]=fake_data+i+1;
748
/* Hack! Hack! Hack! Oh, why do I abuse getopt() so */
751
while (arguments_pass<3) {
752
/* Pass 0 read from file, if there */
753
if (arguments_pass==0) {
754
if (!read_from_file) {
758
custom_argc=&fake_argc;
759
custom_argv=fake_argv;
762
/* Pass 1 is command-line and overrides file */
763
if (arguments_pass==1) {
764
/* reset getopt() *HACK HACK HACK* */
770
/* -i passed, so reset everything and just go through command */
772
if (arguments_pass==2) {
773
setup_info(&settings);
781
/*******************************************************/
782
/* Parse options (from file or command line arguments) */
783
/*******************************************************/
785
while ((c = getopt (*custom_argc, custom_argv,"D:F:L:"
786
"a::b::c::de:fghiklno:pst:uvw:y"))!=-1) {
788
case 'a': settings.plain_ascii=1; break;
789
case 'b': settings.banner_mode=1; break;
790
case 'c': settings.banner_mode=0; logo_num=2; break;
791
case 'd': settings.pretty_output=0;
792
set_pretty_printing(0);
794
case 'D': custom_logo=load_logo_from_disk(optarg);
796
case 'e': set_cpuinfo_file(optarg); break;
797
case 'f': settings.wipe_screen=1; break;
798
case 'F': string_size=strlen(optarg);
799
if (string_size==0) break;
801
settings.custom_format=1;
802
if (settings.format) free(settings.format);
804
settings.format=calloc(string_size,sizeof(char));
805
strncpy(settings.format,optarg,string_size);
807
/* Decode the \n's. */
808
/* Should I decode other \ codes? */
809
/* also, \ codes are always smaller, hence why */
810
/* we can overwrite our own buffer */
813
while(i<strlen(settings.format)) {
814
if (settings.format[i]=='\\') {
815
switch(settings.format[i+1]) {
816
case 'n': settings.format[x]='\n'; i++; break;
817
default: settings.format[x]='\\'; break;
820
else settings.format[x]=settings.format[i];
823
settings.format[x]='\0';
825
case 'g': settings.display_sysinfo_only=1; break;
826
case 'h': help_message(argv[0], 1);
829
case 'i': ignore_config_file=1;
831
case 'k': settings.center_sysinfo=0;
833
case 'l': settings.display_logo_only=1; break;
835
/* Reset values in case we get this after
836
* reading the file */
837
logo_num = 1; logo_override = 0; random_logo = 0;
838
logo_num=strtol(optarg,&endptr,10);
839
if ( endptr == optarg ) {
840
temp_st=strdup(optarg);
841
if (!strncmp(temp_st,"list",4)) {
845
if (!strncmp(temp_st,"random",6)) {
847
random_type=temp_st[7];
848
random_type2=temp_st[8];
851
printf("\nUnknown -L directive!\n\n");
855
else { /* It's a number */
859
case 'n': settings.no_periods=1; break;
861
settings.offset=strtol(optarg,&endptr,10);
862
if ( endptr == optarg ) help_message(argv[0], 1);
864
case 'p': settings.preserve_xy=1; break;
865
case 's': settings.skip_bogomips=1; break;
867
settings.display_usertext=1;
868
settings.user_text=strdup(optarg);
870
case 'u': settings.show_uptime=1; break;
871
case 'v': help_message(argv[0], 0);
875
settings.width=strtol(optarg,&endptr,10);
876
if ( endptr == optarg ) help_message(argv[0], 1);
878
case 'y': settings.show_load=1; break;
879
case '?': printf("Try \"%s -h\" to show help\n\n",argv[0]);
885
/* If unkown arguments, print the help */
886
if ( custom_argv[optind] != NULL ) {
887
printf("Unkown option %i: \"%s\"\n",optind,custom_argv[optind]);
892
if ((!ignore_config_file) && (arguments_pass==2)) arguments_pass++;
895
/*******************************************************/
896
/* DONE WITH ALL THE STUPID OPTION PARSING */
897
/* now actually do things */
898
/*******************************************************/
900
setup_logos(&settings);
903
printf("\nAvailable Built-in Logos:\n");
904
printf("\tNum\tType\tAscii\tDescription\n");
906
temp_logo=logo_info_head;
908
while (temp_logo!=NULL) {
910
if (temp_logo->sysinfo_position) printf("\tBanner");
911
else printf("\tClassic");
912
if (temp_logo->ascii_logo!=NULL) printf("\tYes");
914
printf("\t%s\n",temp_logo->description);
915
temp_logo=temp_logo->next_logo;
918
printf("\nDo \"linux_logo -L num\" where num is from "
919
"above to get the appropriate logo.\n");
920
printf("Remember to also use -a to get ascii version.\n\n");
925
gettimeofday(&time_time,NULL);
926
srand(time_time.tv_usec); /* Not really random, but... */
927
i=rand()%1024; /* Hopefully we have less than 1024 logos */
928
custom_logo=logo_info_head;
930
if (custom_logo->next_logo==NULL) custom_logo=logo_info_head;
931
else custom_logo=custom_logo->next_logo;
937
if (random_type=='b') { /* Want banner mode */
938
if (!custom_logo->sysinfo_position) logo_found=0;
939
else settings.banner_mode=1;
941
if (random_type=='c') { /* Want classic mode */
942
if (custom_logo->sysinfo_position) logo_found=0;
943
else settings.banner_mode=0;
945
if (random_type=='e') { /* Want either */
946
/* we should be OK */
949
if (random_type2=='e') { /* Any logo at all */
950
settings.plain_ascii=rand()%2;
951
if (custom_logo->ascii_logo==NULL)
952
settings.plain_ascii=!settings.plain_ascii;
954
if (random_type2=='a') { /* Want Ascii */
955
if (custom_logo->ascii_logo==NULL) logo_found=0;
956
else settings.plain_ascii=1;
959
if (random_type2=='n') { /* Want non-ascii */
960
if (custom_logo->logo==NULL) logo_found=0;
961
else settings.plain_ascii=0;
965
if (logo_found) break;
967
if (custom_logo->next_logo==NULL) {
968
custom_logo=logo_info_head;
971
else custom_logo=custom_logo->next_logo;
974
printf("\nSorry, can't generate random logo of that type.\n\n");
980
custom_logo=logo_info_head;
983
if (custom_logo->next_logo==NULL) {
984
printf("\nError! Logo %d is invalid! \"linux_logo -L list\""
985
" lists valid logo numbers.\n\n",logo_num);
988
custom_logo=custom_logo->next_logo;
993
/* We have to keep these consistent or funny things happen */
994
if (custom_logo!=NULL) {
995
settings.banner_mode=custom_logo->sysinfo_position;
998
/* Prepare the sysinfo stuff if not done for us */
999
/* Handle "normal" output by basically faking the */
1000
/* appropriate "custom" output string */
1001
if (!settings.custom_format) {
1002
if (settings.banner_mode)
1003
settings.format=strdup(_(DEFAULT_BANNER_FORMAT));
1004
else settings.format=strdup(DEFAULT_CLASSIC_FORMAT);
1006
if (settings.display_usertext) {
1007
sprintf(temp_string,"#E\n%s",settings.format);
1008
settings.format=strdup(temp_string);
1011
if (settings.show_load) {
1012
settings.format[strlen(settings.format)-3]='\000';
1013
sprintf(temp_string,"%s#L\n#H\n",settings.format);
1014
settings.format=strdup(temp_string);
1017
if (settings.show_uptime) {
1018
settings.format[strlen(settings.format)-3]='\000';
1019
sprintf(temp_string,"%s#U\n#H\n",settings.format);
1020
settings.format=strdup(temp_string);
1024
/* Preserve xy if so desired */
1025
if ((settings.preserve_xy) && (!settings.plain_ascii))
1030
draw_logo(custom_logo,&settings);
1032
/* Restore xy if we saved it */
1033
if ((settings.preserve_xy) && (!settings.plain_ascii)) ansi_print("^[8");
1
/*-------------------------------------------------------------------------*\
2
LINUX LOGO 5.03 - Creates Nifty Logo With System Info - 3 January 2008
4
by Vince Weaver (vince@deater.net, http://www.deater.net/weave )
6
A program to display text/ansi logos with system information.
8
Thanks to many, many people who sent patches in.
9
See the CHANGES file for a list of all those who helped out.
10
\*-------------------------------------------------------------------------*/
13
#define VERSION "5.03"
16
#include <stdlib.h> /* calloc() */
17
#include <string.h> /* strdup() */
18
#include <sys/time.h> /* time() */
24
#include "linux_logo.h"
25
#include "logo_types.h"
26
#include "load_logo.h"
31
#define _(String) gettext((String))
33
#define _(String) (String)
36
/* Change the values in the below file to alter default behavior */
39
/* Some global variables. Possibly bad in practice, but it saves a lot *\
40
\* of paramater passing, which has caused bugs to develop before. */
42
struct logo_info *logo_info_head = NULL;
43
struct logo_info *logo_info_tail = NULL;
46
char *vmw_strcat(char *dest, char *src, int space_remaining) {
48
if (strlen(src) >= space_remaining) {
49
fprintf(stderr,"Error! Not enough room in string!\n\n");
52
return strcat(dest,src);
55
/* Convert a number into an ordinal string */
56
static void strcat_ordinal(int value,char *string, int space) {
59
case 0: vmw_strcat(string,_("Zero"),space); break;
60
case 1: vmw_strcat(string,_("One"),space); break;
61
case 2: vmw_strcat(string,_("Two"),space); break;
62
case 3: vmw_strcat(string,_("Three"),space); break;
63
case 4: vmw_strcat(string,_("Four"),space); break;
64
case 5: vmw_strcat(string,_("Five"),space); break;
65
case 6: vmw_strcat(string,_("Six"),space); break;
66
case 7: vmw_strcat(string,_("Seven"),space); break;
67
case 8: vmw_strcat(string,_("Eight"),space); break;
68
case 9: vmw_strcat(string,_("Nine"),space); break;
69
default: vmw_strcat(string,_("Many"),space); break;
74
/* setup the default logos, which are always present */
75
static void setup_default_logos() {
77
struct logo_info *new_logo;
79
#include "load_logos.h"
84
/* Setup the "settings" structure to some defaults */
85
/* Edit the "defaults.h" file to change these */
86
static void setup_info(struct linux_logo_info_type *settings) {
88
settings->width=DEFAULT_WIDTH; /* Defaults to 80 */
89
settings->no_periods=DEFAULT_NO_PERIODS; /* Defaults to None */
90
settings->preserve_xy=DEFAULT_PRESERVE_XY; /* Defaults to Off */
91
settings->skip_bogomips=DEFAULT_SKIP_BOGOMIPS; /* Defaults to No */
92
settings->offset=DEFAULT_OFFSET; /* Defaults to 0 */
93
settings->plain_ascii=DEFAULT_PLAIN_ASCII; /* Defaults to No */
94
settings->banner_mode=DEFAULT_BANNER_MODE; /* Defualts to Yes */
95
settings->wipe_screen=DEFAULT_WIPE_SCREEN; /* Defaults to No */
96
settings->show_uptime=DEFAULT_SHOW_UPTIME; /* Defaults to No */
97
settings->show_load=DEFAULT_SHOW_LOAD; /* Defaults to No */
98
settings->narrow_logo=DEFAULT_NARROW_LOGO; /* Defaults to No */
99
settings->pretty_output=DEFAULT_PRETTY_OUTPUT; /* Defaults to Yes */
100
set_pretty_printing(DEFAULT_PRETTY_OUTPUT);
101
settings->display_logo_only=0;
102
settings->display_sysinfo_only=0;
103
settings->display_usertext=0;
104
settings->custom_format=0;
105
settings->center_sysinfo=1;
106
settings->user_text[0]=0;
107
settings->format[0]=0;
110
/* Use ansi codes or spaces to shift the cursor to the right */
111
static void shift_right(int shift,int plain_ascii) {
115
if (shift<=0) return;
118
for(i=0;i<shift;i++) {
123
printf("\033[%iC",shift);
127
/* Prints a string, but stops at a newline or end of string */
128
static char *print_line(char *string) {
130
char *temp_st=string;
132
if (temp_st==NULL) return NULL;
134
while ((*temp_st!='\n') && (*temp_st!='\0')) {
138
if ((*temp_st)=='\n') {
145
/* print enough chars to center text of given size */
146
static void center(int size,int width,int plain_ascii) {
151
shift_right(i,plain_ascii);
156
/* Uses escape codes to clear the screen */
157
static void clear_screen(int plain_ascii) {
160
printf("\033[2J\033[0;0H\n");
163
/* clear the screen some other way? */
167
/* Change uptime seconds into time string */
168
static void strcat_uptime(int seconds,char *string, int space) {
170
int up_days,up_hrs,up_mins;
171
char temp_string[BUFSIZ],final_string[BUFSIZ];
173
up_days=seconds/86400;
174
up_hrs=(seconds-(up_days*86400))/3600;
175
up_mins=(seconds-(up_days*86400)-(up_hrs*3600))/60;
178
vmw_strcat(final_string,_("Uptime "),BUFSIZ);
181
snprintf(temp_string,BUFSIZ,"%d %s ",
182
up_days,(up_days==1 ? _("day"):_("days")));
183
vmw_strcat(final_string,temp_string,BUFSIZ-strlen(final_string));
187
snprintf(temp_string,BUFSIZ,"%d %s ",
188
up_hrs,(up_hrs==1 ? _("hour"):_("hours")));
189
vmw_strcat(final_string,temp_string,BUFSIZ-strlen(final_string));
192
snprintf(temp_string,BUFSIZ,"%d %s",
193
up_mins,(up_mins==1 ? _("minute"):_("minutes")));
194
vmw_strcat(final_string,temp_string,BUFSIZ-strlen(final_string));
196
vmw_strcat(string,final_string,space);
199
/* Prints the help */
200
static void help_message(char *binname, char full) {
202
char temp_version[BUFSIZ];
204
printf("\nLinux Logo Version %s using libsysinfo %s\n",VERSION,
205
get_sysinfo_version(temp_version));
206
printf("\tby Vince Weaver <vince@deater.net>\n");
207
printf(" Newest Versions at:\n");
208
printf(" http://www.deater.net/weave/vmwprod/linux_logo\n");
209
printf(" http://metalab.unc.edu/pub/Linux/logos/penguins\n\n");
211
printf("Usage: %s [-a] [-b] [-c] [-d] [-D file] [-e file] [-f] "
213
" [-h] [-i] [-k] [-l] [-n] [-o num] [-p] [-s] [-t str] "
215
" [-w Num] [-x] [-y] [-F format] "
216
"[-L num | NAME | list | random_xy]\n",binname);
217
printf(" [-a] -- Display an ascii-only Logo\n");
218
printf(" [-b] -- Display a Banner Logo!\n");
219
printf(" [-c] -- Display a \"Classic\" type logo\n");
220
printf(" [-d] -- disable \"prettying\" of output\n");
221
printf(" [-D file]-- use custom logo from \"file\"\n");
222
printf(" [-e file]-- Use \"file\" instead of /proc/cpuinfo [for "
224
printf(" [-f] -- force the screen clear before drawing\n");
225
printf(" [-F format] Format output. See README.\n");
226
printf(" B [-g] -- give system info only\n");
227
printf(" [-h] -- this help screen\n");
228
printf(" [-i] -- ignore ~/.linux_logo and /etc/linux_logo.conf\n");
229
printf(" [-k] -- keep sysinfo flushed-left (non-centered)\n");
230
printf(" B [-l] -- display logo only\n");
231
printf(" C [-o Num] -- offset output Num spaces to the right\n");
232
printf(" [-p] -- preserve cursor location\n");
233
printf(" [-s] -- skip Bogomips [speeds up on non-Linux "
235
printf(" [-t str] -- display user-supplied string\n");
236
printf(" * [-u] -- show uptime\n");
237
printf(" [-v] -- version information\n");
238
printf(" [-w Num] -- set width of screen to Num [default 80]\n");
239
printf(" * [-y] -- show load average\n");
240
printf(" [-L num | NAME | list | random_xy] -- multiple Logo options. See README\n\n");
241
printf(" B=Banner mode only, C=Classic Mode Only *=Works Only in Linux"
246
/* The nifty customizable sysinfo parser */
247
static int generate_sysinfo(
249
struct linux_logo_info_type *settings) {
251
struct os_info_type os_info;
252
struct cpu_info_type cpu_info;
255
char temp_string[BUFSIZ],hostname[BUFSIZ],domain[BUFSIZ];
256
char temp_line[BUFSIZ];
257
float load_1,load_5,load_15;
259
char char_string[2]={0,0};
260
int allocated_lines=10;
262
/* Get the system info */
263
get_os_info(&os_info);
264
get_cpu_info(&cpu_info);
266
len=strlen(settings->format);
268
/* allocate 10 lines to start with */
269
temp_sysinfo=calloc(allocated_lines,sizeof(char *));
273
/* clear out our line */
277
while (settings->format[x]!='\n') {
279
/* If not a #, then just print the character */
280
if (settings->format[x]!='#') {
281
char_string[0]=*((settings->format)+x);
282
vmw_strcat(temp_line,char_string,BUFSIZ-strlen(temp_line));
287
switch(settings->format[x]) {
288
/* double # just prints a # */
289
case '#': vmw_strcat(temp_line,"#",BUFSIZ-strlen(temp_line)); break;
290
/* #B prints the bogomips */
291
/* If really high, don't print fractional part */
292
case 'B': if (cpu_info.bogomips<10000.0) {
293
snprintf(temp_string,BUFSIZ,"%.2f",cpu_info.bogomips);
296
snprintf(temp_string,BUFSIZ,"%.0f",cpu_info.bogomips);
298
vmw_strcat(temp_line,temp_string,BUFSIZ-strlen(temp_line));
300
/* #C prints OS revision */
301
case 'C': vmw_strcat(temp_line,os_info.os_revision,
302
BUFSIZ-strlen(temp_line));
304
/* #E prints user text */
305
case 'E': vmw_strcat(temp_line,settings->user_text,
306
BUFSIZ-strlen(temp_line));
308
/* #H prints hostname */
309
case 'H': vmw_strcat(temp_line,get_host_name(hostname,domain),
310
BUFSIZ-strlen(temp_line));
312
/* #L prints load average */
313
case 'L': get_load_average(&load_1,&load_5,&load_15);
314
snprintf(temp_string,BUFSIZ,"%s %.2f, %.2f, %.2f",
315
_("Load Average"),load_1,load_5,load_15);
316
vmw_strcat(temp_line,temp_string,BUFSIZ-strlen(temp_line));
318
/* #M prints Megahertz */
319
case 'M': if (cpu_info.megahertz>0.0) {
320
if (cpu_info.megahertz>999.0) {
321
snprintf(temp_string,BUFSIZ,"%.3gGHz",
322
cpu_info.megahertz/1000.0);
325
snprintf(temp_string,BUFSIZ,"%.3gMHz",
328
vmw_strcat(temp_line,temp_string,
329
BUFSIZ-strlen(temp_line));
332
/* No megahertz. Back up the pointer. */
333
/* This is a hack to avoid extra spaces in the output */
334
if (strlen(temp_line)>0) {
335
temp_line[strlen(temp_line)-1]=0;
339
/* #N prints number of CPUs */
340
/* Spelled out if it is less than 10 */
341
/* The actual number if less than 100,000 */
342
/* The word "Many" if more than 100,000 */
343
case 'N': if (cpu_info.num_cpus<=9) {
344
strcat_ordinal(cpu_info.num_cpus,temp_line,
345
BUFSIZ-strlen(temp_line));
347
else if (cpu_info.num_cpus<=99999) {
348
snprintf(temp_string,BUFSIZ,"%d",cpu_info.num_cpus);
349
vmw_strcat(temp_line,temp_string,
350
BUFSIZ-strlen(temp_line));
353
strcat_ordinal(10,temp_line,
354
BUFSIZ-strlen(temp_line));
357
/* #O prints the OS name */
358
case 'O': vmw_strcat(temp_line,os_info.os_name,
359
BUFSIZ-strlen(temp_line));
361
/* #P prints "Processor" or its plural. Sort of a hack */
362
/* This probably doesn't work with all languages */
363
case 'P': if (cpu_info.num_cpus!=1) {
364
vmw_strcat(temp_line,_(PROCESSOR_PLURAL),
365
BUFSIZ-strlen(temp_line));
368
vmw_strcat(temp_line,_(PROCESSOR_SINGULAR),
369
BUFSIZ-strlen(temp_line));
372
/* #R prints the amount of memory */
373
case 'R': if (get_mem_size()>1023*1024) {
374
snprintf(temp_string,BUFSIZ,"%.2gTB",
375
((double)get_mem_size())/(1024.0*1024.0));
377
else if (get_mem_size()>1023) {
378
snprintf(temp_string,BUFSIZ,"%.2gGB",
379
((double)get_mem_size()/1024.0));
381
snprintf(temp_string,BUFSIZ,"%ldM",get_mem_size());
383
vmw_strcat(temp_line,temp_string,BUFSIZ-strlen(temp_line));
385
/* #S prints "s" if CPU's are more than 1. DEPRECATED */
386
case 'S': if (cpu_info.num_cpus!=1) {
387
vmw_strcat(temp_line,"s",BUFSIZ-strlen(temp_line));
390
/* #T prints the CPU type */
391
case 'T': vmw_strcat(temp_line,cpu_info.chip_type,
392
BUFSIZ-strlen(temp_line));
394
/* #U prints the uptime */
395
case 'U': strcat_uptime(get_uptime(),temp_line,
396
BUFSIZ-strlen(temp_line));
398
/* #V prints the OS version */
399
case 'V': vmw_strcat(temp_line,os_info.os_version,
400
BUFSIZ-strlen(temp_line));
402
/* #X Prints the CPU vendor */
403
case 'X': if (!strncmp(cpu_info.chip_vendor,"Unknown",7)) {
404
if (strlen(temp_line)>0) {
405
temp_line[strlen(temp_line)-1]=0;
409
vmw_strcat(temp_line,cpu_info.chip_vendor,
410
BUFSIZ-strlen(temp_line));
413
default: fprintf(stderr,"\nInvalid format '#%c'\n",
414
settings->format[x]);
420
temp_sysinfo[line]=strdup(temp_line);
423
/* If we are using more than the pre-allocated amount */
424
/* allocate more lines */
425
if (line>=allocated_lines) {
426
temp_sysinfo=realloc(temp_sysinfo,sizeof(char *)*(line+1));
427
allocated_lines=line;
430
/* skip the newline */
433
*string=temp_sysinfo;
438
/* The Main Drawing Routine */
439
static void draw_logo(struct logo_info *logo_override,
440
struct linux_logo_info_type *settings) {
442
struct logo_info *our_logo_info;
444
int i,ysize,sysinfo_length=0;
445
char **sysinfo_string;
447
sysinfo_length=generate_sysinfo(&sysinfo_string,settings);
449
if (logo_info_head==NULL) {
450
printf("\n\nNo logos available!!\n");
454
if (logo_override!=NULL) {
455
our_logo_info=logo_override;
457
else { /* Search for a proper logo! */
458
our_logo_info=logo_info_head;
460
if (our_logo_info==NULL) {
461
printf("\nAppropriate logo not found!\n\n");
464
if ((settings->banner_mode) &&
465
(our_logo_info->sysinfo_position==SYSINFO_BOTTOM)) {
466
if (settings->plain_ascii) {
467
if (our_logo_info->ascii_logo!=NULL) {
471
else { /* Not ascii */
472
if (our_logo_info->logo!=NULL) {
477
if ((!settings->banner_mode) &&
478
(our_logo_info->sysinfo_position==SYSINFO_RIGHT)) { /* Classic mode */
479
if (settings->plain_ascii) {
480
if (our_logo_info->ascii_logo!=NULL) {
483
} else { /* Not ascii */
484
if (our_logo_info->logo!=NULL) {
489
our_logo_info=our_logo_info->next_logo;
493
if (settings->width<80) settings->width=80; /* Right now we don't */
494
/* handle width < 80 */
496
if (settings->wipe_screen) clear_screen(settings->plain_ascii);
498
/* Select the proper logo */
499
if (settings->plain_ascii) {
500
ysize=our_logo_info->ascii_ysize;
501
if (our_logo_info->ascii_logo==NULL) {
502
printf("\nSpecified logo has no ascii version!\n\n");
505
else string_point=our_logo_info->ascii_logo;
508
ysize=our_logo_info->ysize;
509
if (our_logo_info->logo==NULL) {
510
printf("\nSpecified logo has no non-ascii version!\n\n");
513
else string_point=our_logo_info->logo;
517
if (!settings->display_sysinfo_only) {
518
if (settings->banner_mode) { /* Banner mode */
519
for(i=0;i<ysize;i++) {
520
shift_right((settings->width-80)/2,settings->plain_ascii);
521
string_point=print_line(string_point);
524
if (!settings->display_logo_only) printf("\n");
526
else { /* Classic mode logo */
528
/* Print the first 7 lines of logo */
531
printf("\nError! Classic logos must be at least 7 lines long!\n");
534
if (!settings->plain_ascii) printf("\033[40m\033[40m\n");
537
shift_right(settings->offset,settings->plain_ascii);
538
string_point=print_line(string_point);
542
/* The next lines can have cpuinfo after them */
543
for(i=7;i<ysize;i++) {
544
shift_right(settings->offset,settings->plain_ascii);
545
string_point=print_line(string_point);
546
shift_right(2,settings->plain_ascii);
547
if (i-7<sysinfo_length) {
548
if (!settings->plain_ascii) printf("\033[1;37;40m");
549
printf("%s",sysinfo_string[i-7]);
550
if (!settings->plain_ascii) printf("\033[0m");
557
/* Print the sysinfo if we haven't already */
558
if (!settings->display_logo_only) {
559
if (settings->banner_mode) {
560
for(i=0;i<sysinfo_length;i++) {
562
if (settings->center_sysinfo) {
563
center(strlen(sysinfo_string[i]),settings->width,
564
settings->plain_ascii);
567
if (!settings->plain_ascii) printf("\033[1;37;40m");
568
printf("%s",sysinfo_string[i]);
569
if (!settings->plain_ascii) printf("\033[0m");
576
/* Restore cursor color to normal */
577
if (!settings->plain_ascii) {
578
printf("\033[0m\033[255D");
583
static char *get_arg(int *index,int argc,char **argv) {
587
if (argv[*index][2]=='\0') {
591
printf("Missing parameter to option -%c\n\n",argv[(*index)-1][1]);
595
argument=argv[*index];
599
argument=&(argv[*index][2]);
606
/**************************/
607
/* logo support functions */
608
/**************************/
611
/* global variables, a bit of a hack, should find a better way */
612
int logo_num=0,logo_override=0,random_logo=0,want_list_logos=0;
613
char random_type='e',random_type2='e',*logo_name=NULL,*logo_disk=NULL;
616
/* Find a logo by name */
617
static struct logo_info *get_logo_by_name(char *logo_name) {
619
static struct logo_info *custom_logo;
621
custom_logo=logo_info_head;
622
while(custom_logo!=NULL) {
624
if (!strcmp(custom_logo->name,logo_name)) {
627
custom_logo=custom_logo->next_logo;
629
fprintf(stderr,"Error! No logo with the name %s is available!\n",logo_name);
633
/* Find a logo by number */
634
static struct logo_info *get_logo_by_number(int logo_num) {
637
static struct logo_info *custom_logo;
639
custom_logo=logo_info_head;
642
if (custom_logo->next_logo==NULL) {
643
fprintf(stderr,"\nError! Logo %d is invalid! \"linux_logo -L list\""
644
" lists valid logo numbers.\n\n",logo_num);
645
custom_logo=logo_info_head;
648
custom_logo=custom_logo->next_logo;
654
/* find a random logo */
655
static struct logo_info *get_random_logo(int random_type, int random_type2,
656
struct linux_logo_info_type *settings) {
658
struct timeval time_time;
660
static struct logo_info *custom_logo;
662
gettimeofday(&time_time,NULL);
663
srand(time_time.tv_usec); /* Not really random, but... */
664
i=rand()%1024; /* Hopefully we have less than 1024 logos FIXME */
666
custom_logo=logo_info_head;
668
if (custom_logo->next_logo==NULL) custom_logo=logo_info_head;
669
else custom_logo=custom_logo->next_logo;
676
if (random_type=='b') { /* Want banner mode */
677
if (!custom_logo->sysinfo_position) logo_found=0;
678
else settings->banner_mode=1;
680
if (random_type=='c') { /* Want classic mode */
681
if (custom_logo->sysinfo_position) logo_found=0;
682
else settings->banner_mode=0;
684
if (random_type=='e') { /* Want either */
685
/* we should be OK */
688
if (random_type2=='e') { /* Any logo at all */
689
settings->plain_ascii=rand()%2;
690
if (custom_logo->ascii_logo==NULL) {
691
settings->plain_ascii=!settings->plain_ascii;
694
if (random_type2=='a') { /* Want Ascii */
695
if (custom_logo->ascii_logo==NULL) logo_found=0;
696
else settings->plain_ascii=1;
699
if (random_type2=='n') { /* Want non-ascii */
700
if (custom_logo->logo==NULL) logo_found=0;
701
else settings->plain_ascii=0;
705
if (logo_found) break;
707
if (custom_logo->next_logo==NULL) {
708
custom_logo=logo_info_head;
711
else custom_logo=custom_logo->next_logo;
714
printf("\nSorry, can't generate random logo of that type.\n\n");
721
static void list_logos() {
724
struct logo_info *temp_logo;
726
printf("\nAvailable Built-in Logos:\n");
727
printf("\tNum\tType\tAscii\tName\t\tDescription\n");
729
temp_logo=logo_info_head;
731
while (temp_logo!=NULL) {
733
if (temp_logo->sysinfo_position) printf("\tBanner");
734
else printf("\tClassic");
735
if (temp_logo->ascii_logo!=NULL) printf("\tYes");
737
printf("\t%s",temp_logo->name);
738
if (strlen(temp_logo->name)<8) printf("\t");
739
printf("\t%s\n",temp_logo->description);
740
temp_logo=temp_logo->next_logo;
743
printf("\nDo \"linux_logo -L num\" where num is from "
744
"above to get the appropriate logo.\n");
745
printf("Remember to also use -a to get ascii version.\n\n");
750
/*******************************************************/
751
/* Parse options (from file or command line arguments) */
752
/*******************************************************/
753
static void parse_command_line(struct linux_logo_info_type *settings,
754
int argc, char **argv) {
757
char *endptr,*argument;
765
if (argv[index][0]!='-') {
766
printf("Unknown parameter %s\n",argv[index]);
769
option=argv[index][1];
772
case 'a': settings->plain_ascii=1;
774
case 'b': settings->banner_mode=1;
776
case 'c': settings->banner_mode=0;
778
case 'd': settings->pretty_output=0;
779
set_pretty_printing(0);
781
case 'D': argument=get_arg(&index,argc,argv);
782
logo_disk=strdup(argument);
784
case 'e': argument=get_arg(&index,argc,argv);
785
set_cpuinfo_file(argument);
787
case 'f': settings->wipe_screen=1;
789
case 'F': argument=get_arg(&index,argc,argv);
790
string_size=strlen(argument);
791
if (string_size==0) break;
793
settings->custom_format=1;
794
strncpy(settings->format,argument,BUFSIZ);
796
/* Decode the \n's. */
797
/* Should I decode other \ codes? */
798
/* also, \ codes are always smaller, hence why */
799
/* we can overwrite our own buffer */
802
while(i<strlen(settings->format)) {
803
if (settings->format[i]=='\\') {
804
switch(settings->format[i+1]) {
805
case 'n': settings->format[x]='\n'; i++; break;
806
default: settings->format[x]='\\'; break;
810
settings->format[x]=settings->format[i];
814
settings->format[x]='\0';
816
case 'g': settings->display_sysinfo_only=1;
819
case '?': help_message(argv[0], 1);
823
case 'i': /* is it even possible to do this right? */
824
/* we'd have to do two passes, possibly */
825
/* resetting to defaults in between */
826
/*ignore_config_file=1; */
828
case 'k': settings->center_sysinfo=0;
830
case 'l': settings->display_logo_only=1;
832
case 'L': argument=get_arg(&index,argc,argv);
833
/* Reset values in case we get this after reading the file */
834
logo_num = 1; logo_override = 0; random_logo = 0;
835
logo_num=strtol(argument,&endptr,10);
836
if ( endptr == argument ) {
837
/* we leak temp_st, need to fix */
838
temp_st=strdup(argument);
839
if (!strncmp(temp_st,"list",4)) {
842
else if (!strncmp(temp_st,"random",6)) {
844
random_type=temp_st[7];
845
random_type2=temp_st[8];
848
logo_name=strdup(temp_st);
851
else { /* It's a number */
856
case 'n': settings->no_periods=1;
858
case 'o': argument=get_arg(&index,argc,argv);
859
settings->offset=strtol(argument,&endptr,10);
860
if ( endptr == argument ) {
861
printf("Invalid offset length %s\n\n",argument);
865
case 'p': settings->preserve_xy=1;
867
case 's': settings->skip_bogomips=1;
869
case 't': argument=get_arg(&index,argc,argv);
870
settings->display_usertext=1;
871
strncpy(settings->user_text,argument,BUFSIZ);
873
case 'u': settings->show_uptime=1;
875
case 'v': help_message(argv[0], 0);
878
case 'w': argument=get_arg(&index,argc,argv);
879
settings->width=strtol(argument,&endptr,10);
880
if ( endptr == argument ) {
881
printf("Invalid width %s\n\n",argument);
885
case 'y': settings->show_load=1;
887
default: printf("Unknown option -%c\n",option);
892
if (index>=argc) break;
897
/* Look for ~/.linux_logo or /etc/linux_logo config files */
898
void read_config_file(struct linux_logo_info_type *settings) {
900
int string_size,valid_string=0,i,size=0,counter=0;
901
int fake_data_offset=0,ch,oldch,in_quote=0,fake_argc=0;
902
char *tempst,*fake_data,**fake_argv;
903
FILE *config_file=NULL;
904
char config_string[BUFSIZ];
905
char config_filename[]="/.linux_logo";
907
/* Check for the files */
909
/* look for ~/.linux_logo */
910
if (getenv("HOME")) {
911
string_size=strlen(getenv("HOME"));
912
tempst=calloc(strlen(config_filename)+string_size+1,sizeof(char));
913
strncpy(tempst,getenv("HOME"),string_size);
914
strncat(tempst,config_filename,strlen(config_filename));
915
config_file=fopen(tempst,"r");
916
free(tempst); /* free the calloc's! */
919
/* if no ~/.linux_logo, check for /etc/linux_logo.conf */
920
if (config_file==NULL) {
921
config_file=fopen("/etc/linux_logo.conf","r");
924
/* If no config files, just make do with command-line arguments */
925
/* Note to Vince of 2000.. this was the most horrible */
926
/* atrocity of code ever. -- Vince of 2006 */
927
/* It should be a lot better now. -- Vince of 2007 */
929
if (config_file!=NULL) {
931
/* skip over whitespace and comments */
932
while(!valid_string) {
933
fgets(config_string,BUFSIZ,config_file);
934
for(i=0;i<strlen(config_string);i++) {
935
if (config_string[i]=='#') break; /* a comment */
936
else if (config_string[i]=='\n') break; /* empty line */
937
else if (config_string[i]==' ' || config_string[i]=='\t'); /* whitespace */
943
if (feof(config_file)) break;
948
size=strlen(config_string);
950
config_string[size-1]='\0'; /* get rid of trailing \n */
952
/* create room for the fake command-line */
953
fake_data=calloc(size+12,sizeof(char));
954
/* stick "linux_logo" as argv[0] */
955
strncpy(fake_data,"linux_logo ",11);
957
vmw_strcat(fake_data,config_string,size);
960
for(i=0;i<size;i++) {
963
ch=config_string[i]; /* start after linux_logo */
965
/* if after a space, and not in a quote, begin a new token */
966
if ((oldch==' ') && (!in_quote) && (ch!=' ')) {
967
if (fake_data_offset>0) fake_data[fake_data_offset]='\0';
972
/* The shell strips quotes and excess whitespace */
973
/* thought for now we just strip spaces outside of quotations */
974
if ((ch!='\"') && ((ch!=' ') || ((ch==' ') && (in_quote)))) {
975
fake_data[fake_data_offset]=ch;
979
/* start/end a quotation */
980
if (ch=='\"') in_quote= !in_quote;
986
fake_argc+=1; /* plus the last one */
988
/* Allocate room for the fake argv[] list of pointers */
989
/* +1 cause NULL at the end */
990
fake_argv=calloc(fake_argc+1,sizeof(char *));
992
fake_argv[0]=fake_data;
994
/* Actually find the tokens based on the NULLs put before */
995
for(i=0;i<fake_data_offset;i++) {
996
if (fake_data[i]=='\0') {
997
if (counter<fake_argc) {
998
fake_argv[counter]=fake_data+i+1;
1004
parse_command_line(settings,fake_argc,fake_argv);
1010
/* The main program */
1011
int main(int argc,char **argv) {
1013
char temp_string[BUFSIZ],*temp_pointer;
1014
struct linux_logo_info_type settings;
1015
struct logo_info *custom_logo=NULL;
1019
setlocale(LC_ALL, "");
1020
bindtextdomain("linux_logo", LOCALE_DIR);
1021
textdomain("linux_logo");
1023
/* Set some defaults */
1024
setup_info(&settings);
1026
read_config_file(&settings);
1028
parse_command_line(&settings,argc,argv);
1030
/*******************************************************/
1031
/* DONE WITH ALL THE STUPID OPTION PARSING */
1032
/* now actually do things */
1033
/*******************************************************/
1035
/* Setup all the logos */
1036
setup_default_logos();
1038
/* If user requested a list, list them and exit */
1039
if (want_list_logos) list_logos();
1041
/* If user requested random logo, get one */
1042
if (random_logo) custom_logo=get_random_logo(random_type,random_type2,&settings);
1044
/* If user requested logo by number, get it */
1045
if (logo_num!=0) custom_logo=get_logo_by_number(logo_num);
1047
/* If user requested logo by name, get it */
1048
if (logo_name!=NULL) custom_logo=get_logo_by_name(logo_name);
1050
/* If user wants a logo from disk, get it */
1051
if (logo_disk!=NULL) custom_logo=load_logo_from_disk(logo_disk);
1053
/* We have to keep these consistent or funny things happen */
1054
if (custom_logo!=NULL) settings.banner_mode=custom_logo->sysinfo_position;
1056
/**************************************************/
1057
/* Prepare the sysinfo stuff if not done for us */
1058
/* Handle "normal" output by basically faking the */
1059
/* appropriate "custom" output string */
1060
/**************************************************/
1062
if (!settings.custom_format) {
1064
/* Set the format for banner or classic mode */
1065
if (settings.banner_mode) {
1066
strncpy(settings.format,_(DEFAULT_BANNER_FORMAT),BUFSIZ);
1069
strncpy(settings.format,DEFAULT_CLASSIC_FORMAT,BUFSIZ);
1072
/* If usertext specified, add it at beginning */
1073
if (settings.display_usertext) {
1074
strncpy(temp_string,settings.format,BUFSIZ);
1075
strncpy(settings.format,"#E\n",BUFSIZ);
1076
vmw_strcat(settings.format,temp_string,BUFSIZ-strlen(settings.format));
1079
/* If want system load, add it second-to-last */
1080
if (settings.show_load) {
1082
/* put it before the hostname */
1083
temp_pointer=strstr(settings.format,"#H");
1084
/* If for some reason not found, put it at end */
1085
if (temp_pointer==NULL) {
1086
vmw_strcat(settings.format,"#L\n",BUFSIZ-strlen(settings.format));
1089
if (strlen(settings.format)+3<BUFSIZ) {
1090
strcpy(temp_pointer,"#L\n#H\n");
1095
/* if want uptime, add it second_to_last */
1096
if (settings.show_uptime) {
1098
/* put it before the hostname */
1099
temp_pointer=strstr(settings.format,"#H");
1100
/* If for some reason not found, put it at end */
1101
if (temp_pointer==NULL) {
1102
vmw_strcat(settings.format,"#U\n",BUFSIZ-strlen(settings.format));
1105
if (strlen(settings.format)+3<BUFSIZ) {
1106
strcpy(temp_pointer,"#U\n#H\n");
1112
/* Preserve xy if so desired */
1113
if ( (settings.preserve_xy) && (!settings.plain_ascii) ) {
1118
draw_logo(custom_logo,&settings);
1120
/* Restore xy if we saved it */
1121
if ( (settings.preserve_xy) && (!settings.plain_ascii) ) {