~ubuntu-branches/ubuntu/trusty/linuxlogo/trusty

« back to all changes in this revision

Viewing changes to linux_logo.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2008-06-20 09:19:00 UTC
  • mfrom: (4.1.2 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080620091900-4xzuv7c7ntxvs7wt
Tags: 5.03-4
* Adding patch to fix FTBFS on s390x.
* Updating to standards 3.8.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*-------------------------------------------------------------------------*\
2
 
  LINUX LOGO 4.14 - Creates Nifty Logo With System Info - 20 July 2006
3
 
 
4
 
    by Vince Weaver (vince@deater.net, http://www.deater.net/weave )
5
 
                     
6
 
  A program to display text/ansi logos with system information.
7
 
 
8
 
  Thanks to many, many people who sent patches in.  See the CHANGES file for
9
 
     a list of all those who helped out.
10
 
 
11
 
\*-------------------------------------------------------------------------*/
12
 
 
13
 
#include <stdio.h>
14
 
#include <stdlib.h>
15
 
#include <ctype.h>
16
 
#include <unistd.h>
17
 
#include <string.h>
18
 
#include <sys/utsname.h>
19
 
#include <sys/time.h>
20
 
#include <locale.h>
21
 
 
22
 
#include "i18n.h"
23
 
 
24
 
#define ESCAPE '\033'
25
 
#define VERSION "4.14"
26
 
 
27
 
#include "sysinfo.h"
28
 
#include "linux_logo.h"
29
 
#include "logo_types.h"
30
 
#include "vmw_string.h"
31
 
 
32
 
/* Change the values in the below file to alter default behavior */
33
 
#include "defaults.h"
34
 
 
35
 
    /* See defaults.h when setting this */
36
 
#if (USE_I18N==0)
37
 
#undef _
38
 
#define _(string) string
39
 
#endif
40
 
 
41
 
 
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;}
44
 
 
45
 
#define FILE_OPTIONS_PASS          0
46
 
#define COMMAND_OPTIONS_PASS       1
47
 
#define WANT_DEFAULT_OPTIONS_PASS  2
48
 
 
49
 
char *ordinal(int value) {
50
 
   static char text[20];
51
 
   
52
 
   switch(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;
64
 
      
65
 
   }
66
 
   return text;
67
 
}
68
 
 
69
 
 
70
 
/* Some global variables.  Possibly bad in practice, but it saves a lot *\
71
 
\* of paramater passing, which has caused bugs to develop before.       */
72
 
 
73
 
struct logo_info    *logo_info_head = NULL;
74
 
struct logo_info    *logo_info_tail = NULL;
75
 
 
76
 
void draw_banner_logo(struct logo_info *the_logo, struct linux_logo_info_type *settings);
77
 
 
78
 
struct logo_info *load_logo_from_disk(char *filename) {
79
 
 
80
 
   struct logo_info *new_logo;
81
 
   int logo_start=0,ascii_logo_start=0;
82
 
   int ascii_size=0,size=0;
83
 
   char temp_st[BUFSIZ];
84
 
   FILE *fff;
85
 
      
86
 
   new_logo=calloc(1,sizeof(struct logo_info));
87
 
 
88
 
   if (new_logo==NULL) {
89
 
      printf("Error allocating memory!\n");
90
 
      return NULL;
91
 
   }
92
 
        
93
 
   fff=fopen(filename,"r");
94
 
   if (fff==NULL) {
95
 
      printf("Error loading logo: %s\n",filename);
96
 
      return NULL;
97
 
   }
98
 
   
99
 
   new_logo->logo=NULL;
100
 
   new_logo->ascii_logo=NULL;
101
 
   
102
 
   while (!feof(fff)) {
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;
106
 
      if (logo_start) {
107
 
         size+=strlen(temp_st);
108
 
         if (new_logo->logo==NULL) {
109
 
            new_logo->logo=strdup(temp_st);
110
 
         }
111
 
         else {
112
 
            new_logo->logo=realloc(new_logo->logo,size+1);
113
 
            strncat( new_logo->logo,temp_st,strlen(temp_st));
114
 
         }
115
 
         new_logo->ysize++;
116
 
      }
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);
121
 
         }
122
 
         else {
123
 
            new_logo->ascii_logo=realloc(new_logo->ascii_logo,ascii_size+1);
124
 
            strncat( new_logo->ascii_logo,temp_st,strlen(temp_st));
125
 
         }
126
 
         new_logo->ascii_ysize++;
127
 
      }
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;
134
 
            }
135
 
            if (!strncmp(temp_st+17,"right",5)) {
136
 
               new_logo->sysinfo_position=SYSINFO_RIGHT;
137
 
            }
138
 
         }
139
 
         if (!strncmp(temp_st,"DESCRIPTION_STRING",18)) {
140
 
            new_logo->description=strdup(temp_st+19);      
141
 
         }
142
 
      }
143
 
   }
144
 
   
145
 
   new_logo->next_logo=NULL;
146
 
   
147
 
   logo_info_tail=new_logo;
148
 
 
149
 
   fclose(fff);
150
 
   
151
 
   return new_logo;   
152
 
}
153
 
 
154
 
void free_logos() {
155
 
    struct logo_info *logo;
156
 
    struct logo_info *prev_logo;
157
 
   
158
 
    logo=logo_info_head;
159
 
   
160
 
    while(logo!=NULL) {
161
 
       if (logo->description) free(logo->description);
162
 
       if (logo->logo) free(logo->logo);
163
 
       if (logo->ascii_logo) free(logo->ascii_logo);
164
 
       prev_logo=logo;
165
 
       logo=logo->next_logo;
166
 
       free(prev_logo);
167
 
    }
168
 
    logo_info_head=NULL;
169
 
    logo_info_tail=NULL;
170
 
}
171
 
 
172
 
 
173
 
void setup_logos() {
174
 
 
175
 
   struct logo_info *new_logo;
176
 
   
177
 
#include "load_logos.h"
178
 
   
179
 
//   logo_info_head=load_logo_from_disk("./logos/banner.logo");   
180
 
//   logo_info_tail->next_logo=load_logo_from_disk("./logos/classic.logo");
181
 
   
182
 
}
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) {
186
 
    
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;
208
 
}
209
 
 
210
 
    /* Use ansi codes or spaces to shift the cursor to the right */
211
 
void shift_right(int shift,int plain_ascii)
212
 
{
213
 
    int i;
214
 
   
215
 
    if (shift<=0) return; 
216
 
   
217
 
    if (plain_ascii) for(i=0;i<shift;i++) putchar(' ');
218
 
    else printf("%c[%iC",ESCAPE,shift);
219
 
}
220
 
 
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)
226
 
{
227
 
    int i;
228
 
   
229
 
    i=0;
230
 
    while(1) {
231
 
       switch(string[i]){
232
 
          case '\0': return 0;
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]);
236
 
       }
237
 
       i++;
238
 
    } 
239
 
    return 0;
240
 
}
241
 
 
242
 
 
243
 
 
244
 
char *print_line(char *string)
245
 
{
246
 
 
247
 
    char *temp_st=string;
248
 
 
249
 
    while ((*temp_st!='\n') && (*temp_st!='\0')) {
250
 
       putchar(*temp_st);
251
 
       temp_st++;
252
 
    }
253
 
    if ((*temp_st)=='\n') {
254
 
       return temp_st+1;
255
 
    }
256
 
    else return NULL;
257
 
}
258
 
 
259
 
 
260
 
    /* print some centered text */
