From: frank.kaefer@Germany.Sun.COM (Frank Kaefer)
Newsgroups: de.comp.sources.unix
Subject: v01i042: dcf77 - Ein DCF-77 Treiberprogramm in C unter UNIX, OS/2 und DOS
Date: 7 Sep 92 19:53:26 GMT
Reply-To: fsommer@krefcom.ish.de
Followup-To: de.comp.sources.d

Submitted-by: fsommer@krefcom.ish.de
Posting-number: Volume 1, Issue 42
Archive-name: dcf77/part01

[ Dies ist ein dcf77 Treiberprogramm. Ich konnte es magels eines DCF-77
  nicht testen. Das File dcf.inp habe ich vom Autor so mit Laenge 0
  bekommen und man sagte mir, dass die Software auch ohne es
  funktioniert - Rueckfragen daher bitte direkt an den Autor     -fk     ]

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# Contents:  dcf dcf/Makefile dcf/Notes dcf/README.ixos dcf/dcf.c
#   dcf/dcf.inp dcf/dcf.rel dcf/dcfdef.h dcf/dcfdoc dcf/dcfport.c
#   dcf/dcfport.rel
# Wrapped by fkk@stasys on Mon Sep  7 21:40:39 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo '          "shar: End of archive 1 (of 1)."'
if test ! -d 'dcf' ; then
    echo shar: Creating directory \"'dcf'\"
    mkdir 'dcf'
fi
if test -f 'dcf/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dcf/Makefile'\"
else
  echo shar: Extracting \"'dcf/Makefile'\" \(895 characters\)
  sed "s/^X//" >'dcf/Makefile' <<'END_OF_FILE'
X################################################################################
X# Makefile fuer dcf       (c) 1992 by fsommer@krefcom.ish.de
X#
X#
X#-DSUN fuer Sun/OS einfuegen,
X#-D_OS2_ fuer OS/2 einfuegen,
X#-DSYSV fuer System V einfuegen, 
X#-DSET_TERM_PAR einfuegen, wenn Terminaleinstellungen vorgenommen werden sollen
X#(geht nicht bei OS/2)
X#
X#-nointl bei SCO eingefuegt verkleinert das Programm erheblich
X################################################################################
X
X
XCFLAGS	= -O  -DSYSV -DSET_TERM_PAR -nointl  
XOBJS	= dcf.o dcfport.o
XDESTDIR = /usr/local/bin
X#CCLIBS = -lc_s      # Shared Lib bei SYSV (verkleinert das Executable) 
XCC = cc     # aufpassen bei gcc ver. 2.2.2 !
X
Xdcf:	$(OBJS)
X	${CC} ${CFLAGS} -o  $@ ${OBJS}  ${CCLIBS}
X
Xclean:
X	rm -f dcfport.o dcf.o dcf
X
X
Xinstall:
X	strip dcf
X	chmod a+rx dcf
X	cp dcf ${DESTDIR}/dcf
X	ln ${DESTDIR}/dcf ${DESTDIR}/dcfstat
X 
END_OF_FILE
  if test 895 -ne `wc -c <'dcf/Makefile'`; then
    echo shar: \"'dcf/Makefile'\" unpacked with wrong size!
  fi
  # end of 'dcf/Makefile'
fi
if test -f 'dcf/Notes' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dcf/Notes'\"
else
  echo shar: Extracting \"'dcf/Notes'\" \(843 characters\)
  sed "s/^X//" >'dcf/Notes' <<'END_OF_FILE'
XFehlerreport dcf Version 4.1:
X
X
X
XKorrekturen dcf Version 4.1:
X
XAlle wichtigen Flags koennen auch als Kommandozeilenparameter "ubergeben
Xwerden (hilfe z.B. mit -h).
XWird das Programm als "dcfstat" aufgerufen, wird nur der SHM-Block aus-
Xgewertet (geht schneller).
XVerbesserte Methode, um das Programm in den Hintergrund zu schieben (mit dem 
XK-Parameter -b = Background).
XMit Hilfe der Datei dcf.inp kann ein Funktionstest der Software durchgefuehrt
Xwerden. Einfach "dcf.inp" als DCF-Port angeben.
X
XJetzt  auch lauffaehig unter Sun/OS (siehe hierzu README.ixos !)
X
X
XOS/2:
XAls Portname muss der entsprechende COM-Port angegeben werden.
XDa unter OS/2 die verwendete Schnittstelle nicht initialisiert wird,
Xmuss das vor dem Aufruf ueber "MODE" geschehen, z.B.: mode com1:1200,n,5,xon=on
X
X
XDas ist die absolut letzte DCF77-Treiber Version von mir.
END_OF_FILE
  if test 843 -ne `wc -c <'dcf/Notes'`; then
    echo shar: \"'dcf/Notes'\" unpacked with wrong size!
  fi
  # end of 'dcf/Notes'
fi
if test -f 'dcf/README.ixos' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dcf/README.ixos'\"
else
  echo shar: Extracting \"'dcf/README.ixos'\" \(1215 characters\)
  sed "s/^X//" >'dcf/README.ixos' <<'END_OF_FILE'
X
XDu musst in der Makefile auch -DSUN angeben (zusaetzlich zu -DSYSV).
X
XFerner MUSST Du den Kernel mit den System IPC Mechanismen konfigurieren
X(in /usr/sys/sun4c/conf/NAME):
X
X--------------------------------------------------
X#
X# The following options are for various System V IPC facilities.
X# Most standard software does not need them, although they are
X# used by SunGKS and some third-party software.
X#
Xoptions	IPCMESSAGE	# System V IPC message facility
Xoptions	IPCSEMAPHORE	# System V IPC semaphore facility
Xoptions	IPCSHMEM	# System V IPC shared-memory facility
X
X#
X--------------------------------------------------
X
XNur dann kann man das Shared Memory ansprechen.
X
XEs gibt auf der Sun Sparc keinen Game-Port. Der Empfaenger geht
Xaber auch mit einer 4,5 V Flachbatterie oder 4x1,2 Volt NiCd-Akkus.
X(Anmerkung: keine Gewaehr fuers funktionieren!)
X
XACHTUNG: ich bin auf diese Patches nicht stolz, aber es laeuft so
Xganz gut und daher mach ichs nicht cleaner.
XDas Programm ist auch kein Produkt der iXOS Software GmbH und weder die Firma
XiXOS, noch ich, uebernehmen eine Haftung.
X
XLove,
XSnoopy
Xsnoopy@munich.ixos.de
XiXOS Software GmbH
XBretonischer Ring 12
X8011 Grasbrunn
XTel. 089-46 00 5-142
XFax. 089-46 00 5-199
END_OF_FILE
  if test 1215 -ne `wc -c <'dcf/README.ixos'`; then
    echo shar: \"'dcf/README.ixos'\" unpacked with wrong size!
  fi
  # end of 'dcf/README.ixos'
fi
if test -f 'dcf/dcf.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dcf/dcf.c'\"
else
  echo shar: Extracting \"'dcf/dcf.c'\" \(18732 characters\)
  sed "s/^X//" >'dcf/dcf.c' <<'END_OF_FILE'
