/*

  linuxinfo, written by M. Lang, University of Mainz, 12/1996
 
Linuxinfo shows several nice stuff about the running Linux-system on the 
PS/2 95 series LED-display. This means that you need at least an IBM PS/2
95 with this special LED-display, the Kernel-patch for MCA and it all 
together running. Compile this code with

   gcc -O display.c -o display

Because it accesses ports, this program must be run as root.  This means 
either root must run it, or it must be owned by root with the suid bit 
set (chown root.root display ; chmod 4755 display)  The program doesn't 
check for root permission, so you'll get a Seg. fault if it is not root.

*/


#include <stdio.h>
#include <string.h>
#include <time.h>
#include <linux/unistd.h>
#include <asm/io.h>
#include <signal.h>

char regs[9];

void hauweg(int);

int show_string(char *text)
{
   int i,j;

   j=strlen(text); /* set maximum textlength */
   if (j>7) j=7;   
   
   for (i=0; i<j; i++)
     {
	outb((char)text[i],0x109+6-i);
     }
   return(0);
}

int roll_display(char *text)
{
   int i,j;
   
   j=strlen(text);
   for (i=0; i<6; i++)
     outb(32,0x109+6-i); 
   for (i=0; i<=6; i++)
     regs[i]=regs[i+1];
   regs[5]=text[0];
   for (i=0; i<6; i++)
     {
	outb((char)regs[i],0x109+6-i);
     }
   return(0);
}
     
char *datum(void)
{
   time_t t;
   t=time(NULL);
   return(ctime(&t));
}


int main (int argc, char *argv[])
{
   int b;
   char len;
   char s[16384];
   char zeile[256];
   char *progname;
   char zeit[256];
   FILE *hi, *ut;
   char x1[30],x2[30],x3[30];
   char y1[30],y2[30],y3[30];
   char t1[20],t2[20];
      
   for (b=0; b<=9; b++)
     {
	regs[b]=(char)32;
     }
   
   /* permission to the PS/2 95 display ports */
   ioperm(0x109,7,1);
   progname = argv[0];
   
   signal(SIGHUP, SIG_IGN);
   signal(SIGINT, hauweg);
   signal(SIGTERM, hauweg);
   signal(SIGKILL, hauweg);
   signal(SIGQUIT, hauweg);
      
   if ((hi=fopen("/proc/version","r"))==NULL)
     {
	fprintf(stderr,"Error - Cannot get Linux version, no proc-fs support.\n");
	return(-1);
     }
   
   fgets(zeile,255,hi);
   fclose(hi);
   sscanf(zeile,"%s%s%s",x1,x2,x3);
      
   for (;;)
     {
	if ((hi=fopen("/proc/loadavg","r"))==NULL)
          {
	     fprintf(stderr,"Error - Cannot get system load, no proc-fs support.\n");
	     return(-1);
          }   
        fgets(zeile,255,hi);
        fclose(hi);
	sscanf(zeile,"%s%s%s",y1,y2,y3);
	strcpy(s,x1);
	
	if ((ut=fopen("/proc/uptime","r"))==NULL)
	  {
	     fprintf(stderr,"Error - Cannot get system uptime.\n");
	     return(-1);
	  }
	fgets(zeile,255,ut);
	fclose(ut);
	sscanf(zeile,"%s%s",t1,t2);
   
	strcat(s," ");
	strcat(s,x2);
	strcat(s," ");
	strcat(s,x3);
	strcat(s,", Time: ");
        strcpy(zeit,datum());
        zeit[strlen(zeit)-1]='\0';
	strcat(s,zeit);
	strcat(s,", Sys-Load: ");
	strcat(s,y1);
	strcat(s,"/");
	strcat(s,y2);
	strcat(s,"/");
	strcat(s,y3);
	strcat(s,", Sys-Uptime: ");
	strcat(s,t1);
	strcat(s," ");
	strcat(s,t2);
        strcat(s," *** ");
	
        for (b=0; b<strlen(s); b++)
     	  {
             roll_display(s+b);
	     usleep(200000);
          }
     }
   return(0);
}

void hauweg(int signal)
{
    show_string("Arrgh!");
    sleep(2);
    show_string("      ");
    exit(0);
}