261
 
void center_and_print(char *string,int size,int width,
262
 
                      struct linux_logo_info_type *settings)
263
 
{
264
 
   int i;
265
 
 
266
 
   if (settings->center_sysinfo) {
267
 
      i=((width-size)/2);
268
 
      shift_right(i,settings->plain_ascii);
269
 
   }
270
 
   
271
 
      /* Why was I setting the colors here? */
272
 
   if (!settings->plain_ascii) ansi_print("^[[1;37;40m");
273
 
   printf("%s",string);
274
 
   if (!settings->plain_ascii) ansi_print("^[[0m");
275
 
   printf("\n");
276
 
}
277
 
 
278
 
    /* Uses escape codes to clear the screen */
279
 
void clear_screen(struct linux_logo_info_type *settings)
280
 
{
281
 
   if (!settings->plain_ascii) ansi_print("^[[2J^[[0;0H\n");  
282
 
}
283
 
 
284
 
    /* Change uptime seconds into time string */
285
 
char *uptime_string(int seconds) {
286
 
   
287
 
    int up_days,up_hrs,up_mins;
288
 
    char temp_string[BUFSIZ];
289
 
   
290
 
    up_days=seconds/86400;
291
 
    up_hrs=(seconds-(up_days*86400))/3600;
292
 
    up_mins=(seconds-(up_days*86400)-(up_hrs*3600))/60;
293
 
  
294
 
    if (up_days<=0) 
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"));
298
 
    else 
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);
304
 
}
305
 
 
306
 
    /* Prints the help */
307
 
void help_message(char *binname, char full)
308
 
{
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");
316
 
    if (!full) exit(0);
317
 
    printf("Usage:   %s [-a] [-b] [-c] [-d] [-D file] [-e file] [-f] "
318
 
           "[-g]\n"
319
 
           "                    [-h] [-i] [-k] [-l] [-n] [-o num] [-p] [-s] [-t str] "
320
 
           "[-u] [-v]\n"
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 "
329
 
           "debugging]\n");
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 "
340
 
           "platforms]\n");
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"
348
 
           "\n\n");
349
 
}
350
 
 
351
 
    /* The nifty customizable sysinfo parser */
352
 
int print_sysinfo(int line, char *string,
353
 
                  struct linux_logo_info_type *settings) {
354
 
   
355
 
    static os_info_t os_info;
356
 
    static cpu_info_t cpu_info;
357
 
   
358
 
    static int sysinfo_already_run=0; 
359
 
   
360
 
    int x=0,y=0,len;
361
 
    int string_ptr;
362
 
    char temp_string[255],hostname[65],domain[65];
363
 
    float load_1,load_5,load_15;
364
 
   
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;
370
 
    }
371
 
       
372
 
    len=strlen(settings->format);
373
 
   
374
 
    string_ptr=0;
375
 
    string[string_ptr]='\000';
376
 
 
377
 
    while (y<line) {
378
 
        if (settings->format[x]=='\n') y++;
379
 
        x++;
380
 
        if (x>len) return 1;
381
 
    }
382
 
    
383
 
    while (settings->format[x]!='\n') {
384
 
       if (settings->format[x]!='#') {
385
 
          string[string_ptr]=settings->format[x];
386
 
          string_ptr++;
387
 
       }
388
 
       else {
389
 
          string[string_ptr]='\000';
390
 
          x++;
391
 
          if (x>len) break;       
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);
396
 
                     }
397
 
                     else {
398
 
                        sprintf(temp_string,"%.0f",cpu_info.bogomips);
399
 
                     }
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); 
407
 
                     break;
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);
411
 
                        }
412
 
                        else {
413
 
                            sprintf(temp_string,"%.3gMHz",cpu_info.megahertz);
414
 
                        }
415
 
                        string_ptr+=vmw_strcat(string,temp_string); 
416
 
                     }
417
 
                     else {
418
 
                        /* No megahertz.  Back up the pointer.  This is a hack */
419
 
                        if (string_ptr>0) string_ptr--;
420
 
                     }
421
 
                     break;
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);
427
 
                     }
428
 
                     else string_ptr+=vmw_strcat(string,ordinal(10));
429
 
                     break;
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));
434
 
                     break;
435
 
           case 'R': if (get_mem_size()>1000000) {
436
 
                        sprintf(temp_string,"%.2gTB",
437
 
                                ((float)get_mem_size())/(1024.0*1024.0));
438
 
                     } 
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); 
444
 
                     break;
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())); 
449
 
                     break;
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--;
453
 
                     }
454
 
                     else {
455
 
                        string_ptr+=vmw_strcat(string,cpu_info.chip_vendor); 
456
 
                     }
457
 
                     break;
458
 
           default: printf("\nInvalid format '#%c'\n",settings->format[x]);
459
 
          }
460
 
       }
461
 
       x++;
462
 
       if (x>len) break;
463
 
    }
464
 
   
465
 
    string[string_ptr]='\000';
466
 
    return 0;
467
 
}
468
 
 
469
 
    /* The Main Drawing Routine */
470
 
void draw_logo(struct logo_info *logo_override,
471
 
               struct linux_logo_info_type *settings)
472
 
{
473
 
    struct logo_info *our_logo_info;
474
 
    char temp_string[BUFSIZ];
475
 
    char *string_point;
476
 
    int i,ysize;
477
 
   
478
 
    if (logo_info_head==NULL) {    
479
 
       printf("\n\nNo logos available!!\n");
480
 
       return;
481
 
    }
482
 
   
483
 
    if (logo_override!=NULL) {
484
 
       our_logo_info=logo_override;
485
 
    }
486
 
   
487
 
    else { /* Search for a proper logo! */
488
 
   
489
 
       our_logo_info=logo_info_head;
490
 
       while (1) {
491
 
          if (our_logo_info==NULL) {
492
 
             printf("\nAppropriate logo not found!\n\n");
493
 
             return;
494
 
          }
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) {
498
 
                   break;
499
 
                }
500
 
             }
501
 
             else { /* Not ascii */
502
 
                if (our_logo_info->logo!=NULL) {
503
 
                   break;
504
 
                }
505
 
             }
506
 
          }
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) {
510
 
                   break;
511
 
                }
512
 
             } else { /* Not ascii */
513
 
               if (our_logo_info->logo!=NULL) {
514
 
                  break;
515
 
               }
516
 
             }
517
 
          }
518
 
          our_logo_info=our_logo_info->next_logo;
519
 
       }
520
 
    }
521
 
   
522
 
    if (settings->width<80) settings->width=80;  /* Right now we don't */
523
 
                                                 /* handle width < 80  */
524
 
 
525
 
    if (settings->wipe_screen) clear_screen(settings);
526
 
  
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");
532
 
          return;
533
 
       }
534
 
       else string_point=our_logo_info->ascii_logo;
535
 
    }
536
 
    else {
537
 
       ysize=our_logo_info->ysize;
538
 
       if (our_logo_info->logo==NULL) {
539
 
          printf("\nSpecified logo has no non-ascii version!\n\n");
540
 
          return;
541
 
       }
542
 
       else string_point=our_logo_info->logo;
543
 
    }
544
 
   
545
 
       /* Draw the logos */
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);
551
 
             printf("\n");
552
 
          }
553
 
          if (!settings->display_logo_only) printf("\n");