X/*-----------------------------------------------------------------------*/
X/*    dcf77 - Ein DCF-77 Treiberprogramm in C unter UNIX, OS/2 und DOS   */
X/*                                                  (Novell NLM a.A.)    */
X/*									 */
X/*									 */
X/*    (c) 1992 by F.Sommer						 */
X/*									 */
X/*     Verbreitung -der Originalversion- fuer NICHT-kommerzielle         */
X/*     Zwecke erwuenscht                                                 */
X/*     Verkauf durch professionelle PD-Anbieter VERBOTEN                 */
X/*     "Wer das Programm bei Computer Solutions oder sonstwo KAUFT,      */
X/*     ist selber schuld !"                                              */
X/*									 */
X/*    Meerbusch, Februar 1992    gez. Frank Sommer			 */
X/*-----------------------------------------------------------------------*/
X/*
X ifdefs SUN added for SunOS 4.1.X by Snoopy, snoopy@munich.ixos.de
X Please do not remove this comment - Franks above comments also apply
X to the SUN patches.
X
X N.B. You have to relink your SUnOS Kernel with System V IPC enabled for the
X program to work !
X June 15th, 1992
X*/
X
X#include <stdio.h>
X#include "dcfdef.h"
X#include <fcntl.h>
X#include <sys/types.h>
X
X#ifndef _OS2_
X
X#include <signal.h>
X#include <sys/ipc.h>
X#include <sys/shm.h>
X#include <sys/sem.h>        /* Semaphor-Operationen */
X#if defined (SYSV)
X#include <termio.h>
X#define TERM_CONTR struct termio dcf_termset
X#endif
X
X#define LOCK_SEMA	acc_sem.sem_op = -1; \
X		  	semop(semid,&acc_sem,1);
X
X#define REL_SEMA	acc_sem.sem_op = 1; \
X			semop(semid,&acc_sem,1)
X
XTERM_CONTR;
X#endif
X
Xchar *SCCSID = "@(#)dcf.c		4.1 92/08/30 13:23:20  by fsommer@krefcom.ish.de";
X
X
Xint dcf_fdesc;
X
Xchar programmname[20];
Xchar dcfport[20];
Xdcf_dat_t dcf_datum;
XSTATUS *status;
X
X
Xint tin[63];
Xint new_time;
X
Xint haltflag;
Xint error;
Xint error_flag = 0;
X
Xint count = 1, errcnt = 0;
X
Xint SHM_write = 0;
Xstatic int shmid;
Xstatic int semid;
Xlong shmkey;
Xlong semkey;
X
X#ifndef _OS2_
Xstatic struct sembuf acc_sem = {0,1,SEM_UNDO};
X#endif
X
Xextern void exit();
Xextern void perror();
Xextern unsigned sleep();
X
Xint  unix_time;            /* TRUE: UNIX Systemzeit setzen */
Xint  quit;		   /* TRUE: nach Empfang wird abgebrochen */
Xint  recqual;              /* TRUE: nach 6 Versuchen wird abgebrochen */
Xint  dosetclock;           /* TRUE: auch /dev/clock wird gesetzt */
Xint  plausibel ;           /* TRUE: Zeit wird auf Plausibilitaet ueberprueft*/
Xint  backgnd;              /* TRUE: Programm in den Hintergrund shiften */
Xint  debug = 0;            /* TRUE: Alle empfangenen Zeichen drucken */
Xint  statmodus = 0;        /* TRUE: dcfint */
X
X#ifndef _OS2_
X
Xvoid rel_SHMB();
Xvoid disable_dcf();
X#define PATHTERM	'/'
X			   /* Path_Terminator; normalerweise ein Slash */
X#else
X
X#define LOCK_SEMA
X#define REL_SEMA
X
X#endif
X
X
X/*-----------------------------------------------------------------------*/
Xvoid TOUThandler()
X
X{
X#ifndef _OS2_
X  fprintf(stderr,"Timeout-Fehler in Spezialdatei aufgetreten.\n");
X  fprintf(stderr,"Kein Zeitsignalempfang oder DCF-Empfaenger nicht richtig angeschlossen!\n");
X  rel_SHMB();
X  exit(100);
X#endif
X}
X
X
X/*----------------------------------------------------------------------*/
Xvoid SIGhandler(signo)      /* Zum Erkennen von Signalen  */
Xint signo;
X{
X
X#ifndef _OS2_
X int err_code;
X	rel_SHMB();
X	fprintf(stderr,"DCF-77 Treiber suspendiert.\n");
X        err_code = 64+ signo;
X	exit(err_code);
X#endif
X}
X
X/*----------------------------------------------------------------------*/
Xvoid rel_SHMB ()              /* loescht SHMB   */
X
X{
X#ifndef _OS2_
X	shmdt ((char *)status);
X	if (SHM_write)
X		{
X		shmctl (shmid,IPC_RMID,(struct shmid_ds *)0);
X		semctl (semid,0,IPC_RMID);
X		}
X#endif
X}
X
X
X/*------------------------------------------------------------------------*/
Xvoid disable_dcf()        /* schliesst den DCF-Port   */
X
X{
X	close(dcf_fdesc);
X}
X
X
X/*-----------------------------------------------------------------------*/
Xvoid dcfin()        /* liest ein Datum vom DCF-Port */
X
X{
X	char x;
X#if defined (TEST_REC)
X	signal(SIGALRM,TOUThandler);
X	alarm(60);                    /* nach 60 Sekunden Alarm ausloesen */
X#endif
X	read(dcf_fdesc, &x, 1);
X#if defined (TEST_REC)
X	alarm(0);        	/* Alarm terminieren, wenn Daten empfangen */
X#endif
X	dcf_datum.data = (int) ((x & 1));
X	dcf_datum.break_det = (int) ((x & 2) >> 1);
X        if (debug)
X         printf ("DATA: %01d    BREAK: %01d  \n",dcf_datum.data,dcf_datum.break_det);
X}
X
X
X/*-----------------------------------------------------------------------*/
Xint bcdtodec(start, ende)  /* wandelt den Bitstr. i. BCD-Zahlen */
Xint start, ende;
X
X{
X	int i, tmp = 0 ;
X
X	for (i=start;i<=ende;i++)
X	{
X		tmp += tin[i] << (i - start);
X		if (i-start > 3)
X		    tmp -=(3 * tin[i] << (i - start - 3)); 
X	}
X	return (tmp);
X}
X
X
X/*-----------------------------------------------------------------------*/
Xint parity (start, ende)   /* Berechnet die Paritaet */
Xint start, ende;
X
X{
X	int i, tmp = 0, x;
X
X	for (i=start;i<=ende;i++)
X	  tmp += tin[i];
X	x = (int) tmp % 2;
X	return(x);
X}
X
X/*--------------------------------------------------------------------*/
Xint check_date(year,month,day,hour,min) /*ueberprueft, ob Zeit plausibel ist*/
Xint year, month, day, hour, min;
X
X
X{
X   long tmpsec;
X   long faktor ();
X   int tmpstat;
X   static long lasttime = -1;
X   static int laststat = -1;
X
X   tmpstat =tin[17]+((tin[18])<<1);
X   
X   tmpsec = faktor(day,month,year) - 719528;
X   tmpsec = (tmpsec*24*60*60) + (hour*60*60) + (min*60);
X   if ((tmpsec-60 == lasttime) && (tmpstat == laststat))
X     {
X       lasttime = tmpsec;
X       laststat = tmpstat;
X       return(1);
X     }
X     else
X     {
X       lasttime = tmpsec;
X       laststat = tmpstat;
X       return(0);
X     }
X}
X
X
X/*--------------------------------------------------------------------*/
Xvoid conv_time ()   /* Konvertiert die Zeit in ein lesbares Format */
X
X{
X
Xstatic int minute_61 = 0;
Xint year, month, day, hour, min;
Xerror_flag = 0;
X
Xstatus->blocks++;
Xif ((count== 60 && !(minute_61)) || (count== 61 && (minute_61) /* && !(tin[19])*/))
X	{
X	if ((min = bcdtodec(21,27)) > 59) error_flag = 5;
X	if ((hour = bcdtodec(29,34))> 23) error_flag = 5;
X	if ((day = bcdtodec(36,41)) > 31) error_flag = 5;
X	if ((month = bcdtodec(45,49))>12) error_flag = 5;
X	year = bcdtodec(50,57) + 1900;
X	if (!tin[20])  error_flag = 5;
X	if (parity (21,27) ^ (tin[28] & 1)) error_flag = 2;
X	if (parity (29,34) ^ (tin[35] & 1)) error_flag = 2;
X	if (parity (36,57) ^ (tin[58] & 1)) error_flag = 2;
X	if (year < 1990) year += 100;
X	if (!error_flag)
X		{
X		if (check_date(year,month,day,hour,min)|| !(plausibel))
X			{ 
X			if (status->ausfall = tin[4]) error_flag = 3;
X			status->reserve = tin[15];
X			status->ankuend = tin[16];
X			status->sommert = tin[17];
X			status->wintert = tin[18];
X			status->schalts = tin[19];
X			status->wochent = bcdtodec(42,44);	
X			status->hour = hour;
X			status->min = min;
X			status->year = year;
X			status->month = month;
X			status->day = day;
X			status->valid = 1;
X			status->err_flag = 0;
X			}
X		else
X                         {
X			  error_flag = status->err_flag = 8;
X                          status->errors--;
X                         }
X		}
X	}else
X         error_flag = status->err_flag = 5;
Xif (!error_flag)  new_time = 1;
X	else
X	{
X		new_time = status->valid = 0;
X		status->errors++;
X		errcnt++;
X	}
Xstatus->err_flag = error_flag;
Xminute_61 = tin[19];
X}
X
X
X/*----------------------------------------------------------------------*/
Xvoid titelbild()     /* Druckt das Titelbild  */
X
X{
X	fprintf(stderr,"FS'  DCF-77 Dekodierung  1989-1992  fuer DOS  OS/2 und UNIX");
X	fprintf(stderr," \n");
X}
X
X
X/*----------------------------------------------------------------------*/
Xvoid setstatus ()                    /* Ausgabe aller Statusvariablen */
X
X{
Xchar wochentag[10];
X
Xprintf("\nStatus:\n");
Xswitch (status->wochent)
X	{
X	case 1 :{ 
X	         strcpy(wochentag,"Montag");
X		 break;
X		}
X	case 2 : {
X		 strcpy(wochentag,"Dienstag");
X		 break;
X		}
X	case 3 : {
X		 strcpy(wochentag,"Mittwoch");
X		 break;
X		}
X	case 4 :{
X		 strcpy(wochentag,"Donnerstag");
X		 break;
X		}
X	case 5 : {
X		 strcpy(wochentag,"Freitag");
X		 break;
X		}
X	case 6 : {
X		 strcpy(wochentag,"Samstag");
X		 break;
X		}
X	case 7 : {
X	         strcpy(wochentag,"Sonntag");
X		 break;
X		}
X	default: {
X		 strcpy(wochentag,"ungueltig");
X		 break;
X		}
X	}
X
Xprintf ("%-15s",wochentag);
Xprintf (": %02d.%02d.%04d",status->day,status->month,status->year);
Xprintf ("  %02d.%02d.%02d Uhr ME",status->hour,status->min,status->sec);
Xswitch (status->wintert)
X	{
X	case 0 : 
X	  {
X	  printf("SZ\n");
X	  break;
X	  }
X	case 1 :
X	  {
X	  printf("Z\n");
X	  break;
X	  }
X}
Xprintf ("Reserveantenne : %1d",status->reserve);
Xprintf ("  Sommerzeit   : %1d ",status->sommert);
Xprintf (" Empfangene Bloecke : %07ld\n",status->blocks);
Xprintf ("Schaltsekunde  : %1d",status->schalts);
Xprintf ("  Ankuendigung : %1d ",status->ankuend);
Xprintf (" davon fehlerhaft   : %07ld\n",status->errors);
Xif (!status->err_flag)
X  {  printf ("DCF-77 Normalzeit erkannt. ");
X     if (!quit)
X	  printf("Programm kann nun beendet werden.");
X      printf ("\n");
X  }
X}
X  
X
X/*-------------------------------------------------------------------------*/
Xvoid print_error (err)
Xint err;
X
X{
Xswitch (err)
X	{
X	case 1 :
X	  {
X	  printf ("Korrekter Programmaufruf:\n");
X	  printf ("%s -b -d -[n]i -p [name] -[n]q -[n]s \n",programmname);
X	  printf ("\n");
X
X#ifndef _OS2_
X	  printf ("             b : Programm als Hintergrund-\n");
X	  printf ("                 prozess starten\n"); 
X#endif
X
X	  printf ("             d : DEBUG-Modus \n");
X	  printf ("             i : Empfangsfehler ignorieren \n");
X	  printf ("      p [name] : DCF-IF Port\n");
X	  printf ("             q : Programm nach Zeitempfang \n");
X	  printf ("                 beenden.\n");
X	  printf ("             s : Systemzeit setzen \n");
X	  printf ("                 (nur Superuser)\n");
X	  haltflag = 1;
X	  break;
X	  }
X	case 2 :
X	  {
X	  printf ("Paritaetsfehler in den DCF-77 Daten. ");
X	  printf ("Keine gueltige Uhrzeit empfangen!\n");
X	  break;
X	  }
X	case 3:
X	  {
X	  printf ("Ausfall der Sendeanlage in Frankfurt. ");
X	  printf ("Zur Zeit ist kein DCF Empfang moeglich!\n");
X	  break;
X	  }
X	case 4:
X	  {
X	  printf ("Versuche Shared Memory Block zu lesen...\n");
X	  break;
X	  }
X	case 5:
X	  {
X	  printf ("Datenfehler in den DCF-77 Daten. Keine gueltige Uhrzeit empfangen!\n");
X	  break;
X	  }
X	case 6:
X	  {
X	  printf ("Bis zum Empfang einer korrekten Zeit koennen ");
X	  printf ("zwei Minuten vergehen!\n");
X	  break;
X	  }
X	case 7:
X 	  {
X	  printf ("Zu viele Empfangsfehler!\n");
X	  printf ("Programm wird abgebrochen. ");
X	  printf ("Keine gueltige Uhrzeit mehr empfangen.\n");
X	  haltflag = 1;
X	  break;
X	  }
X	case 8:
X	  {
X	  printf ("Plausibilitaetspruefung gescheitert. ");
X	  printf ("Keine gueltige Uhrzeit empfangen!\n");
X	  break;
X	  }
X
X	}
X}
X
X
X/*----------------------------------------------------------------------*/
Xint getparam (argc,argv)
Xint argc;
Xchar *argv[];
X
X{
X  int i= 1, s= 1;
X  int flag_no= 0;
X  char *ptr;
X  char orgptr[80];
X  char **kommandos;
X  char ezeich;
X
X  error_flag = 0;
X  strcpy(orgptr,argv[0]);
X  kommandos = (char **)malloc ((unsigned) (argc+1) *sizeof(char *));
X  kommandos[0] = malloc ((unsigned)strlen(argv[0])+1);
X  strcpy(kommandos[0],argv[0]);               /* Parameterliste aufbauen */
X  for (i=1;i<argc;i++)
X      if (strcmp(argv[i],"-b") != 0)
X       {
X        kommandos[s] = malloc ((unsigned)strlen(argv[i])+1);
X        strcpy(kommandos[s],argv[i]);
X	s++;
X       }
X     else
X#ifndef _OS2_
X        signal(SIGINT,SIG_IGN);
X#endif
X  kommandos[s] = (char *) 0;
X  s=0;
X#ifndef _OS2_
X  for (i=0;i<strlen(argv[0]);i++)       /* Programmname vom Pfad trennen */
X      {
X      if ((ezeich = orgptr[i] )!= PATHTERM )
X       {
X        programmname[s] = ezeich; s++;
X       }
X       else {
X              programmname[0] ='\0';s= 0;
X            }
X     }
X programmname[s] = '\0';
X
X#else
Xstrcpy(programmname,"dcf");    /* OS/2: Programmodus immer festgelegt */
X#endif
X
X
X  if (strcmp(programmname,"dcfstat") == 0)    /* Programmodus festlegen */
X      statmodus = 1;
X  while (--argc > 0 && (*++argv)[0] == '-')   /* Parameter auswerten */
X   { flag_no = 0;
X    for (ptr=argv[0]+1; *ptr != '\0'; ++ptr)
X    switch (*ptr) {
X    case 'n': flag_no = 1; break;
X
X#ifndef _OS2_
X    case 'b': if (flag_no) backgnd = 0; else
X			{
X                           int od, pid;
X                              {
X                               od = open("/dev/null",O_WRONLY);
X                               close(1); dup(od); close(2); dup(od);
X                               switch (pid = fork())
X                                {
X                                 case 0 : {
X                                        execvp(orgptr,kommandos);
X                                        exit(0);
X                                          }
X                                 default: exit(0);
X                               }
X                              }
X			}
X                           break;
X
X#endif
X    case 'd': if (flag_no) debug = 0; else
X                           debug = 1; break;
X    case 'i': if (flag_no) recqual = 1; else
X                           recqual = 0; break;
X    case 'q': if (flag_no) quit = 0; else
X                           quit = 1; break;
X    case 's': if (flag_no) unix_time = 0; else
X                           unix_time = 1; break;
X    case 'p': { strcpy(dcfport,*++argv); break;} 
X    default: error_flag = 1;
X   }
X }
Xreturn (error_flag);
X}
X
X
X/*---------------------------------------------------------------------------*/
Xlong faktor(tag,monat,jahr)    /* ber. den char. Faktor fuer ein best. Datum */
Xint tag, monat, jahr;
X
X{
X  long tmp;
X  if (monat <3)
X   tmp= 365*jahr+tag+31*(monat-1)+((jahr-1)/4)-((3*((jahr-1)/100)/4)+1);
X  else
X   tmp= 365*jahr+tag+31*(monat-1)-((monat*4+23)/10)+(jahr/4)-((3*(jahr/100)/4)+1);
Xreturn (tmp);
X}
X
X/*----------------------------------------------------------------------*/
Xvoid dcf_evalshmb ()
X
X{
X#ifndef _OS2_
Xint tmpsec = 0;
X
Xif ((shmid = shmget ((key_t) shmkey,sizeof(STATUS),0))==-1)
X        {
X        fprintf(stderr,"Fehler beim Suchen des SHMB!\n");
X	exit(60);
X	}
Xif ((semid= semget((key_t)shmkey,1,0)) == -1)
X	{
X	fprintf(stderr,"Fehler beim Zuordnen der Semaphor!\n");
X	}
Xif ((status = (STATUS *) shmat(shmid,(char*)0,SHM_RDONLY))== (STATUS *) -1)
X	{
X	fprintf(stderr,"Kann SHMB nicht allokieren!\n");
X	}
X	else
X	do
X	        {
X		LOCK_SEMA;
X		while ((tmpsec == status->sec))
X		 	{
X			REL_SEMA;
X			sleep(1);
X		 	if ((shmid= shmget((key_t)shmkey,sizeof(STATUS),0))==-1)
X				{
Xfprintf(stderr,"SHMB wurde vom DCF-Server geloescht! Programm abgebrochen.\n");
X				exit(50);
X				}
X			LOCK_SEMA;
X			}
X		if (!status->valid)
X			{
X			print_error(status->err_flag);
X			while (!status->valid)
X				{
X				REL_SEMA;
X				sleep(60);
X		 	if((shmid=shmget((key_t)shmkey,sizeof(STATUS),0))==-1)
X					{
Xfprintf(stderr,"SHMB wurde vom DCF-Server geloescht! Programm abgebrochen.\n");
X					exit(50);
X					}
X				LOCK_SEMA;
X				print_error(status->err_flag);
X				}
X			}
X		tmpsec = status->sec;
X	 	setstatus();
X		REL_SEMA;
X		}
X		while (!haltflag);
X
X#endif
X}
X
X
X/*----------------------------------------------------------------------*/
Xvoid stat_evalshmb ()
X
X{
X#ifndef _OS2_
Xint tmpsec = 0;
X
Xif ((shmid = shmget ((key_t) shmkey,sizeof(STATUS),0))==-1)
X        {
X        fprintf(stderr,"Fehler beim Suchen des SHMB!\n");
X	exit(60);
X	}
Xif ((semid= semget((key_t)shmkey,1,0)) == -1)
X	{
X	fprintf(stderr,"Fehler beim Zuordnen der Semaphor!\n");
X	}
Xif ((status = (STATUS *) shmat(shmid,(char*)0,SHM_RDONLY))== (STATUS *) -1)
X	{
X	fprintf(stderr,"Kann SHMB nicht allokieren!\n");
X	}
X	else
X	        {
X		LOCK_SEMA;
X	 	if((shmid=shmget((key_t)shmkey,sizeof(STATUS),0))==-1)
X				{
Xfprintf(stderr,"SHMB wurde vom DCF-Server geloescht! Programm abgebrochen.\n");
X				exit(50);
X				}
X	 	setstatus();
X		print_error(status->err_flag);
X                error_flag = status->err_flag;
X		REL_SEMA;
X		}
X#endif    /* not for _OS2_ */
X}
X
X
X
X/*-----------------------------------------------------------------------*/
Xvoid break_occur ()       /* Aktionen,  wenn ein Break auftrat */
X
X{
Xextern int quit;
Xextern void exec_date_command ();
X
X	LOCK_SEMA;
X	conv_time();
X	status->sec =0;
X	count = 1;
X	if (error_flag == 0)
X		{
X		setstatus();
X		errcnt = 0;
X		if (unix_time)
X        	exec_date_command();
X		if (quit) haltflag = 1;
X		}
X	else
X		print_error(error_flag);
X	REL_SEMA;
X}
X
X/*----------------------------------------------------------------------*/
Xvoid alloc_shmb ()   /* Allokierung SHMB */
X
X{
X#ifndef _OS2_
Xif ((shmid=shmget((key_t)shmkey,sizeof(STATUS),IPC_CREAT|IPC_EXCL|SHMMODE)) == -1)
X	fprintf(stderr," WARNUNG1! Kann Shared Memory nicht erstellen !\n");
Xstatus = (STATUS *)shmat(shmid,(char*)0,0);
Xif ((semid=semget((key_t)shmkey,1,IPC_CREAT|IPC_EXCL|SEMMODE)) == -1)
X	fprintf(stderr," WARNUNG! Kann Semaphor nicht einrichten !\n");
X	else
X	REL_SEMA;
XSHM_write = 1;
X#else
Xstatus = (STATUS *)malloc (sizeof(STATUS));  /* Nur bei OS/2 */
X#endif
X}
X
X/*----------------------------------------------------------------------*/
Xvoid read_time ()  /*liest die Uhrzeit und schreibt den SHMB */
X
X  {
X
X    int tmp_ank;
X    print_error(6);
X    count= 1;
X    LOCK_SEMA;
X    status->err_flag = 6;
X    status->blocks = status->errors = status->valid = tmp_ank = 0;
X    REL_SEMA;
X    while ((haltflag == 0) || (tmp_ank))
X	{
X	error = 0;
X	dcfin();
X	tin[count] = dcf_datum.data;
X	count++;
X	LOCK_SEMA;
X	status->sec++;
X	REL_SEMA;
X	if (dcf_datum.break_det == 1)
X		{
X		break_occur();
X		LOCK_SEMA;
X		tmp_ank = status->ankuend;
X		REL_SEMA;
X		}
X	if (count > 61)
X		{
X		print_error(5);
X		errcnt++;
X		LOCK_SEMA;
X		status->valid = status->sec = 0;
X		REL_SEMA;
X		count = 1;
X		}
X	if ((errcnt >6) && (recqual))
X	{
X	print_error(7);
X	haltflag =1;
X	}
X}
Xdisable_dcf();
X
X}
X
X
X/*----------------------------------------------------------------------*/
Xmain (argc,argv)
Xint argc;
Xchar  *argv[];
X
X{
Xextern int enable_dcf();
Xextern void dcf_init();
X
X#ifndef  _OS2_
X signal (SIGHUP,SIG_IGN);
X signal (SIGQUIT,SIG_IGN);
X signal (SIGTERM,SIGhandler);
X signal (SIGKILL,SIGhandler);
X signal (SIGINT,SIGhandler);
X#endif
X
X titelbild();
X fprintf(stderr,"Version:%s\n",SCCSID);
X dcf_init();
X
X
X if (!getparam(argc,argv) && (strcmp(programmname,"dcf") == 0) || (strcmp(programmname,"dcfstat") == 0))
X {
X#ifdef TEST
X         printf("Portname: %s\n",dcfport);
X#endif
X   if (enable_dcf()&& (!statmodus))
X	{
X         alloc_shmb ();
X	 if (error_flag > 0 )
X		  print_error(error_flag);
X		  else
X		  {
X#ifdef TEST_OS2
X		  printf ("Nun Zeit ermitteln.\n");
X#endif
X		  read_time();
X		  }
X	}
X	else
X	{
X	 if (!statmodus) fprintf(stderr,"Fehler beim Oeffnen der Spezialdatei!\n");
X	 print_error(4);
X	 if (statmodus) stat_evalshmb();
X         else dcf_evalshmb();
X	}
X rel_SHMB();
X }
X else print_error(error_flag);
X exit(error_flag);
X}
END_OF_FILE
  if test 18732 -ne `wc -c <'dcf/dcf.c'`; then
    echo shar: \"'dcf/dcf.c'\" unpacked with wrong size!
  fi
  # end of 'dcf/dcf.c'
