1From tmpuhf.saar.de!wg.saar.de!stone!kammer Fri Oct 21 15:19:02 1994
2Return-Path: <@tmpuhf.saar.de:stone!kammer@wg.saar.de>
3Received: by greenie.muc.de (/\==/\ Smail3.1.24.1 #24.2)
4	id <m0qyKo1-0001peC@greenie.muc.de>; Fri, 21 Oct 94 15:18 MET
5Received: from shug-internet.saar.de ([192.109.53.4]) by colin.muc.de with SMTP id <25571(1)>; Fri, 21 Oct 1994 15:18:33 +0100
6Received: from TMPuhf.Saar.DE (tmpuhf.saar.de [192.109.53.3]) by shug-internet.saar.de (8.6.8.1/8.5) with SMTP id PAA02329; Fri, 21 Oct 1994 15:18:17 +0100
7Received: from wg.saar.de by TMPuhf.Saar.DE with uucp
8	(Smail3.1.28.1 #1) id m0qyKVv-00021NC; Fri, 21 Oct 94 14:00 WET
9Received: by bellona.wg.saar.de id m0qyJpt-0002fRC; Fri, 21 Oct 94 13:16
10Received: by stone.saar.de (Smail3.1.28.1 #6)
11	id m0qy2ly-0002szC; Thu, 20 Oct 94 20:03 MET
12Message-Id: <m0qy2ly-0002szC@stone.saar.de>
13Subject: mgetty-0.21 einige Patches.
14To: gert@greenie.muc.de
15Date: Thu, 20 Oct 1994 20:03:34 +0100
16From: Juergen Kammer <kammer@Stone.Quarry.Saar.DE>
17Cc: kammer@Stone.Quarry.Saar.DE (Juergen Kammer)
18X-Mailer: ELM [version 2.4 PL21]
19Content-Type: text
20Content-Length: 17047
21Status: RO
22
23Hallo Gert,
24
25Du erinnerst Dich vielleicht noch an mich, ich war der mit dem "Deltafax",
26der sich so eine komische Konfiguration mit 2 Modems zusammengebaut hatte
27(irgendwann mit Version 0.18).
28
29Die 0.21er Testversion hab ich mir mal geangelt und meine Patches dort
30nochmal - diesmal IMHO sauberer als damals - eingebaut. Die Patches haengen
31als Bestandteil dieser Mail weiter untern dran, das eine oder andere ist
32evtl. auch fuer andere Leute interessant. Meine inittab (Linux 1.1.irgendwas)
33sieht derzeit fuer den mgetty so aus:
34
35t1:34:respawn:/etc/mgetty -x 4 -s 38400 -n 1 -C data -T 42 -X ttyS4 ttyS3
36t2:34:respawn:/etc/mgetty -x 4 -s 19200 -n 10 -C cls2 -T 48 -F ttyS4
37
38Suess, nicht?
39
40Mit der Bedeutung, dass der erste mgetty den zweiten aufweckt, falls er
41nach 42 Sekunden keinen DATA connect zustandebekommt. F steht fuer Fax only.
42Das -T bei zweiten ist Kosmetik... hat wenig Sinn, dass der mgetty laenger
43wartet, als das Modem versucht, was zu tun.
44
45    Zur Erinnerung: Mein Datenmodem hat keine FAX-Erkennung, und das FAX-
46    Modem ist ein 2400er, was ich meinen Leuten fuer Logins nicht zumuten
47    kann.  FAX-Schicker muessen halt ca. 50 Sekunden Geduld zeigen, bis ein
48    FAX-Carrier kommt. Im Prinzip entspricht das Verfahren der Einfachst-
49    Faxerkennung (Versuche DATA Verbindung, wenn kein Erfolg, versuche FAX).
50
51    Trick ist, das Faxmodem VOR dem Datenmodem an der Leitung haengen zu
52    haben, damit das FAXmodem Vorfahrt bekommt und Gespraeche "uebernehmen"
53    kann.
54
55Mit DTR togglen spiel ich auch noch, dafuer gibts auch schon Option.
56
57Frei nach Manual-Page
58
59    It *really* should be fully run-time configurable.
60
61sind alle Features schaltbar. Die Aenderungen im einzeln kannst meiner
62Aenderungsdatei entnehmen, deren momentanen Stand ich vor dem eigentlichen
63Patch hier drunterhaenge. Das ganze ist erst einen Tag alt, tickert aber
64anscheinend so vor sich hin. Falls es noch Probs hier gibt, hoerst Du von
65mir.
66
67BTW, Faxen hab ich noch nicht probiert... wird aber auch bald passieren.
68Erst noch den FAX-spool-Kram durchgehen. Hat sich ja einiges getan seit
690.18.
70
71Keep up the good work,
72
73	Juergen.
74
75--------- jk-patch-contents follows ---------------
76
77Patch ist relativ zu <version.h follows>
78
79static char * mgetty_version = "experimental test release 0.21-August10";
80
81---
82
83Inhalt des Patches:
84
85- Wegwerfen des Pidfiles auch bei exit()-Aufrufen.
86    Aenderungen in mgetty.c.
87
88	TODO:   Lockbeseitigen und Pidfileabraeumen in anderen Dateien,
89	        wenn exit aufgerufen wird, zB in getlockname.
90	        "Quick and Dirty"-Loesung: sig_goodbye aufrufen,
91	        exit-Situation durch "Signal" >31 anzeigen.
92
93	MORETODO:  Auch dip raeumt nicht ab. Dip-Aenderungen sind bei meiner
94	        Version mannigfach (Keine Pid im Lockfile, klar, siehe
95	        patch unter contrib... aber: nach Daemonizing "lebt" dip
96	        mit anderer Pid weiter... und er hat nicht zuerst gelockt
97	        und dann open gemacht und rumgebosselt, sondern erst open
98	        gemacht, rumgebosselt, dann Lockfile (versucht) anzulegen
99	        und dann weitergebosselt. Flutschte zuerst nur als
100	        cua?, musste als getties rauswerfen, um rauszuslippen:
101	        aetzend. Heavily broken, das Teil.)
102	        Abgesehen davon, dass mein dip hier mit umherlaufenden
103	        anderen Versionen mittlerweile immer weniger zu tun hat
104	        (ifconfig + route-aufrufe in Shellskripte ausgelagert:
105	        SEHR angenehm, wenn /etc/diphosts nicht alles hergibt,
106	        was geconfig't und geroutet werden muss  [urspruenglich
107	        stammt letzteres von Patrick (bof@wg.saar.de)]. Ich weiss
108	        nicht, mit welcher Version er mal angefangen hat).
109
110	Bemerkung: Das fehlende Abraeumen stoert im lfd. Betrieb _seltenst_.
111	        Wenn die Kiste aber mal runtergefahren wird und die
112		Verhaeltnisse passen, fraegt man sich, warum der getty nicht
113		aufs Modem will (ist mir immerhin 1* passiert: alles sauber
114		hochgefahren und der getty geht nicht auf Modem, uucp
115		geht nicht, was iss denn jetzt kaputt!? Bis man in der
116		Situation an ein stale-Lockfile denkt... OK, beim Hochfahren
117		wirft man alle alten Locks weg - das war der eigentlich
118		Fehler, aber naja, was man im Vorfeld verhindern kann...
119		Ohne Runterfahren in diese Situation zu kommen, hm...,
120		unwahrscheinlich... aber wie ich Murphy kenne, wird er mich
121		eines besseren belehren.
122
123- Moeglichkeit, auf DATA zu verzichten und NUR Faxe zu machen. (fax_only)
124    Aenderungen in mgetty.c und mg_m_init.c.
125    (nur fuer Modemclass cls2 gemacht)
126    Option dafuer: -F
127
128	TODO:   Dasselbe bei FCLASS2.0.
129
130- Moeglichkeit, den Timeout im Chat (answer_chat_timeout) via CommandLine
131    zu setzen.
132    Aenderungen in mgetty.c.
133    Option dafuer: -T <timeout>
134
135- Moeglichkeit, nach Ablauf des Timeout im Chat anderen mgetty via
136    SIGUSR1 zum Abheben zu Bewegen.
137    Aenderungen in mgetty.c
138
139    Option dafuer: -X <device von anderem mgetty>
140
141- Moeglichkeit, DTR-togglen zur Initialisierung via Commandline abzuschalten
142    Aenderungen in mgetty.c
143
144    Option dafuer: -R
145
146- TODO:
147	Manualpage mit neuen Optionen aufpusten.
148
149	sendfax aufbohren: Kein Fax zu senden versuchen, wenn auf dem DATA
150	Modem ein Lock drauf ist. Puh. Sieht nach einer Compile-option aus.
151	Oder bau ichs in eines der faxspool-Skripte ein? Einstweilen gehts
152	manuell, muss halt aufpassen ;-)
153
154---------------- jk-patch follows ------------------------
155diff -u orig/mg_m_init.c ./mg_m_init.c
156--- orig/mg_m_init.c	Wed Oct 19 15:32:50 1994
157+++ ./mg_m_init.c	Wed Oct 19 15:43:11 1994
158@@ -34,7 +34,7 @@
159  * To send a backslash, you have to use "\\\\" (four backslashes!) */
160
161 static char *	init_chat_seq[] = { "",
162-			    "\\d\\d\\d+++\\d\\d\\d\r\\dATQ0V1H0", "OK",
163+			    "\\d\\d\\d+++\\d\\d\\d\r\\dATQ0H0", "OK",
164
165 /* initialize the modem - defined in policy.h
166  */
167@@ -64,8 +64,8 @@
168
169 /* initialize fax section */
170
171-int mg_init_fax _P3( (fd, mclass, fax_id),
172-		      int fd, char * mclass, char * fax_id )
173+int mg_init_fax _P4( (fd, mclass, fax_id, fax_only),
174+		      int fd, char * mclass, char * fax_id, boolean fax_only )
175 {
176     /* find out whether this beast is a fax modem... */
177
178@@ -103,21 +103,42 @@
179 	 * +FCLASS=0: there are some weird modems out there that won't
180 	 * properly auto-detect fax/data when in +FCLASS=2 mode...
181 	 */
182-	if ( mdm_command( "AT+FCLASS=0", fd ) == FAIL )
183-	{
184-	    lprintf( L_MESG, "weird: cannot set class 0" );
185-	}
186
187-	/* now, set various flags and modem settings. Failures are logged,
188-	   but ignored - after all, either the modem works or not, we'll
189-	   see it when answering the phone ... */
190-
191-	/* set adaptive answering, bit order, receiver on */
192+	if ( fax_only )
193+	{
194+	    if ( mdm_command( "AT+FCLASS=2", fd ) == FAIL )
195+	    {
196+		lprintf( L_MESG, "weird: cannot set class 0" );
197+	    }
198+	    /* now, set various flags and modem settings. Failures are logged,
199+	       but ignored - after all, either the modem works or not, we'll
200+	       see it when answering the phone ... */
201+
202+	    /* set adaptive answering, bit order, receiver on */
203
204-	if ( mdm_command( "AT+FAA=1;+FCR=1", fd ) == FAIL )
205+	    if ( mdm_command( "AT+FAA=0;+FCR=1", fd ) == FAIL )
206+	    {
207+		lprintf( L_MESG, "cannot set reception flags" );
208+	    }
209+	}
210+	else
211 	{
212-	    lprintf( L_MESG, "cannot set reception flags" );
213+	    if ( mdm_command( "AT+FCLASS=0", fd ) == FAIL )
214+	    {
215+		lprintf( L_MESG, "weird: cannot set class 0" );
216+	    }
217+	    /* now, set various flags and modem settings. Failures are logged,
218+	       but ignored - after all, either the modem works or not, we'll
219+	       see it when answering the phone ... */
220+
221+	    /* set adaptive answering, bit order, receiver on */
222+
223+	    if ( mdm_command( "AT+FAA=1;+FCR=1", fd ) == FAIL )
224+	    {
225+		lprintf( L_MESG, "cannot set reception flags" );
226+	    }
227 	}
228+
229 	if ( fax_set_bor( fd, 0 ) == FAIL )
230 	{
231 	    lprintf( L_MESG, "cannot set bit order. Huh?" );
232diff -u orig/mgetty.c ./mgetty.c
233--- orig/mgetty.c	Mon Oct 17 19:12:08 1994
234+++ ./mgetty.c	Thu Oct 20 19:34:06 1994
235@@ -102,6 +102,10 @@
236 char	* DevID;			/* device name withouth '/'s */
237 char	* GettyID = "<none>";		/* Tag for gettydefs in cmd line */
238
239+char	* other_Device = NULL;		/* device of other mgetty to signal */
240+char	* other_DevID = NULL;		/* ditto name without '/'s */
241+static char other_pid_file_name[ MAXPATH ];
242+
243 boolean	toggle_dtr = TRUE;		/* lower DTR */
244
245 int	toggle_dtr_waittime = 500;	/* milliseconds while DTR is low */
246@@ -118,18 +122,6 @@
247 boolean verbose = FALSE;
248
249 boolean virtual_ring = FALSE;
250-static RETSIGTYPE sig_pick_phone()		/* "simulated RING" handler */
251-{
252-    signal( SIGUSR1, sig_pick_phone );
253-    virtual_ring = TRUE;
254-}
255-static RETSIGTYPE sig_goodbye _P1 ( (signo), int signo )
256-{
257-    lprintf( L_AUDIT, "failed dev=%s, pid=%d, got signal %d, exiting",
258-	              Device, getpid(), signo );
259-    rmlocks();
260-    exit(10);
261-}
262
263 #ifdef MGETTY_PID_FILE
264 /* create a file with the process ID of the mgetty currently
265@@ -151,6 +143,22 @@
266     }
267 }
268 #endif
269+
270+static RETSIGTYPE sig_pick_phone()		/* "simulated RING" handler */
271+{
272+    signal( SIGUSR1, sig_pick_phone );
273+    virtual_ring = TRUE;
274+}
275+static RETSIGTYPE sig_goodbye _P1 ( (signo), int signo )
276+{
277+    lprintf( L_AUDIT, "failed dev=%s, pid=%d, got signal %d, exiting",
278+	              Device, getpid(), signo );
279+    rmlocks();
280+#ifdef MGETTY_PID_FILE
281+	(void) unlink( pid_file_name );
282+#endif
283+    exit(10);
284+}
285
286
287 enum { St_unknown,
288@@ -185,6 +193,7 @@
289 #else
290     boolean	data_only = FALSE;
291 #endif
292+    boolean	fax_only  = FALSE;
293     char	* modem_class = DEFAULT_MODEMTYPE;	/* policy.h */
294     boolean	autobauding = FALSE;
295
296@@ -244,7 +253,7 @@
297 	direct_line = TRUE;
298     }
299
300-    while ((c = getopt(argc, argv, "c:x:s:rp:n:i:DC:S:m:I:ba")) != EOF)
301+    while ((c = getopt(argc, argv, "c:x:s:rp:n:i:DFC:S:T:X:m:I:baR")) != EOF)
302     {
303 	switch (c) {
304 	  case 'c':			/* check */
305@@ -294,6 +303,9 @@
306 	  case 'D':			/* switch off fax */
307 	    data_only = TRUE;
308 	    break;
309+	  case 'F':			/* switch off data */
310+	    fax_only = TRUE;
311+	    break;
312 	  case 'C':
313 	    modem_class = optarg;
314 	    if ( strcmp( modem_class, "data" ) == 0 ) data_only = TRUE;
315@@ -301,6 +313,26 @@
316 	  case 'S':
317 	    fax_server_file = optarg;
318 	    break;
319+	  case 'T':			/* set chat-timeout */
320+	    i = atoi(optarg);
321+	    if ( i > 0 && i < 120 )	/* do at least some sanity check */
322+		answer_chat_timeout = i;
323+	    break;
324+	  case 'X':
325+	    other_Device = optarg;
326+	    /* remove leading /dev/ prefix */
327+	    if ( strncmp( other_Device, "/dev/", 5 ) == 0 ) other_Device += 5;
328+	    other_DevID = mydup( other_Device );
329+	    for ( i=0; other_DevID[i] != 0; i++ )
330+		if ( other_DevID[i] == '/' ) other_DevID[i] = '-';
331+	    /* need pidfilename of other getty */
332+#ifdef MGETTY_PID_FILE
333+	    sprintf( other_pid_file_name, MGETTY_PID_FILE, other_DevID );
334+#else
335+	    /* use a default, hopefulle it will work */
336+	    sprintf( other_pid_file_name, "/etc/mg-pid.%s", other_DevID );
337+#endif
338+	    break;
339 	  case 'I':
340 	    fax_station_id = optarg; break;
341 	  case 'b':			/* open port in blocking mode */
342@@ -307,6 +339,8 @@
343 	    blocking_open = TRUE; break;
344 	  case 'a':			/* autobauding */
345 	    autobauding = TRUE; break;
346+	  case 'R':
347+	    toggle_dtr  = FALSE; break;
348 	  case '?':
349 	    exit_usage(2);
350 	    break;
351@@ -366,6 +400,9 @@
352     if (checklock(Device) != NO_LOCK)
353     {
354 	while (checklock(Device) != NO_LOCK) sleep(10);
355+#ifdef MGETTY_PID_FILE
356+	(void) unlink( pid_file_name );
357+#endif
358 	exit(0);
359     }
360
361@@ -376,6 +413,9 @@
362     if ( makelock(Device) == FAIL )
363     {
364 	while( checklock(Device) != NO_LOCK ) sleep(10);
365+#ifdef MGETTY_PID_FILE
366+	(void) unlink( pid_file_name );
367+#endif
368 	exit(0);
369     }
370
371@@ -395,6 +435,9 @@
372     if ( mg_open_device( devname, blocking_open ) == ERROR ) /* mg_m_init.c */
373     {
374 	lprintf( L_FATAL, "open device %s failed, exiting", devname );
375+#ifdef MGETTY_PID_FILE
376+	(void) unlink( pid_file_name );
377+#endif
378 	exit( FAIL );
379     }
380
381@@ -412,6 +455,9 @@
382 			 portspeed ) == ERROR )
383     {
384 	lprintf( L_FATAL, "cannot initialize device, exiting" );
385+#ifdef MGETTY_PID_FILE
386+	(void) unlink( pid_file_name );
387+#endif
388 	exit( 20 );
389     }
390
391@@ -428,11 +474,15 @@
392 	if ( mg_init_data( STDIN ) == FAIL )
393 	{
394 	    rmlocks();
395+#ifdef MGETTY_PID_FILE
396+	(void) unlink( pid_file_name );
397+#endif
398 	    exit(1);
399 	}
400+	/* jk iff fax_only tell it to mg_init_fax */
401 	/* initialize ``normal'' fax functions */
402 	if ( ( ! data_only ) &&
403-	     mg_init_fax( STDIN, modem_class, fax_station_id ) == SUCCESS )
404+	     mg_init_fax( STDIN, modem_class, fax_station_id, fax_only ) == SUCCESS )
405 	{
406 	    /* initialize fax polling server (only if faxmodem) */
407 	    if ( fax_server_file )
408@@ -589,6 +639,9 @@
409 	    lprintf( L_FATAL, "modem on %s doesn't react!", devname );
410
411 	    /* give up */
412+#ifdef MGETTY_PID_FILE
413+	(void) unlink( pid_file_name );
414+#endif
415 	    exit( 30 );
416
417 	    break;
418@@ -635,6 +688,9 @@
419 		mgetty_state = St_incoming_fax; break;
420 	      default:
421 		lprintf( L_MESG, "unexpected action: %d", what_action );
422+#ifdef MGETTY_PID_FILE
423+	(void) unlink( pid_file_name );
424+#endif
425 		exit(20);
426 	    }
427 #endif
428@@ -672,6 +728,9 @@
429  	    while ( checklock(Device) != NO_LOCK );
430
431 	    /* OK, leave & get restarted by init */
432+#ifdef MGETTY_PID_FILE
433+	(void) unlink( pid_file_name );
434+#endif
435 	    exit(0);
436 	    break;
437
438@@ -689,8 +748,11 @@
439
440 	    while ( rings < rings_wanted )
441 	    {
442+		i = (fax_only) ? 50 : 0;
443+		/* increase timeout waiting for rings iff fax_only */
444+		/* because other modem may ring us virtually */
445 		if ( do_chat( STDIN, ring_chat_seq, ring_chat_actions,
446-			      &what_action, ring_chat_timeout,
447+			      &what_action, ring_chat_timeout+i,
448 			      TRUE ) == FAIL
449 #ifdef DIST_RING
450 		    && (what_action != DIST_RING_VOICE)
451@@ -718,6 +780,9 @@
452 		{
453 		    lprintf( L_WARN, "huh? Junk on the line?" );
454 		    rmlocks();		/* line is free again */
455+#ifdef MGETTY_PID_FILE
456+	(void) unlink( pid_file_name );
457+#endif
458 		    exit(0);		/* let init restart mgetty */
459 		}
460 		lprintf( L_MESG, "phone stopped ringing (rings=%d)", rings );
461@@ -737,9 +802,15 @@
462 	      case A_FAIL:
463 		lprintf( L_AUDIT, "failed A_FAIL dev=%s, pid=%d, caller=%s",
464 			          Device, getpid(), CallerId );
465+#ifdef MGETTY_PID_FILE
466+	(void) unlink( pid_file_name );
467+#endif
468 		exit(20);
469 	      default:
470 		lprintf( L_MESG, "unexpected action: %d", what_action );
471+#ifdef MGETTY_PID_FILE
472+	(void) unlink( pid_file_name );
473+#endif
474 		exit(20);
475 	    }
476 	    break;
477@@ -798,8 +869,44 @@
478 		   "failed %s dev=%s, pid=%d, caller=%s, conn='%s', name='%s'",
479 		    what_action == A_TIMOUT? "timeout": "A_FAIL",
480 		    Device, getpid(), CallerId, Connect, CallName );
481+
482+		if ( other_Device != NULL )
483+		{
484+		    /* we are told to try to signal other getty to take over */
485+		    /* get pid of that f*cker */
486+		    FILE *fp;
487+		    int  other_pid = 65000;	/* never valid, pids < 32768 */
488+		    fp = fopen( other_pid_file_name, "r" );
489+		    if ( fp == NULL )
490+			lprintf( L_ERROR, "can't get pid of other mgetty out of file %s", other_pid_file_name );
491+		    else
492+		    {
493+			fscanf( fp, "%d\n", &other_pid ); fclose( fp );
494+
495+			if ( other_pid > 1 && other_pid < 32768 )
496+			{
497+
498+			    lprintf( L_AUDIT,
499+				"Found pid %d, signaling.",
500+					    other_pid);
501+			    if ( kill( other_pid, SIGUSR1 ) < 0 )
502+			    {
503+				lprintf( L_ERROR, "Signaling failed, errno = %d",
504+				    errno );
505+			    }
506+			    else
507+			    {
508+				/* give it chance to overtake */
509+				sleep(5);
510+			    }
511+			}
512+		    }
513+		}
514
515 		rmlocks();
516+#ifdef MGETTY_PID_FILE
517+	(void) unlink( pid_file_name );
518+#endif
519 		exit(1);
520 	    }
521
522@@ -845,6 +952,9 @@
523 	    lprintf( L_MESG, "start fax receiver..." );
524 	    faxrec( FAX_SPOOL_IN );
525 	    rmlocks();
526+#ifdef MGETTY_PID_FILE
527+	(void) unlink( pid_file_name );
528+#endif
529 	    exit( 0 );
530 	    break;
531
532@@ -852,6 +962,9 @@
533 	    /* unknown machine state */
534
535 	    lprintf( L_WARN, "unknown state: %s", mgetty_state );
536+#ifdef MGETTY_PID_FILE
537+	(void) unlink( pid_file_name );
538+#endif
539 	    exit( 33 );
540 	}		/* end switch( mgetty_state ) */
541     }			/* end while( state != St_get_login ) */
542diff -u orig/mgetty.h ./mgetty.h
543--- orig/mgetty.h	Wed Oct 19 15:42:15 1994
544+++ ./mgetty.h	Wed Oct 19 15:42:20 1994
545@@ -133,7 +133,7 @@
546
547 /* initialization stuff: mg_m_init.c */
548 int	mg_init_data  _PROTO(( int fd ));
549-int	mg_init_fax   _PROTO(( int fd, char * mclass, char * fax_id ));
550+int	mg_init_fax   _PROTO(( int fd, char * mclass, char * fax_id, boolean fax_only ));
551 int 	mg_init_voice _PROTO(( int fd ));
552 void	faxpoll_server_init _PROTO(( int fd, char * fax_server_file ));
553 int	mg_open_device _PROTO(( char * devname, boolean blocking ));
554------------------------ENDE PATCH ----------------------------------------
555--
556Juergen Kammer	             |  Linux
557Kurt-Schumacher-Allee 139    |    - program, for whatever OS you are:
558D-66740 Saarlouis, Germany   |        ** Resistance is futile.  **
559Email: kammer@stone.saar.de  |        ** Prepare to be EMULATED.**
560
561