554
 
       }
555
 
       else {  /* Classic mode logo */
556
 
       
557
 
             /* Print the first 7 lines of logo */
558
 
          
559
 
          if (ysize<7) {
560
 
             printf("\nError! Classic logos must be at least 7 lines long!\n");
561
 
          }
562
 
          
563
 
          if (!settings->plain_ascii) ansi_print("^[[40m^[[40m\n");
564
 
  
565
 
          for(i=0;i<7;i++) {
566
 
             shift_right(settings->offset,settings->plain_ascii);
567
 
             string_point=print_line(string_point);
568
 
             printf("\n"); 
569
 
          }
570
 
 
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");
580
 
             }
581
 
             printf("\n");
582
 
          }
583
 
       }
584
 
    }
585
 
      
586
 
       /* Print the sysinfo if we haven't already */
587
 
    if (!settings->display_logo_only) {
588
 
       if (settings->banner_mode) {
589
 
          i=0;
590
 
          while (print_sysinfo(i,temp_string,settings)!=1) {
591
 
             center_and_print(temp_string,strlen(temp_string),settings->width,
592
 
                           settings);
593
 
             i++;
594
 
          }
595
 
       }
596
 
    }
597
 
     
598
 
       /* Restore cursor color to normal */
599
 
    if (!settings->plain_ascii) 
600
 
       ansi_print("^[[0m^[[255D");
601
 
}
602
 
 
603
 
 
604
 
int main(int argc,char **argv)
605
 
{
606
 
    char *endptr,*temp_st;
607
 
    int c,i,x,logo_num=1,random_logo=0,do_listing=0,logo_override=0;
608
 
    int logo_found;
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;
614
 
    char *fake_data;
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;
622
 
    char *tempst;
623
 
    char config_string[BUFSIZ];
624
 
    int valid_string=0;
625
 
   
626
 
#ifndef __FreeBSD__  
627
 
       /* i18n */
628
 
    setlocale(LC_ALL, "");
629
 
    textdomain("linux_logo");
630
 
    bindtextdomain("linux_logo", "/usr/lib/locale");
631
 
#endif   
632
 
       /* Set some defaults */
633
 
    setup_info(&settings); 
634
 
    
635
 
       /* ****************************************************** */
636
 
       /* Look for ~/.linux_logo or /etc/linux_logo config files */
637
 
       /* ****************************************************** */
638
 
   
639
 
       /* Check for the files */
640
 
   
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! */
649
 
    }
650
 
 
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");
654
 
    }
655
 
   
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              */
659
 
   
660
 
    if (config_file==NULL) {
661
 
       read_from_file=0;
662
 
    } 
663
 
    else {
664
 
 
665
 
       
666
 
          /* Create "fake" argc and argv */
667
 
       read_from_file=1;
668
 
       
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 */
675
 
             else {
676
 
                valid_string=1;
677
 
                break;
678
 
             }
679
 
          }
680
 
          if (feof(config_file)) break;
681
 
       }
682
 
       
683
 
       
684
 
       if (valid_string) {
685
 
          file_size=strlen(config_string);
686
 
 
687
 
 
688
 
          config_string[file_size-1]='\0';  /* get rid of trailing \n */
689
 
 
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);
694
 
          fake_data_offset=11;
695
 
          strncat(fake_data,config_string,file_size);
696
 
                  
697
 
          ch=' ';
698
 
          for(i=0;i<file_size;i++) {
699
 
             
700
 
             oldch=ch;
701
 
             ch=config_string[i]; /* start after linux_logo */
702
 
             
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';
706
 
                fake_data_offset++;
707
 
                fake_argc++;
708
 
             }
709
 
          
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;
714
 
                fake_data_offset++;
715
 
             }
716
 
   
717
 
                /* start/end a quotation */
718
 
             if (ch=='\"') in_quote= !in_quote;
719
 
 
720
 
          }
721
 
       
722
 
          fclose(config_file);
723
 
   
724
 
          fake_argc+=1; /*  plus the last one */
725
 
   
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 *));
729
 
   
730
 
          fake_argv[0]=fake_data;
731
 
          counter=1;
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;
737
 
                }
738
 
                counter++;
739
 
             }
740
 
          }
741
 
 
742
 
       }
743
 
       else {
744
 
          read_from_file=0;
745
 
       }
746
 
 
747
 
    }
748
 
       /* Hack! Hack! Hack!  Oh, why do I abuse getopt() so */
749
 
    SAVE_GETOPT;
750
 
   
751
 
    while (arguments_pass<3) {
752
 
          /* Pass 0 read from file, if there */
753
 
       if (arguments_pass==0) {
754
 
          if (!read_from_file) {
755
 
             arguments_pass++;
756
 
          }
757
 
          else {
758
 
             custom_argc=&fake_argc;
759
 
             custom_argv=fake_argv;
760
 
          }
761
 
       }
762
 
          /* Pass 1 is command-line and overrides file */
763
 
       if (arguments_pass==1) {
764
 
             /* reset getopt()  *HACK HACK HACK* */
765
 
          RESET_GETOPT;
766
 
          custom_argc=&argc;
767
 
          custom_argv=argv;
768
 
          optarg=NULL;
769
 
       }
770
 
          /* -i passed, so reset everything and just go through command */
771
 
          /* line again */
772
 
       if (arguments_pass==2) {
773
 
          setup_info(&settings);
774
 
          custom_logo=NULL;
775
 
          RESET_GETOPT;
776
 
          custom_argc=&argc;
777
 
          custom_argv=argv;
778
 
          optarg=NULL;
779
 
       }
780
 
       
781
 
             /*******************************************************/
782
 
             /* Parse options (from file or command line arguments) */
783
 
             /*******************************************************/
784
 
       
785
 
       while ((c = getopt (*custom_argc, custom_argv,"D:F:L:"
786
 
                                   "a::b::c::de:fghiklno:pst:uvw:y"))!=-1) {
787
 
          switch (c) {
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);
793
 
                       break; 
794
 
             case 'D': custom_logo=load_logo_from_disk(optarg);
795
 
                       break;
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;
800
 
             
801
 
                       settings.custom_format=1;
802
 
                       if (settings.format) free(settings.format);
803
 
                    
804
 
                       settings.format=calloc(string_size,sizeof(char));
805
 
                       strncpy(settings.format,optarg,string_size);
806
 
                          
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 */
811
 
             
812
 
                       i=0; x=0;
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; 
818
 
                             }
819
 
                          }
820
 
                          else settings.format[x]=settings.format[i];
821
 
                          i++; x++;
822
 
                       }
823
 
                       settings.format[x]='\0';
824
 
                       break;
825
 
             case 'g': settings.display_sysinfo_only=1; break;
826
 
             case 'h': help_message(argv[0], 1); 
827
 
                       exit(0);
828
 
                       break;
829
 
             case 'i': ignore_config_file=1; 
830
 
                       break;
831
 
             case 'k': settings.center_sysinfo=0;
832
 
                       break;
833
 
             case 'l': settings.display_logo_only=1; break;
834
 
             case 'L': 
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)) {
842
 
                             do_listing=1;
843
 
                          }
844
 
                          else 
845
 
                          if (!strncmp(temp_st,"random",6)) {
846
 
                             random_logo=1;
847
 
                             random_type=temp_st[7];
848
 
                             random_type2=temp_st[8];
849
 
                          }