fi
if test -f 'dcf/dcf.inp' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dcf/dcf.inp'\"
else
  echo shar: Extracting \"'dcf/dcf.inp'\" \(0 characters\)
  sed "s/^X//" >'dcf/dcf.inp' <<'END_OF_FILE'
END_OF_FILE
  if test 0 -ne `wc -c <'dcf/dcf.inp'`; then
    echo shar: \"'dcf/dcf.inp'\" unpacked with wrong size!
  fi
  # end of 'dcf/dcf.inp'
fi
if test -f 'dcf/dcf.rel' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dcf/dcf.rel'\"
else
  echo shar: Extracting \"'dcf/dcf.rel'\" \(4303 characters\)
  sed "s/^X//" >'dcf/dcf.rel' <<'END_OF_FILE'
Xs.dcf.c:
X
XD 3.3.1.7 92/06/01 21:09:28 fso 45 44	00184/00049/00547
XMRs:
XCOMMENTS:
XKommandozeilenparameter ergaenzt
X
XD 3.3.1.6 92/04/11 20:22:51 fso 44 42	00012/00006/00584
XMRs:
XCOMMENTS:
XZeitzone korrigiert
X
XD 3.6 92/02/20 12:26:19 fso 43 41	00008/00001/00543
XMRs:
XCOMMENTS:
Xstruct termio in dcf.c ergaenzt (fuer XENIX)
X
XD 3.3.1.5 92/02/20 12:15:09 fso 42 40	00006/00000/00584
XMRs:
XCOMMENTS:
Xstruct termio... in dcf.c ergaenzt (fuer XENIX)
X
XD 3.5 92/02/18 18:38:17 fso 41 37	00002/00002/00542
XMRs:
XCOMMENTS:
XUltimative PD-Version
X
XD 3.3.1.4 92/02/18 18:30:05 fso 40 39	00000/00000/00584
XMRs:
XCOMMENTS:
X*status Variablendeklaration
X
XD 3.3.1.3 92/02/18 18:24:02 fso 39 38	00002/00002/00582
XMRs:
XCOMMENTS:
XVariablendeklaration
X
XD 3.3.1.2 92/02/18 16:22:24 fso 38 36	00014/00013/00570
XMRs:
XCOMMENTS:
XJR Koorekturen ?
X
XD 3.4 92/02/15 20:25:47 fso 37 35	00013/00013/00531
XMRs:
XCOMMENTS:
X?? Fehlermeldung von JR
X
XD 3.3.1.1 92/02/13 23:04:00 fso 36 35	00046/00007/00537
XMRs:
XCOMMENTS:
XSemaphor eingebaut
X
XD 3.3 92/02/12 16:43:27 fso 35 34	00001/00001/00543
XMRs:
XCOMMENTS:
Xexec_setclock geaendert
X
XD 3.2 92/02/12 14:25:09 fso 34 33	00016/00018/00528
XMRs:
XCOMMENTS:
XFehler in der faktor()-Brechnung behoben
X
XD 3.1 92/02/07 11:26:56 fso 33 32	00019/00009/00527
XMRs:
XCOMMENTS:
Xultimative PD-Version
X
XD 2.15 92/02/06 23:17:44 fso 32 31	00118/00189/00418
XMRs:
XCOMMENTS:
XPD-Version
X
XD 2.14 92/02/02 16:36:57 fso 31 30	00007/00008/00600
XMRs:
XCOMMENTS:
X
X
XD 2.13 92/02/02 14:24:20 fso 30 29	00076/00034/00532
XMRs:
XCOMMENTS:
XStatus ergaenzt
X
XD 2.12 92/02/01 19:42:49 fso 29 28	00007/00008/00559
XMRs:
XCOMMENTS:
XSHMB-Kommunikation korrigiert
X
XD 2.11 92/02/01 15:19:59 fso 28 27	00046/00042/00521
XMRs:
XCOMMENTS:
Xmain() umgebaut
X
XD 2.10 92/02/01 12:57:15 fso 27 26	00004/00023/00559
XMRs:
XCOMMENTS:
Xenable_dcf() versetzt
X
XD 2.9 92/02/01 12:18:36 fso 26 25	00007/00006/00575
XMRs:
XCOMMENTS:
XFehler im SHMB-Allokierung behoben
X
XD 2.8 92/02/01 11:56:18 fso 25 24	00000/00000/00581
XMRs:
XCOMMENTS:
X
X
XD 2.7 92/02/01 11:48:30 fso 24 23	00074/00032/00507
XMRs:
XCOMMENTS:
Xstatische Variablen entfernt
X
XD 2.6 92/01/31 22:22:58 fso 23 22	00042/00041/00497
XMRs:
XCOMMENTS:
Xdate und setclock ausgebaut, stime eingebaut.
X
XD 2.5 92/01/27 19:39:29 fso 22 21	00001/00001/00537
XMRs:
XCOMMENTS:
XStatus; volatile-Variable
X
XD 2.4 92/01/25 00:04:16 fso 21 20	00002/00002/00536
XMRs:
XCOMMENTS:
XBaudrate via define einstellbar
X
XD 2.3 92/01/18 21:56:46 fso 20 19	00001/00001/00537
XMRs:
XCOMMENTS:
XStatusausgabe geaendert
X
XD 2.2 92/01/18 21:27:27 fso 19 12	00087/00056/00451
XMRs:
XCOMMENTS:
XAn neues IF angepasst, nice() audgebaut, Schaltsekunde wird bearbeitet
X
XD 2.1.1.5 91/12/29 12:07:01 fso 18 17	00002/00001/00536
XMRs:
XCOMMENTS:
X
X
XD 2.1.1.4 91/12/29 12:00:36 fso 17 16	00002/00002/00535
XMRs:
XCOMMENTS:
X
X
XD 2.1.1.3 91/12/29 11:58:09 fso 16 15	00000/00000/00537
XMRs:
XCOMMENTS:
X
X
XD 2.1.1.2 91/12/29 11:56:32 fso 15 14	00012/00004/00525
XMRs:
XCOMMENTS:
XAerger mit utmp (wahrscheinlich) beseitigt
X
XD 2.1.1.1 91/12/28 21:51:33 fso 14 12	00065/00043/00464
XMRs:
XCOMMENTS:
XErrorlevel ergaenzt, diverse Verbesserungen
X
XD 2.1.1.0 91/12/28 18:25:04 fso 13 12	00006/00006/00501
XMRs:
XCOMMENTS:
Xdeutsche Umlaute entfernt
X
XD 2.1 91/12/28 18:01:58 fso 12 11	00005/00000/00502
XMRs:
XCOMMENTS:
XSHMB Allokation in eval_shmb korrigiert
X
XD 1.11 91/12/27 23:38:32 fso 11 10	00000/00000/00502
XMRs:
XCOMMENTS:
X
X
XD 1.10 91/12/27 23:33:54 fso 10 9	00005/00005/00497
XMRs:
XCOMMENTS:
XProgramm laeuft mit 20 "geniced"
X
XD 1.9 91/12/27 23:11:59 fso 9 8	00012/00009/00490
XMRs:
XCOMMENTS:
Xtitelbild()-Aufruf versetzt, sonst kein Datenempfang.
X
XD 1.8 91/12/27 22:12:59 fso 8 7	00001/00002/00498
XMRs:
XCOMMENTS:
XVerschoenerungen
X
XD 1.7 91/12/27 22:00:29 fso 7 6	00004/00004/00496
XMRs:
XCOMMENTS:
X
X
XD 1.6 91/12/27 21:49:48 fso 6 5	00001/00001/00499
XMRs:
XCOMMENTS:
X
X
XD 1.5 91/12/27 21:45:50 fso 5 4	00000/00000/00500
XMRs:
XCOMMENTS:
X
X
XD 1.4 91/12/27 21:43:36 fso 4 3	00004/00005/00496
XMRs:
XCOMMENTS:
XReleasenummer wird beim Start mit ausgedruckt
X
XD 1.3 91/12/27 21:20:45 fso 3 2	00011/00010/00490
XMRs:
XCOMMENTS:
XReleaselevel wird beim Starten mit ausgedruckt
X
XD 1.2 91/12/27 21:09:11 fso 2 1	00000/00000/00500
XMRs:
XCOMMENTS:
XErste wirklich brauchbare Version. Unnoetige Includs geloescht
X
XD 1.1 91/12/27 21:07:16 fso 1 0	00500/00000/00000
XMRs:
XCOMMENTS:
Xdate and time created 91/12/27 21:07:16 by fso
X
END_OF_FILE
  if test 4303 -ne `wc -c <'dcf/dcf.rel'`; then
    echo shar: \"'dcf/dcf.rel'\" unpacked with wrong size!
  fi
  # end of 'dcf/dcf.rel'