850
 
                          else {
851
 
                             printf("\nUnknown -L directive!\n\n");
852
 
                             return 4;
853
 
                          }
854
 
                       }
855
 
                       else { /* It's a number */
856
 
                          logo_override=1;
857
 
                       }
858
 
                       break;
859
 
             case 'n': settings.no_periods=1; break;
860
 
             case 'o': 
861
 
                       settings.offset=strtol(optarg,&endptr,10);
862
 
                       if ( endptr == optarg ) help_message(argv[0], 1);
863
 
                       break;
864
 
             case 'p': settings.preserve_xy=1; break;
865
 
             case 's': settings.skip_bogomips=1; break;
866
 
             case 't': 
867
 
                       settings.display_usertext=1;
868
 
                       settings.user_text=strdup(optarg);
869
 
                       break;
870
 
             case 'u': settings.show_uptime=1; break;
871
 
             case 'v': help_message(argv[0], 0);
872
 
                       exit(0);
873
 
                       break;
874
 
             case 'w':
875
 
                       settings.width=strtol(optarg,&endptr,10);
876
 
                       if ( endptr == optarg ) help_message(argv[0], 1);
877
 
                       break;
878
 
             case 'y': settings.show_load=1; break;
879
 
             case '?': printf("Try \"%s -h\" to show help\n\n",argv[0]);
880
 
                       exit(0); 
881
 
                       break;
882
 
          }
883
 
       }
884
 
   
885
 
          /* If unkown arguments, print the help */
886
 
       if ( custom_argv[optind] != NULL ) {
887
 
          printf("Unkown option %i: \"%s\"\n",optind,custom_argv[optind]);
888
 
          exit(1);
889
 
          
890
 
       }
891
 
       arguments_pass++;   
892
 
       if ((!ignore_config_file) && (arguments_pass==2)) arguments_pass++;
893
 
    }
894
 
    
895
 
       /*******************************************************/
896
 
       /* DONE WITH ALL THE STUPID OPTION PARSING             */
897
 
       /* now actually do things                              */
898
 
       /*******************************************************/
899
 
       
900
 
    setup_logos(&settings);
901
 
   
902
 
    if (do_listing) {
903
 
       printf("\nAvailable Built-in Logos:\n");
904
 
       printf("\tNum\tType\tAscii\tDescription\n");
905
 
 
906
 
       temp_logo=logo_info_head;
907
 
       i=1;
908
 
       while (temp_logo!=NULL) {
909
 
           printf("\t%d",i);
910
 
           if (temp_logo->sysinfo_position) printf("\tBanner");
911
 
           else printf("\tClassic");
912
 
           if (temp_logo->ascii_logo!=NULL) printf("\tYes");
913
 
           else printf("\tNo");
914
 
           printf("\t%s\n",temp_logo->description);
915
 
           temp_logo=temp_logo->next_logo;
916
 
           i++;
917
 
       }
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");
921
 
       return 0;  
922
 
    }
923
 
   
924
 
    if (random_logo) {
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;
929
 
       while(i) {
930
 
          if (custom_logo->next_logo==NULL) custom_logo=logo_info_head;
931
 
          else custom_logo=custom_logo->next_logo;
932
 
          i--;  
933
 
       }
934
 
       i=0;
935
 
       while (i<2) {
936
 
          logo_found=1;
937
 
          if (random_type=='b') { /* Want banner mode */
938
 
             if (!custom_logo->sysinfo_position) logo_found=0;
939
 
             else settings.banner_mode=1;
940
 
          }  
941
 
          if (random_type=='c') { /* Want classic mode */
942
 
             if (custom_logo->sysinfo_position) logo_found=0;
943
 
             else settings.banner_mode=0;
944
 
          }
945
 
          if (random_type=='e') { /* Want either */
946
 
             /* we should be OK */
947
 
          }  
948
 
 
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;
953
 
          }  
954
 
          if (random_type2=='a') { /* Want Ascii */
955
 
             if (custom_logo->ascii_logo==NULL) logo_found=0;
956
 
             else settings.plain_ascii=1;
957
 
          }
958
 
          
959
 
          if (random_type2=='n') { /* Want non-ascii */
960
 
             if (custom_logo->logo==NULL) logo_found=0;
961
 
             else settings.plain_ascii=0;
962
 
             break;
963
 
          }
964
 
          
965
 
          if (logo_found) break;
966
 
          
967
 
          if (custom_logo->next_logo==NULL) {
968
 
             custom_logo=logo_info_head;
969
 
             i++;
970
 
          }
971
 
          else custom_logo=custom_logo->next_logo;
972
 
       }
973
 
       if (i>1) {
974
 
          printf("\nSorry, can't generate random logo of that type.\n\n");
975
 
          return 3;
976
 
       }
977
 
    }
978
 
   
979
 
    if (logo_override) {
980
 
       custom_logo=logo_info_head;
981
 
       i=1;
982
 
       while (i<logo_num) {
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);
986
 
              return 1;
987
 
           }
988
 
           custom_logo=custom_logo->next_logo;
989
 
           i++;
990
 
       }
991
 
    }
992
 
   
993
 
       /* We have to keep these consistent or funny things happen */
994
 
    if (custom_logo!=NULL) {
995
 
       settings.banner_mode=custom_logo->sysinfo_position;
996
 
    }
997
 
 
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);
1005
 
    
1006
 
       if (settings.display_usertext) {
1007
 
          sprintf(temp_string,"#E\n%s",settings.format);
1008
 
          settings.format=strdup(temp_string);
1009
 
       }
1010
 
       
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);
1015
 
       }
1016
 
       
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);
1021
 
       }
1022
 
    }
1023
 
   
1024
 
       /* Preserve xy if so desired */
1025
 
    if ((settings.preserve_xy) && (!settings.plain_ascii)) 
1026
 
       ansi_print("^[7");
1027
 
   
1028
 
       /* Draw the logo */
1029
 
    
1030
 
    draw_logo(custom_logo,&settings);
1031
 
         
1032
 
       /* Restore xy if we saved it */
1033
 
    if ((settings.preserve_xy) && (!settings.plain_ascii)) ansi_print("^[8");
1034
 
   
1035
 
    return 0;
1036
 
}
 
1
/*-------------------------------------------------------------------------*\
 
2
  LINUX LOGO 5.03 - Creates Nifty Logo With System Info - 3 January 2008
 
3
 
 
4
    by Vince Weaver (vince@deater.net, http://www.deater.net/weave )
 
5
 
 
6
  A program to display text/ansi logos with system information.
 
7
 
 
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
\*-------------------------------------------------------------------------*/
 
11
 
 
12
 
 
13
#define VERSION "5.03"
 
14
 
 
15
#include <stdio.h>
 
16
#include <stdlib.h>   /* calloc() */
 
17
#include <string.h>   /* strdup() */
 
18
#include <sys/time.h> /* time() */
 
19
#include <locale.h>
 
20
 
 
21
#define ESCAPE "\033"
 
22
 
 
23
#include "sysinfo.h"
 
24
#include "linux_logo.h"
 
25
#include "logo_types.h"
 
26
#include "load_logo.h"
 
27
 
 
28
#if (USE_I18N==1)
 
29
#undef __OPTIMIZE__
 
30
#include <libintl.h>
 
31
#define _(String) gettext((String))
 
32
#else
 
33
#define _(String) (String)
 
34
#endif
 
35
 
 
36
/* Change the values in the below file to alter default behavior */
 
37
#include "defaults.h"
 
38
 
 
39
/* Some global variables.  Possibly bad in practice, but it saves a lot *\
 
40
\* of paramater passing, which has caused bugs to develop before.       */
 
41
 
 
42
struct logo_info    *logo_info_head = NULL;
 
43
struct logo_info    *logo_info_tail = NULL;
 
44
 
 
45
 
 
46
char *vmw_strcat(char *dest, char *src, int space_remaining) {
 
47
 
 
48
   if (strlen(src) >= space_remaining) {
 
49
      fprintf(stderr,"Error!  Not enough room in string!\n\n");
 
50
      exit(1);
 
51
   }
 
52
   return strcat(dest,src);   
 
53
}
 
54
 
 
55
   /* Convert a number into an ordinal string */
 
56
static void strcat_ordinal(int value,char *string, int space) {
 
57
 
 
58
     switch(value) {
 
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;
 
70
   }
 
71
}
 
72
 
 
73
 
 
74
  /* setup the default logos, which are always present */
 
75
static void setup_default_logos() {
 
76
 
 
77
   struct logo_info *new_logo;
 
78
 
 
79
#include "load_logos.h"
 
80
   
 
81
}
 
82
 
 
83
 
 
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) {
 
87
 
 
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;
 
108
}
 
109
 
 
110
    /* Use ansi codes or spaces to shift the cursor to the right */
 
111
static void shift_right(int shift,int plain_ascii) {
 
112
 
 
113
    int i;
 
114
 
 
115
    if (shift<=0) return;
 
116
 
 
117
    if (plain_ascii) {
 
118
       for(i=0;i<shift;i++) {
 
119
          putchar(' ');
 
120
       }
 
121
    }
 
122
    else {
 
123
       printf("\033[%iC",shift);
 
124
    }
 
125
}
 
126
 
 
127
   /* Prints a string, but stops at a newline or end of string */
 
128
static char *print_line(char *string) {
 
129
 
 
130
    char *temp_st=string;
 
131
   
 
132
    if (temp_st==NULL) return NULL;
 
133
 
 
134
    while ((*temp_st!='\n') && (*temp_st!='\0')) {
 
135
       putchar(*temp_st);
 
136
       temp_st++;
 
137
    }
 
138
    if ((*temp_st)=='\n') {
 
139
       return temp_st+1;
 
140
    }
 
141
    else return NULL;
 
142
}
 
143
 
 
144
 
 
145
    /* print enough chars to center text of given size */
 
146
static void center(int size,int width,int plain_ascii) {
 
147
 
 
148
   int i;
 
149
 
 
150
   i=((width-size)/2);
 
151
   shift_right(i,plain_ascii);
 
152
 
 
153
}
 
154
 
 
155
 
 
156
    /* Uses escape codes to clear the screen */
 
157
static void clear_screen(int plain_ascii) {
 
158
 
 
159
   if (!plain_ascii) {
 
160
      printf("\033[2J\033[0;0H\n");
 
161
   }
 
162
   else {
 
163
      /* clear the screen some other way? */
 
164
   }
 
165
}
 
166
 
 
167
    /* Change uptime seconds into time string */
 
168
static void strcat_uptime(int seconds,char *string, int space) {
 
169
 
 
170
    int up_days,up_hrs,up_mins;
 
171
    char temp_string[BUFSIZ],final_string[BUFSIZ];
 
172
 
 
173
    up_days=seconds/86400;
 
174
    up_hrs=(seconds-(up_days*86400))/3600;
 
175
    up_mins=(seconds-(up_days*86400)-(up_hrs*3600))/60;
 
176
 
 
177
    final_string[0]=0;
 
178
    vmw_strcat(final_string,_("Uptime "),BUFSIZ);
 
179
 
 
180
    if (up_days>0) {
 
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));
 
184
    }
 
185
 
 
186
    if (up_hrs>0) {
 
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));
 
190
    }
 
191
    if (up_mins>0) {
 
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));
 
195
    }
 
196
    vmw_strcat(string,final_string,space);
 
197
}
 
198
 
 
199
    /* Prints the help */
 
200
static void help_message(char *binname, char full) {
 
201
 
 
202
    char temp_version[BUFSIZ];
 
203
   
 
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");
 
210
    if (!full) exit(0);
 
211
    printf("Usage:   %s [-a] [-b] [-c] [-d] [-D file] [-e file] [-f] "
 
212
           "[-g]\n"
 
213
           "                    [-h] [-i] [-k] [-l] [-n] [-o num] [-p] [-s] [-t str] "
 
214
           "[-u] [-v]\n"
 
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 "
 
223
           "debugging]\n");
 
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 "
 
234
           "platforms]\n");
 
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"
 
242
           "\n\n");
 
243
}
 
244
 
 
245
  
 
246
    /* The nifty customizable sysinfo parser */
 
247
static int generate_sysinfo(
 
248
                  char ***string,
 
249
                  struct linux_logo_info_type *settings) {
 
250
 
 
251
    struct os_info_type os_info;
 
252
    struct cpu_info_type cpu_info;
 
253
 
 
254
    int x=0,len,line=0;
 
255
    char temp_string[BUFSIZ],hostname[BUFSIZ],domain[BUFSIZ];
 
256
    char temp_line[BUFSIZ];
 
257
    float load_1,load_5,load_15;
 
258
    char **temp_sysinfo;
 
259
    char char_string[2]={0,0};
 
260
    int allocated_lines=10;
 
261
 
 
262
       /* Get the system info */
 
263
    get_os_info(&os_info);
 
264
    get_cpu_info(&cpu_info);
 
265
 
 
266
    len=strlen(settings->format);
 
267
 
 
268
       /* allocate 10 lines to start with */
 
269
    temp_sysinfo=calloc(allocated_lines,sizeof(char *));
 
270
 
 
271
    while (x<len) {
 
272
 
 
273
          /* clear out our line */
 
274
       temp_line[0]=0;
 
275
 
 
276
          /* handle a line */
 
277
       while (settings->format[x]!='\n') {
 
278
 
 
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));
 
283
          }
 
284
          else {
 
285
             x++;
 
286
             if (x>len) break;
 
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);
 
294
                          }
 
295
                          else {
 
296
                             snprintf(temp_string,BUFSIZ,"%.0f",cpu_info.bogomips);
 
297
                          }
 
298
                          vmw_strcat(temp_line,temp_string,BUFSIZ-strlen(temp_line));
 
299
                          break;
 
300
                   /* #C prints OS revision */
 
301
                case 'C': vmw_strcat(temp_line,os_info.os_revision,
 
302
                                     BUFSIZ-strlen(temp_line));
 
303
                                     break;  
 
304
                   /* #E prints user text */
 
305
                case 'E': vmw_strcat(temp_line,settings->user_text,
 
306
                                     BUFSIZ-strlen(temp_line));
 
307
                                     break;  
 
308
                   /* #H prints hostname */
 
309
                case 'H': vmw_strcat(temp_line,get_host_name(hostname,domain),
 
310
                                     BUFSIZ-strlen(temp_line));
 
311
                                     break;
 
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));
 
317
                          break;
 
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);  
 
323
                             }
 
324
                             else {
 
325
                                snprintf(temp_string,BUFSIZ,"%.3gMHz",
 
326
                                         cpu_info.megahertz);  
 
327
                             }
 