fi
if test -f 'dcf/dcfdef.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dcf/dcfdef.h'\"
else
  echo shar: Extracting \"'dcf/dcfdef.h'\" \(401 characters\)
  sed "s/^X//" >'dcf/dcfdef.h' <<'END_OF_FILE'
X#define SHMMODE	0644
X#define SEMMODE 0666
X#define STATUS struct status
X
Xtypedef struct	{
X		char break_det;
X		char data;
X		} dcf_dat_t;
X
XSTATUS 	{
X	int ausfall;
X	int reserve;
X	int ankuend;
X	int sommert;
X	int wintert;
X	int schalts;
X        int wochent;
X	int year;
X	int month;
X	int day;
X	int hour;
X	int min;
X	int sec ; 
X	int valid ;
X	int err_flag;	
X	unsigned long blocks ;
X	unsigned long errors ;
X	} ;
X
X
END_OF_FILE
  if test 401 -ne `wc -c <'dcf/dcfdef.h'`; then
    echo shar: \"'dcf/dcfdef.h'\" unpacked with wrong size!
  fi
  # end of 'dcf/dcfdef.h'
fi
if test -f 'dcf/dcfdoc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dcf/dcfdoc'\"
else
  echo shar: Extracting \"'dcf/dcfdoc'\" \(5168 characters\)
  sed "s/^X//" >'dcf/dcfdoc' <<'END_OF_FILE'