328
                             vmw_strcat(temp_line,temp_string,
 
329
                                        BUFSIZ-strlen(temp_line));
 
330
                          }
 
331
                          else {
 
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;
 
336
                             }
 
337
                          }
 
338
                          break;
 
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));
 
346
                          }
 
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));
 
351
                          }
 
352
                          else {
 
353
                             strcat_ordinal(10,temp_line,
 
354
                                            BUFSIZ-strlen(temp_line));
 
355
                          }
 
356
                          break;
 
357
                   /* #O prints the OS name */
 
358
                case 'O': vmw_strcat(temp_line,os_info.os_name,
 
359
                                     BUFSIZ-strlen(temp_line));
 
360
                                     break;
 
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));
 
366
                          }
 
367
                          else {
 
368
                             vmw_strcat(temp_line,_(PROCESSOR_SINGULAR),
 
369
                                    BUFSIZ-strlen(temp_line));
 
370
                          }
 
371
                          break;
 
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));
 
376
                        }
 
377
                        else if (get_mem_size()>1023) {
 
378
                           snprintf(temp_string,BUFSIZ,"%.2gGB",
 
379
                                 ((double)get_mem_size()/1024.0));
 
380
                        } else {
 
381
                           snprintf(temp_string,BUFSIZ,"%ldM",get_mem_size());
 
382
                        }
 
383
                        vmw_strcat(temp_line,temp_string,BUFSIZ-strlen(temp_line));
 
384
                        break;
 
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));
 
388
                          }
 
389
                          break;
 
390
                   /* #T prints the CPU type */
 
391
                case 'T': vmw_strcat(temp_line,cpu_info.chip_type,
 
392
                                     BUFSIZ-strlen(temp_line));
 
393
                          break;
 
394
                   /* #U prints the uptime */
 
395
                case 'U': strcat_uptime(get_uptime(),temp_line,
 
396
                                        BUFSIZ-strlen(temp_line)); 
 
397
                          break;
 
398
                   /* #V prints the OS version */
 
399
                case 'V': vmw_strcat(temp_line,os_info.os_version,
 
400
                                     BUFSIZ-strlen(temp_line)); 
 
401
                          break;  
 
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;
 
406
                             }
 
407
                          }
 
408
                          else {
 
409
                             vmw_strcat(temp_line,cpu_info.chip_vendor,
 
410
                                        BUFSIZ-strlen(temp_line));
 
411
                          }
 
412
                          break;
 
413
                default: fprintf(stderr,"\nInvalid format '#%c'\n",
 
414
                                 settings->format[x]);
 
415
             }
 
416
          }
 
417
          x++;
 
418
          if (x>=len) break;
 
419
       }
 
420
       temp_sysinfo[line]=strdup(temp_line);  
 
421
       line++;
 
422
         
 
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;
 
428
       }
 
429
 
 
430
       /* skip the newline */
 
431
       x++;
 
432
    }
 
433
    *string=temp_sysinfo;
 
434
    return line;
 
435
}
 
436
 
 
437
 
 
438
    /* The Main Drawing Routine */  
 
439
static void draw_logo(struct logo_info *logo_override,
 
440
               struct linux_logo_info_type *settings) {
 
441
 
 
442
    struct logo_info *our_logo_info;
 
443
    char *string_point;
 
444
    int i,ysize,sysinfo_length=0;
 
445
    char **sysinfo_string;
 
446
 
 
447
    sysinfo_length=generate_sysinfo(&sysinfo_string,settings);
 
448
 
 
449
    if (logo_info_head==NULL) {
 
450
       printf("\n\nNo logos available!!\n");
 
451
       return;
 
452
    }
 
453
 
 
454
    if (logo_override!=NULL) {
 
455
       our_logo_info=logo_override;
 
456
    }
 
457
    else { /* Search for a proper logo! */
 
458
       our_logo_info=logo_info_head;
 
459
       while (1) {
 
460
          if (our_logo_info==NULL) {
 
461
             printf("\nAppropriate logo not found!\n\n");
 
462
             return;
 
463
          }
 
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) {
 
468
                   break;
 
469
                }
 
470
             }
 
471
             else { /* Not ascii */
 
472
                if (our_logo_info->logo!=NULL) {
 
473
                   break;
 
474
                }
 
475
             }
 
476
          }
 
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) {
 
481
                   break;
 
482
                }
 
483
             } else { /* Not ascii */
 
484
               if (our_logo_info->logo!=NULL) {
 
485
                  break;
 
486
               }
 
487
             }
 
488
          }
 
489
          our_logo_info=our_logo_info->next_logo;
 
490
       }
 
491
    }
 
492
 
 
493
    if (settings->width<80) settings->width=80;  /* Right now we don't */
 
494
                                                 /* handle width < 80  */
 
495
  
 
496
    if (settings->wipe_screen) clear_screen(settings->plain_ascii);
 
497
 
 
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");
 
503
          return;
 
504
       }
 
505
       else string_point=our_logo_info->ascii_logo;
 
506
    }
 
507
    else {
 
508
       ysize=our_logo_info->ysize;
 
509
       if (our_logo_info->logo==NULL) {
 
510
          printf("\nSpecified logo has no non-ascii version!\n\n");
 
511
          return;
 
512
       }
 
513
       else string_point=our_logo_info->logo;
 
514
    }
 
515
 
 
516
       /* Draw the logos */
 
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);
 
522
             printf("\n");
 
523
          }
 
524
          if (!settings->display_logo_only) printf("\n");
 
525
       }
 
526
       else {  /* Classic mode logo */
 
527
 
 
528
             /* Print the first 7 lines of logo */
 
529
 
 
530
          if (ysize<7) {
 
531
             printf("\nError! Classic logos must be at least 7 lines long!\n");
 
532
          }
 
533
 
 
534
          if (!settings->plain_ascii) printf("\033[40m\033[40m\n");
 
535
 
 
536
          for(i=0;i<7;i++) {
 
537
             shift_right(settings->offset,settings->plain_ascii);
 
538
             string_point=print_line(string_point);
 
539
             printf("\n");
 
540
          }
 
541
 
 
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");
 
551
             }
 
552
             printf("\n");
 
553
          }
 
554
       }
 
555
    }
 
556
 
 
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++) {
 
561
 
 
562
             if (settings->center_sysinfo) {
 
563
                center(strlen(sysinfo_string[i]),settings->width,
 
564
                       settings->plain_ascii);
 
565
             }
 
566
 
 
567
             if (!settings->plain_ascii) printf("\033[1;37;40m");
 
568
             printf("%s",sysinfo_string[i]);
 
569
             if (!settings->plain_ascii) printf("\033[0m");
 
570
             printf("\n");
 
571
          }
 
572
          printf("\n");
 
573
       }
 
574
    }
 
575
 
 
576
       /* Restore cursor color to normal */
 
577
    if (!settings->plain_ascii) {
 
578
       printf("\033[0m\033[255D");
 
579
    }
 
580
}
 
581
 
 
582
 
 
583
static char *get_arg(int *index,int argc,char **argv) {
 
584
 
 
585
   char *argument;
 
586
 
 
587
   if (argv[*index][2]=='\0') {
 
588
      (*index)++;
 
589
      if (*index>=argc) {
 
590
         argument=NULL;
 
591
         printf("Missing parameter to option -%c\n\n",argv[(*index)-1][1]);
 
592
         exit(1);
 
593
      }
 
594
      else {
 
595
         argument=argv[*index];
 
596
      }
 
597
   }
 
598
   else {
 
599
      argument=&(argv[*index][2]);
 
600
   }
 
601
 
 
602
   return argument;
 
603
 
 
604
}
 
605
 
 
606
    /**************************/
 
607
    /* logo support functions */
 
608
    /**************************/
 
609
 
 
610
 
 
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;
 
614
 
 
615
 
 
616
    /* Find a logo by name */
 
617
static struct logo_info *get_logo_by_name(char *logo_name) {
 
618
 
 
619
   static struct logo_info *custom_logo;
 
620
   
 
621
   custom_logo=logo_info_head;
 
622
   while(custom_logo!=NULL) {
 
623
      
 
624
      if (!strcmp(custom_logo->name,logo_name)) {
 
625
         return custom_logo;     
 
626
      }
 
627
      custom_logo=custom_logo->next_logo;
 
628
   }
 
629
   fprintf(stderr,"Error!  No logo with the name %s is available!\n",logo_name);
 
630
   return NULL;
 
631
}
 
632
 
 
633
   /* Find a logo by number */
 
634
static struct logo_info *get_logo_by_number(int logo_num) {
 
635
 
 
636
    int i;
 
637
    static struct logo_info *custom_logo;
 
638
 
 
639
    custom_logo=logo_info_head;
 
640
    i=1;
 
641
    while (i<logo_num) {
 
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;
 
646
          break;
 
647
       }
 
648
       custom_logo=custom_logo->next_logo;
 
649
       i++;
 
650
    }
 
651
    return custom_logo;
 
652
}
 
653
 
 
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) {
 
657
 
 
658
    struct timeval time_time;
 
659
    int i,logo_found;
 
660
    static struct logo_info *custom_logo;
 
661
   
 
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 */
 
665
 
 
666
    custom_logo=logo_info_head;
 
667
    while(i) {
 
668
       if (custom_logo->next_logo==NULL) custom_logo=logo_info_head;
 
669
       else custom_logo=custom_logo->next_logo;
 
670
       i--;
 
671
    }
 
672
 
 
673
    i=0;
 
674
    while (i<2) {
 
675
       logo_found=1;
 
676
       if (random_type=='b') { /* Want banner mode */
 
677
          if (!custom_logo->sysinfo_position) logo_found=0;
 
678
          else settings->banner_mode=1;
 
679
       }
 
680
       if (random_type=='c') { /* Want classic mode */
 
681
          if (custom_logo->sysinfo_position) logo_found=0;
 
682
          else settings->banner_mode=0;
 
683
       }
 
684
       if (random_type=='e') { /* Want either */
 
685
          /* we should be OK */
 
686
       }
 
687
 
 
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;
 
692
          }
 
693
       }
 
694
       if (random_type2=='a') { /* Want Ascii */
 
695
          if (custom_logo->ascii_logo==NULL) logo_found=0;
 
696
          else settings->plain_ascii=1;
 
697
       }
 
698
 
 
699
       if (random_type2=='n') { /* Want non-ascii */
 
700
          if (custom_logo->logo==NULL) logo_found=0;
 
701
          else settings->plain_ascii=0;
 
702
          break;
 
703
       }
 
704
 
 
705
       if (logo_found) break;
 
706
       
 
707
       if (custom_logo->next_logo==NULL) {
 
708
          custom_logo=logo_info_head;
 
709
          i++;
 
710
       }
 
711
       else custom_logo=custom_logo->next_logo;
 
712
    }
 
713
    if (i>1) {
 
714
       printf("\nSorry, can't generate random logo of that type.\n\n");
 
715
       exit(1);
 
716
    }
 
717
    return custom_logo;
 
718
}
 
719
 
 
720
   /* list the logos */
 
721
static void list_logos() {
 
722
 
 
723
    int i;
 
724
    struct logo_info *temp_logo;
 
725
 
 
726
    printf("\nAvailable Built-in Logos:\n");
 
727
    printf("\tNum\tType\tAscii\tName\t\tDescription\n");
 
728
 
 
729
    temp_logo=logo_info_head;
 
730
    i=1;
 
731
    while (temp_logo!=NULL) {
 
732
       printf("\t%d",i);
 
733
       if (temp_logo->sysinfo_position) printf("\tBanner");
 
734
       else printf("\tClassic");
 
735
       if (temp_logo->ascii_logo!=NULL) printf("\tYes");
 
736
       else printf("\tNo");
 
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;
 
741
       i++;
 
742
    }
 
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");
 
746
    exit(0);
 
747
}
 
748
 
 
749
 
 
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) {
 
755
  
 
756
    int i,x,string_size;
 
757
    char *endptr,*argument;
 
758
    int index=1,option;
 
759
    char *temp_st;
 
760
 
 
761
    if (argc<2) return;
 
762
 
 
763
    while (1) {
 
764
 
 
765
       if (argv[index][0]!='-') {
 
766
          printf("Unknown parameter %s\n",argv[index]);
 
767
          exit(1);
 
768
       }
 
769
       option=argv[index][1];
 
770
 
 
771
       switch (option) {
 
772
          case 'a': settings->plain_ascii=1;
 
773
                    break;
 
774
          case 'b': settings->banner_mode=1;
 
775
                    break;
 
776
          case 'c': settings->banner_mode=0;
 
777
                    break;
 
778
          case 'd': settings->pretty_output=0;
 
779
                    set_pretty_printing(0);
 
780
                    break;
 
781
          case 'D': argument=get_arg(&index,argc,argv);
 
782
                    logo_disk=strdup(argument);
 
783
                    break;
 
784
          case 'e': argument=get_arg(&index,argc,argv);
 
785
                    set_cpuinfo_file(argument);
 
786
                    break;
 
787
          case 'f': settings->wipe_screen=1;
 
788
                    break;
 
789
          case 'F': argument=get_arg(&index,argc,argv);
 
790
                    string_size=strlen(argument);
 
791
                    if (string_size==0) break;
 
792
 
 
793
                    settings->custom_format=1;
 
794
                    strncpy(settings->format,argument,BUFSIZ);
 
795
 
 
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 */
 
800
 
 
801
                    i=0; x=0;
 
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;
 
807
                          }
 
808
                       }
 
809
                       else {
 
810
                          settings->format[x]=settings->format[i];
 
811
                       }
 
812
                       i++; x++;
 
813
                    }
 
814
                    settings->format[x]='\0';
 
815
                    break;
 
816
          case 'g': settings->display_sysinfo_only=1;
 
817
                    break;
 
818
          case 'h':
 
819
          case '?': help_message(argv[0], 1);
 
820
                    exit(0);
 
821
                    break;
 
822
                    /* FIXME */  
 
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; */
 
827
                    break;
 
828
          case 'k': settings->center_sysinfo=0;
 
829
                    break;
 
830
          case 'l': settings->display_logo_only=1;
 
831
                    break;  
 
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)) {
 
840
                          want_list_logos=1;
 
841
                       }
 
842
                       else if (!strncmp(temp_st,"random",6)) {
 
843
                          random_logo=1;
 
844
                          random_type=temp_st[7];
 
845
                          random_type2=temp_st[8];
 
846
                       }
 
847
                       else {
 
848
                          logo_name=strdup(temp_st);
 
849
                       }
 
850
                    }
 