Xdcf: Ein DCF-77 Treiberprogramm in C  fuer  UNIX und OS/2.
X
Xbenoetigte Hardware: 	DCF-77 Empfaengermodul mit seriellem Ausgang.
X			(Bezugsquellennachweis: siehe unten).
X			Serielle Schnittstelle
X			C-Compiler
X
XUnterstuetzte Systeme:  Alle Standard Unix-Systeme, sowie OS/2. Es muessen die
X			folgenden include-Dateien vorhanden sein: 
X                        shm.h, ipc.h, fcntl.h, termio.h (jedoch nicht bei OS/2).
X
X			Das Programm wurde getestet unter: SCO-UNIX/386 und
X			SCO-XENIX/386, Sun/OS (siehe README.ixos)
X			und OS/2 2.0.
X
XFeatures:		Das Serverprogramm unterstuetzt einen Shared-Memory-
X			-Block, der auch von anderen Programmen ausgewertet
X			werden kann (nicht bei OS/2).
X			Umfangreiche Ueberpruefungen stellen sicher, dass die
X			empfangene Uhrzeit auch wirklich korrekt ist. Somit
X			ist die Gefahr falscher Uhrzeiteinstellung,aufgrund 
X			von Empfangsfehlern, aeusserst unwahrscheinlich.
X			Aufgrund der Hardwarekonzeption ist KEIN Echtzeit-
X			betriebssystem zum Empfang der Uhrzeit noetig. 
X			Die Systembelastung durch das Programm ist sehr
X			gering.
X
X
X
X
X2.0 Anleitung
X
X2.1 Portierung
X
XAlle besonderen Compilerschalter sind in der Datei dcfport.c erklaert.
XIn dieser Datei befinden sich auch die Funktionen zur Initialisierung
Xdes gewuenschten Port.
X
XUm zu pruefen, ob alles soweit funktioniert, kann als dcfport die Datei 
X"dcf.inp" angegeben werden. Es werden dann die aufgezeichenten Daten
Xausgewertet. Natuerlich stimmt die Uhrzeit nicht mehr!.     
X
X
X2.2 Bedienung
X
X
X"dcf" kann sowohl im Vordergrund als auch im Hintergrund laufen.
XSoll das Programm keine Bildschirmausgaben machen, so sind diese in die
XDatei /dev/null umzulenken. Wenn dcf das erstemal aufgerufen wird, versucht
Xes einen SHM einzurichten, und schreibt alle Statusaenderungen in diesen
XSpeicherbereich. Es fungiert somit als "Serverprogramm". Sollte nun ein 
Xanderer Prozess auch dcf aufrufen, so versucht dieser Prozess nicht auch 
Xnoch den DCF-Port zu lesen, sondern wertet nur den SHMB-Block aus. 
XSomit kann das Programm von mehreren Benutzern gleichzeitig aufgerufen werden.
X(Bei OS/2 kein SHMB!).
X
X2.3 Systemsicherheit
X
XDas Programm fuehrt umfangreiche Pruefungen durch, bevor die Systemzeit 
Xwirklich geaendert wird. Als erstes wird geprueft, ob alle Daten ihren Werte-
Xbereich nicht ueberschreiten, d.h. dass die Stunden nicht groesser als 23 sein
Xduerfen, oder das die Minuten nicht groesser als 59 sein koennen.
XDann werden auch noch die mitgesendeten Paritaetsbits geprueft. 
XZum Schluss wird kontrolliert, ob die empfangene Zeit um genau 60
XSekunden groesser ist als die letzte. Wenn das nicht der Fall ist, wird 
Xebenfalls die Uhrzeit nicht geaendert. 
XSollte aus irgendeinem Grund der DCF-Empfaenger ausfallen, so wird nach 60 
XSekunden ein Timeout generiert, und das Programm mit einem bestimmten Fehler-
X-code abgebrochen. Ein Shellscript kann dann an den Systemverwalter eine
XMail senden, und z.B. via "at" den Server fuer einen spaeteren Zeitpunkt
Xwieder einplanen.
X
X 
X
X
X
X
X
X4 Verschiedenes
X
X4.1 Bezugsquelle fuer den DCF-77 Empfaengermodul
X
XEin kompletter DCF-77 Empfaengermodul passend zur Software ist beim
XAutor erhaeltlich. Der Modul wird an ueber eine DB-25 Buchse an eine
Xserielle Schnittstelle angeschlossen. Es werden keine besonderen Handshake-
Xleitungen unterstuetzt. Lediglich Pin 3 (RxD) und Pin 7 (Gnd) werden
Xverschaltet. Zur Spannungsversorgung reichen 5V, max. Stromaufnahme 100mA.
XBei PCs koennen die 5V z. B. vom Gameport abgegriffen werden. Das Modul wird 
Xzu diesem Zweck mit einem 15 pol. DB Stecker ausgeliefert, der direkt auf den
XGameport aufgesteckt werden kann.
XAus Kostengruenden arbeitet das Interface nicht mit dem "echten" RS 232 Pegel,
Xsondern nur mit den Spannungen 0V fuer High und 5V fuer Low . Das sollte aber
Xkein Problem sein, weil saemtliche untersuchte Schnittstellen mit 0V, anstatt
X-3V, fuer High auskommen. Auf Anfrage ist aber auch ein Konverter lieferbar.
X
X
XDer Preis (Stand April 1992): 190 DM incl. MwSt und Versand.
XBestellungen bitte nur schriftlich an meine Privatadresse.
XDafuer aber auch keine Nachnahmesendung!
X
XWer sich jedoch ein Interface selbst basteln will, erhaelt gegen Einsendung
Xeines V-Schecks ueber 30 DM einen Schaltplan (nicht PD!) und ein  programmiertes
XGAL.
X
X
XBezugsquelle
X
XFrank Sommer
XMuehlenfeld 6
X
XD-W4005 Meerbusch 2
XTel.: 02159-50072
XeMail: fsommer@krefcom.ish.de
X
X
X
X4.2 Datenformat des Empfaengermoduls und Aufbau des SHMB
X
X
XAufbau der SHMB-Struktur:
X (0 = FALSE)
X
XSTATUS 	{
X	int ausfall;
X	int reserve;
X	int ankuend;
X	int sommert;
X	int wintert;
X	int schalts;
X        int wochent;
X	int year;
X	int month;
X	int day;
X	int hour;
X	int min;
X	int sec; 
X	int valid;
X	int error_flag;	
X	unsigned long blocks;
X	unsigned long errors;
X	} ;
X
X
X
XFormat des empfangenen Datenblocks:
X
XBit             Bedeutung
X
X0		DATA  : 0 = LOW, 1 = HIGH
X1		BREAK : 0 = kein Break aufgetreten, 1 = Break aufgetreten
X
XAlle anderen Bits sind ungueltig!
X
XBrauchbare Uebertragungsparameter:
X
X1200 Baud, 5 Datenbit, 1 Stoppbit, keine Paritaet.
X
X
X
X
X
X
X
X
XWer das Programm brauchbar findet, kann gerne einen Anerkennungsbeitrag
Xauf mein u.a. Konto ueberweisen:
X
XVolksbank Meerbusch eG BLZ 370691 64 (74587) Frank Sommer
X
X
END_OF_FILE
  if test 5168 -ne `wc -c <'dcf/dcfdoc'`; then
    echo shar: \"'dcf/dcfdoc'\" unpacked with wrong size!
  fi
  # end of 'dcf/dcfdoc'
fi
if test -f 'dcf/dcfport.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dcf/dcfport.c'\"
else
  echo shar: Extracting \"'dcf/dcfport.c'\" \(5485 characters\)
  sed "s/^X//" >'dcf/dcfport.c' <<'END_OF_FILE'
X#define PORTNAME  "/dev/dcfport"    
X#define SHMEMKEY 123456789
X#undef EMPFANGSABBRUCH       
X#undef DAUEREMPFANG  
X#define EXECSETCLOCK
X#define DATECHECK	
X#define BAUDRATE B1200
X#undef SETUNIXTIME
X/*--------------------------------------------------------------------*/
X/*   PORTNAME = gewuenschter Port  (max. 20 Zeichen, kompletter Pfad) */
X/*   kann auch als K-Parameter angegeben werden.                      */
X/*   SHMEMKEY = gewuenschter SHARED-MEMORY KEY (long int)             */
X/*   DAUEREMPFANG loeschen, wenn Programm nach 1. Synchronisation     */
X/*   beendet werden soll.                                             */ 
X/*   EMPFANGSABBRUCH definieren, wenn Programm nach 6 Empfangsfehlern */
X/*   beendet werden soll.					      */
X/*   EXECSETCLOCK definieren, wenn zusaetzlich zum date-Kommando      */
X/*   auch die Real-Time Clock (SCO) gesetzt werden soll.              */
X/*   DATECHECK definieren, wenn die Uhrzeit auf Plausibilitaet        */
X/*   ueberprueft werden soll.                                         */
X/*   BAUDRATE mit der Baudrate der verwendeten Schnittstelle besetzen.*/
X/*   Moegliche Werte sind: B1200, B2400 B4800, B9600                  */
X/*   SETUNIXTIME setzen, wenn die Systemzeit defaultmaessig           */
X/*   gesetzt werden soll.                                             */
X/*								      */
X/*   Alle wichtigen Parameter koennen auch ueber die Kommandozeile    */
X/*   definiert werden!						      */
X/*--------------------------------------------------------------------*/
X#if defined (DAUEREMPFANG)
X#define DAUEREMPFANG 0
X#else
X#define DAUEREMPFANG 1
X#endif
X#if defined (EMPFANGSABBRUCH)
X#define EMPFANGSABBRUCH 1
X#else
X#define EMPFANGSABBRUCH 0
X#endif
X#if defined (EXECSETCLOCK)
X#define EXECSETCLOCK 1
X#else
X#define EXECSETCLOCK 0
X#endif
X#if defined (DATECHECK)
X#define DATECHECK 1
X#else
X#define DATECHECK 0
X#endif
X#if defined (SETUNIXTIME)
X#define SETUNIXTIME 1
X#else
X#define SETUNIXTIME 0
X#endif
X/*
XSUN patches added by Snoopy, snoopy@munich.ixos.de
XJune 15th, 1992
X
XFranks comments apply to my patches as well. Please do not remove this
Xnotice
X*/
X
X#ifdef SUN
X#include <sys/stdtypes.h>
X#include <sys/types.h>
X#include <sys/time.h>
X#endif
X
X#ifdef _OS2_
X#include <doscalls.h> 
X#endif
X
X/*************************************************************************/
X#include <stdio.h>
X#include "dcfdef.h"
X
X
X
Xvoid dcf_init ()   /*  Initialisierungen */
X{
X  extern char dcfport[];
X  extern int  recqual;
X  extern int  dosetclock;
X  extern int quit; 
X  extern int plausibel;
X  extern long shmkey;
X  extern int unix_time;
X
X  char *SCCSID = "@(#)dcfport.c	4.1 92/08/30 13:23:20  by fsommer@krefcom.ish.de";
X  quit = DAUEREMPFANG;
X  recqual = EMPFANGSABBRUCH;
X  dosetclock = EXECSETCLOCK;
X  plausibel = DATECHECK;
X  shmkey = SHMEMKEY;
X  unix_time = SETUNIXTIME;
X  strcpy(dcfport,PORTNAME);
X}
X
X
X/*----------------------------------------------------------------------*/
Xint enable_dcf ()           /* Initialisiert den DCF-Port */
X
X{
X#include <sys/types.h>
X#include <fcntl.h>
X
X#ifndef _OS2_
X#include <termio.h>
X  extern struct termio dcf_termset;
X#endif
X
Xextern int dcf_fdesc;
Xextern char dcfport[];
X
X  if ((dcf_fdesc = open(dcfport,O_EXCL|O_RDONLY)) == -1)
X	return(0);
X#ifndef _OS2_
X#ifdef SET_TERM_PAR
X  dcf_termset.c_cflag = BAUDRATE|CS5|CREAD|CLOCAL|HUPCL;
X  dcf_termset.c_cc[VMIN] =1;
X  dcf_termset.c_oflag = 0;
X  dcf_termset.c_cc[VTIME]= 0;
X  dcf_termset.c_line = 0;
X  ioctl (dcf_fdesc, TCSETA, &dcf_termset);
X#endif
X#endif
X#ifdef TEST_OS2
X    printf ("Port Init OK.\n");
X#endif
X  return (1);
X}
X/*------------------------------------------------------------------------*/
Xvoid exec_date_command ()     /*setzt die Systemzeit und Echtzeituhr */
X
X{
X#include <sys/types.h> 
X#ifdef SUN
Xstruct timeval now;
Xstruct timezone zone;
X#endif
X
X extern int dosetclock;
X extern long faktor();
X extern STATUS *status;
X
X int fstatus;
X long days_s_unix;
X long secs_s_unix;
X 
X 
X days_s_unix = faktor(status->day,status->month,status->year) - 719528;
X secs_s_unix =(days_s_unix*24*60*60)+(status->hour*60*60)+(status->min*60)- ((1 + status->sommert) * 3600);
X
X#ifdef SUN
X	fstatus = gettimeofday(&now, &zone);
X	if (fstatus == 0) {
X		now.tv_sec = secs_s_unix;
X		now.tv_usec = 0;
X		fstatus = settimeofday(&now, &zone);
X	};
X#endif
X 
X#ifdef SYSV
Xif ((fstatus = stime(&secs_s_unix)) == -1)
X     printf("Keine Berechtigung zum Setzen der Systemuhr! \n");
X if (dosetclock)
X	{ int dev_desc;
X	  if ((dev_desc = open("/dev/clock",O_RDWR|O_EXCL|O_NDELAY)) == -1)
X            printf("Keine Berechtigung zum Setzen der Echtzeituhr! \n");
X          else
X	  {
X           char timestr[11];
X           sprintf(timestr,"%02d%02d%02d%02d%02d",status->month,status->day,(status->hour),status->min,status->year-1900); 
X	   write(dev_desc,timestr,11); 
X	   close (dev_desc);
X	  }
X	};
X#endif
X;
X#ifdef _OS2_
X{
Xextern unsigned far pascal DOSSETDATETIME (struct DateTime far *);
Xstruct DateTime os2_time_record;
X
X	{
X	 os2_time_record.hour = status->hour;
X         os2_time_record.minutes = status->min;
X         os2_time_record.seconds = status->sec;
X         os2_time_record.hundredths = 10;
X         os2_time_record.day = status->day;
X         os2_time_record.month = status->month;
X	 os2_time_record.year = status->year;        
X	 os2_time_record.timezone = (status->sommert+1) * 60; 
X	 os2_time_record.day_of_week = status->wochent;    
X 	 DOSSETDATETIME(&os2_time_record);	
X	}
X}
X#endif
X}
X
X/*--------------------------------------------------------------------------*/
END_OF_FILE
  if test 5485 -ne `wc -c <'dcf/dcfport.c'`; then
    echo shar: \"'dcf/dcfport.c'\" unpacked with wrong size!
  fi
  # end of 'dcf/dcfport.c'