851
                    else { /* It's a number */
 
852
                       logo_override=1;
 
853
                    }
 
854
                    break;  
 
855
 
 
856
          case 'n': settings->no_periods=1;
 
857
                    break;
 
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);
 
862
                       exit(1);
 
863
                    }
 
864
                    break;
 
865
          case 'p': settings->preserve_xy=1;
 
866
                    break;
 
867
          case 's': settings->skip_bogomips=1;
 
868
                    break;
 
869
          case 't': argument=get_arg(&index,argc,argv);
 
870
                    settings->display_usertext=1;
 
871
                    strncpy(settings->user_text,argument,BUFSIZ);
 
872
                    break;
 
873
          case 'u': settings->show_uptime=1;
 
874
                    break;
 
875
          case 'v': help_message(argv[0], 0);
 
876
                    exit(0);
 
877
                    break;
 
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);
 
882
                       exit(1);
 
883
                    }
 
884
                    break;
 
885
          case 'y': settings->show_load=1;
 
886
                    break;
 
887
          default:  printf("Unknown option -%c\n",option);
 
888
                    exit(1);
 
889
       }
 
890
 
 
891
       index++;
 
892
       if (index>=argc) break;
 
893
    }
 
894
}
 
895
 
 
896
 
 
897
       /* Look for ~/.linux_logo or /etc/linux_logo config files */
 
898
void read_config_file(struct linux_logo_info_type *settings) {
 
899
 
 
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";
 
906
 
 
907
       /* Check for the files */
 
908
 
 
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! */
 
917
    }
 
918
 
 
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");
 
922
    }
 
923
 
 
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             */
 
928
 
 
929
    if (config_file!=NULL) {
 
930
       
 
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 */
 
938
             else {
 
939
                valid_string=1;
 
940
                break;
 
941
             }
 
942
          }
 
943
          if (feof(config_file)) break;
 
944
       }
 
945
 
 
946
       if (valid_string) {
 
947
 
 
948
          size=strlen(config_string);
 
949
 
 
950
          config_string[size-1]='\0';  /* get rid of trailing \n */
 
951
 
 
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);
 
956
          fake_data_offset=11;
 
957
          vmw_strcat(fake_data,config_string,size);
 
958
 
 
959
          ch=' ';
 
960
          for(i=0;i<size;i++) {
 
961
 
 
962
             oldch=ch;
 
963
             ch=config_string[i]; /* start after linux_logo */
 
964
 
 
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';
 
968
                fake_data_offset++;
 
969
                fake_argc++;
 
970
             }
 
971
 
 
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;
 
976
                fake_data_offset++;
 
977
             }
 
978
 
 
979
                /* start/end a quotation */
 
980
             if (ch=='\"') in_quote= !in_quote;
 
981
 
 
982
          }
 
983
 
 
984
          fclose(config_file);
 
985
 
 
986
          fake_argc+=1; /*  plus the last one */
 
987
 
 
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 *));
 
991
 
 
992
          fake_argv[0]=fake_data;
 
993
          counter=1;
 
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;
 
999
                }
 
1000
                counter++;
 
1001
             }
 
1002
          }
 
1003
 
 
1004
          parse_command_line(settings,fake_argc,fake_argv);
 
1005
       }
 
1006
    }
 
1007
}
 
1008
 
 
1009
 
 
1010
    /* The main program */
 
1011
int main(int argc,char **argv) {
 
1012
 
 
1013
    char temp_string[BUFSIZ],*temp_pointer;
 
1014
    struct linux_logo_info_type settings;
 
1015
    struct logo_info *custom_logo=NULL;
 
1016
 
 
1017
#if (USE_I18N==1)
 
1018
       /* i18n */
 
1019
    setlocale(LC_ALL, "");
 
1020
    bindtextdomain("linux_logo", LOCALE_DIR);
 
1021
    textdomain("linux_logo");
 
1022
#endif
 
1023
       /* Set some defaults */
 
1024
    setup_info(&settings);
 
1025
 
 
1026
    read_config_file(&settings);
 
1027
 
 
1028
    parse_command_line(&settings,argc,argv);
 
1029
 
 
1030
       /*******************************************************/
 
1031
       /* DONE WITH ALL THE STUPID OPTION PARSING             */
 
1032
       /* now actually do things                              */
 
1033
       /*******************************************************/
 
1034
 
 
1035
       /* Setup all the logos */
 
1036
    setup_default_logos();
 
1037
 
 
1038
       /* If user requested a list, list them and exit */
 
1039
    if (want_list_logos) list_logos();
 
1040
 
 
1041
       /* If user requested random logo, get one */
 
1042
    if (random_logo) custom_logo=get_random_logo(random_type,random_type2,&settings);
 
1043
 
 
1044
       /* If user requested logo by number, get it */
 
1045
    if (logo_num!=0) custom_logo=get_logo_by_number(logo_num);
 
1046
 
 
1047
       /* If user requested logo by name, get it */
 
1048
    if (logo_name!=NULL) custom_logo=get_logo_by_name(logo_name);
 
1049
 
 
1050
       /* If user wants a logo from disk, get it */
 
1051
    if (logo_disk!=NULL) custom_logo=load_logo_from_disk(logo_disk);
 
1052
 
 
1053
       /* We have to keep these consistent or funny things happen */
 
1054
    if (custom_logo!=NULL) settings.banner_mode=custom_logo->sysinfo_position;
 
1055
 
 
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
       /**************************************************/
 
1061
 
 
1062
    if (!settings.custom_format) {
 
1063
 
 
1064
          /* Set the format for banner or classic mode */
 
1065
       if (settings.banner_mode) {
 
1066
          strncpy(settings.format,_(DEFAULT_BANNER_FORMAT),BUFSIZ);
 
1067
       }
 
1068
       else {
 
1069
          strncpy(settings.format,DEFAULT_CLASSIC_FORMAT,BUFSIZ);
 
1070
       }
 
1071
 
 
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));
 
1077
       }
 
1078
 
 
1079
          /* If want system load, add it second-to-last */
 
1080
       if (settings.show_load) {
 
1081
 
 
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));
 
1087
          }
 
1088
          else {
 
1089
             if (strlen(settings.format)+3<BUFSIZ) {
 
1090
                strcpy(temp_pointer,"#L\n#H\n");
 
1091
             }
 
1092
          }
 
1093
       }
 
1094
 
 
1095
          /* if want uptime, add it second_to_last */
 
1096
       if (settings.show_uptime) {
 
1097
 
 
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));
 
1103
          }
 
1104
          else {
 
1105
             if (strlen(settings.format)+3<BUFSIZ) {
 
1106
                strcpy(temp_pointer,"#U\n#H\n");
 
1107
             }
 
1108
          }
 
1109
       }
 
1110
    }
 
1111
 
 
1112
       /* Preserve xy if so desired */
 
1113
    if ( (settings.preserve_xy) && (!settings.plain_ascii) ) {
 
1114
       printf(ESCAPE"7");
 
1115
    }
 
1116
 
 
1117
       /* Draw the logo */
 
1118
    draw_logo(custom_logo,&settings);
 
1119
 
 
1120
       /* Restore xy if we saved it */
 
1121
    if ( (settings.preserve_xy) && (!settings.plain_ascii) ) {
 
1122
       printf(ESCAPE"8");
 
1123
    }
 
1124
 
 
1125
    return 0;
 
1126
}