fi
if test -f 'dcf/dcfport.rel' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dcf/dcfport.rel'\"
else
  echo shar: Extracting \"'dcf/dcfport.rel'\" \(1496 characters\)
  sed "s/^X//" >'dcf/dcfport.rel' <<'END_OF_FILE'
Xs.dcfport.c:
X
XD 1.16 92/06/01 21:09:30 fso 16 15	00014/00004/00119
XMRs:
XCOMMENTS:
XKommandozeilenparameter ergaenzt
X
XD 1.15 92/04/11 23:53:58 fso 15 14	00001/00001/00122
XMRs:
XCOMMENTS:
XGMT Korrekturfaktor geaendert
X
XD 1.14 92/04/11 20:22:52 fso 14 13	00001/00001/00122
XMRs:
XCOMMENTS:
XZeitzone korrigiert
X
XD 1.13 92/02/20 12:26:20 fso 13 12	00001/00002/00122
XMRs:
XCOMMENTS:
Xstruct termio in dcf.c ergaenzt (fuer XENIX)
X
XD 1.12 92/02/20 12:17:18 fso 12 11	00001/00001/00123
XMRs:
XCOMMENTS:
Xextern struct termio ergaenzt (fuer XENIX)
X
XD 1.11 92/02/18 18:24:04 fso 11 10	00002/00002/00122
XMRs:
XCOMMENTS:
XVariablendeklaration
X
XD 1.10 92/02/15 20:25:49 fso 10 9	00002/00002/00122
XMRs:
XCOMMENTS:
X?? Fehlermeldung von JR
X
XD 1.9 92/02/12 16:43:28 fso 9 8	00001/00001/00123
XMRs:
XCOMMENTS:
Xexec_setclock geaendert
X
XD 1.8 92/02/06 23:17:46 fso 8 7	00047/00006/00077
XMRs:
XCOMMENTS:
XPD-Version
X
XD 1.7 92/02/01 12:57:17 fso 7 6	00026/00002/00057
XMRs:
XCOMMENTS:
Xenable_dcf() versetzt
X
XD 1.6 92/02/01 12:18:58 fso 6 5	00001/00001/00058
XMRs:
XCOMMENTS:
XFehler im SHMB-Allokierung behoben
X
XD 1.5 92/02/01 11:48:09 fso 5 4	00037/00021/00022
XMRs:
XCOMMENTS:
XCHECKDATE hinzugefuegt
X
XD 1.4 91/12/28 21:52:04 fso 4 3	00021/00001/00022
XMRs:
XCOMMENTS:
Xweitere defined-Variablen
X
XD 1.3 91/12/27 23:12:12 fso 3 2	00001/00001/00022
XMRs:
XCOMMENTS:
X
X
XD 1.2 91/12/27 22:11:46 fso 2 1	00000/00000/00023
XMRs:
XCOMMENTS:
X
X
XD 1.1 91/12/27 22:07:51 fso 1 0	00023/00000/00000
XMRs:
XCOMMENTS:
Xdate and time created 91/12/27 22:07:51 by fso
X
END_OF_FILE
  if test 1496 -ne `wc -c <'dcf/dcfport.rel'`; then
    echo shar: \"'dcf/dcfport.rel'\" unpacked with wrong size!
  fi
  # end of 'dcf/dcfport.rel'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have the archive.
    rm -f ark[1-9]isdone
else
    echo You still must unpack the following archives:
    echo "        " ${MISSING}
fi
exit 0