home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / alt / sources / 2515 < prev    next >
Encoding:
Internet Message Format  |  1992-11-15  |  15.1 KB

  1. Path: sparky!uunet!ferkel.ucsb.edu!taco!rock!stanford.edu!ames!agate!doc.ic.ac.uk!uknet!mcsun!Germany.EU.net!anl433!Iain.Lea
  2. From: Iain.Lea%anl433.uucp@Germany.EU.net (Iain Lea)
  3. Newsgroups: alt.sources
  4. Subject: TIN newsreader v1.1 PL7 (Patch 10/10)
  5. Message-ID: <1992Nov15.155457.20513@anl433.uucp>
  6. Date: 15 Nov 92 15:54:57 GMT
  7. Sender: news@anl433.uucp (Netnews Administrator)
  8. Reply-To: Iain.Lea%anl433.uucp@Germany.EU.net
  9. Followup-To: alt.sources.d
  10. Organization: ANL A433, Siemens AG., Germany.
  11. Lines: 604
  12. X-Newsreader: TIN [version 1.1 PL7]
  13.  
  14. Submitted-by: Iain.Lea%anl433.uucp@Germany.EU.net (Iain Lea)
  15. Archive-name: tin-1.17/part10
  16.  
  17. #!/bin/sh
  18. # this is tin.shar.10 (part 10 of tin-1.17)
  19. # do not concatenate these parts, unpack them in order with /bin/sh
  20. # file strftime.c continued
  21. #
  22. if test ! -r _shar_seq_.tmp; then
  23.     echo 'Please unpack part 1 first!'
  24.     exit 1
  25. fi
  26. (read Scheck
  27.  if test "$Scheck" != 10; then
  28.     echo Please unpack part "$Scheck" next!
  29.     exit 1
  30.  else
  31.     exit 0
  32.  fi
  33. ) < _shar_seq_.tmp || exit 1
  34. if test ! -f _shar_wnt_.tmp; then
  35.     echo 'x - still skipping strftime.c'
  36. else
  37. echo 'x - continuing file strftime.c'
  38. sed 's/^X//' << 'SHAR_EOF' >> 'strftime.c' &&
  39. X    static char *days_l[] = {
  40. X        "Sunday", "Monday", "Tuesday", "Wednesday",
  41. X        "Thursday", "Friday", "Saturday",
  42. X    };
  43. X    static char *months_a[] = {
  44. X        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  45. X        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
  46. X    };
  47. X    static char *months_l[] = {
  48. X        "January", "February", "March", "April",
  49. X        "May", "June", "July", "August", "September",
  50. X        "October", "November", "December",
  51. X    };
  52. X    static char *ampm[] = { "AM", "PM", };
  53. X
  54. X    if (s == NULL || format == NULL || timeptr == NULL || maxsize == 0)
  55. X        return 0;
  56. X
  57. X    if (strchr(format, '%') == NULL && strlen(format) + 1 >= maxsize)
  58. X        return 0;
  59. X
  60. X    tzset();
  61. X
  62. X    for (; *format && s < endp - 1; format++) {
  63. X        tbuf[0] = '\0';
  64. X        if (*format != '%') {
  65. X            *s++ = *format;
  66. X            continue;
  67. X        }
  68. X        switch (*++format) {
  69. X        case '\0':
  70. X            *s++ = '%';
  71. X            goto out;
  72. X
  73. X        case '%':
  74. X            *s++ = '%';
  75. X            continue;
  76. X
  77. X        case 'a':    /* abbreviated weekday name */
  78. X            strcpy(tbuf, days_a[timeptr->tm_wday]);
  79. X            break;
  80. X
  81. X        case 'A':    /* full weekday name */
  82. X            strcpy(tbuf, days_l[timeptr->tm_wday]);
  83. X            break;
  84. X
  85. X#ifdef SYSV_EXT
  86. X        case 'h':    /* abbreviated month name */
  87. X#endif
  88. X        case 'b':    /* abbreviated month name */
  89. X            strcpy(tbuf, months_a[timeptr->tm_mon]);
  90. X            break;
  91. X
  92. X        case 'B':    /* full month name */
  93. X            strcpy(tbuf, months_l[timeptr->tm_mon]);
  94. X            break;
  95. X
  96. X        case 'c':    /* appropriate date and time representation */
  97. X            sprintf(tbuf, "%s %s %2d %02d:%02d:%02d %d",
  98. X                days_a[timeptr->tm_wday],
  99. X                months_a[timeptr->tm_mon],
  100. X                timeptr->tm_mday,
  101. X                timeptr->tm_hour,
  102. X                timeptr->tm_min,
  103. X                timeptr->tm_sec,
  104. X                timeptr->tm_year + 1900);
  105. X            break;
  106. X
  107. X        case 'd':    /* day of the month, 01 - 31 */
  108. X            sprintf(tbuf, "%02d", timeptr->tm_mday);
  109. X            break;
  110. X
  111. X        case 'H':    /* hour, 24-hour clock, 00 - 23 */
  112. X            sprintf(tbuf, "%02d", timeptr->tm_hour);
  113. X            break;
  114. X
  115. X        case 'I':    /* hour, 12-hour clock, 01 - 12 */
  116. X            i = timeptr->tm_hour;
  117. X            if (i == 0)
  118. X                i = 12;
  119. X            else if (i > 12)
  120. X                i -= 12;
  121. X            sprintf(tbuf, "%02d", i);
  122. X            break;
  123. X
  124. X        case 'j':    /* day of the year, 001 - 366 */
  125. X            sprintf(tbuf, "%03d", timeptr->tm_yday + 1);
  126. X            break;
  127. X
  128. X        case 'm':    /* month, 01 - 12 */
  129. X            sprintf(tbuf, "%02d", timeptr->tm_mon + 1);
  130. X            break;
  131. X
  132. X        case 'M':    /* minute, 00 - 59 */
  133. X            sprintf(tbuf, "%02d", timeptr->tm_min);
  134. X            break;
  135. X
  136. X        case 'p':    /* am or pm based on 12-hour clock */
  137. X            if (timeptr->tm_hour < 12)
  138. X                strcpy(tbuf, ampm[0]);
  139. X            else
  140. X                strcpy(tbuf, ampm[1]);
  141. X            break;
  142. X
  143. X        case 'S':    /* second, 00 - 61 */
  144. X            sprintf(tbuf, "%02d", timeptr->tm_sec);
  145. X            break;
  146. X
  147. X        case 'w':    /* weekday, Sunday == 0, 0 - 6 */
  148. X            sprintf(tbuf, "%d", timeptr->tm_wday);
  149. X            break;
  150. X
  151. X        case 'x':    /* appropriate date representation */
  152. X            sprintf(tbuf, "%s %s %2d %d",
  153. X                days_a[timeptr->tm_wday],
  154. X                months_a[timeptr->tm_mon],
  155. X                timeptr->tm_mday,
  156. X                timeptr->tm_year + 1900);
  157. X            break;
  158. X
  159. X        case 'X':    /* appropriate time representation */
  160. X            sprintf(tbuf, "%02d:%02d:%02d",
  161. X                timeptr->tm_hour,
  162. X                timeptr->tm_min,
  163. X                timeptr->tm_sec);
  164. X            break;
  165. X
  166. X        case 'y':    /* year without a century, 00 - 99 */
  167. X            i = timeptr->tm_year % 100;
  168. X            sprintf(tbuf, "%d", i);
  169. X            break;
  170. X
  171. X        case 'Y':    /* year with century */
  172. X            sprintf(tbuf, "%d", 1900 + timeptr->tm_year);
  173. X            break;
  174. X
  175. X#ifdef SYSV_EXT
  176. X        case 'n':    /* same as \n */
  177. X            tbuf[0] = '\n';
  178. X            tbuf[1] = '\0';
  179. X            break;
  180. X
  181. X        case 't':    /* same as \t */
  182. X            tbuf[0] = '\t';
  183. X            tbuf[1] = '\0';
  184. X            break;
  185. X
  186. X        case 'D':    /* date as %m/%d/%y */
  187. X            my_strftime(tbuf, sizeof tbuf, "%m/%d/%y", timeptr);
  188. X            break;
  189. X
  190. X        case 'e':    /* day of month, blank padded */
  191. X            sprintf(tbuf, "%2d", timeptr->tm_mday);
  192. X            break;
  193. X
  194. X        case 'r':    /* time as %I:%M:%S %p */
  195. X            my_strftime(tbuf, sizeof tbuf, "%I:%M:%S %p", timeptr);
  196. X            break;
  197. X
  198. X        case 'R':    /* time as %H:%M */
  199. X            my_strftime(tbuf, sizeof tbuf, "%H:%M", timeptr);
  200. X            break;
  201. X
  202. X        case 'T':    /* time as %H:%M:%S */
  203. X            my_strftime(tbuf, sizeof tbuf, "%H:%M:%S", timeptr);
  204. X            break;
  205. X#endif
  206. X
  207. X        default:
  208. X            tbuf[0] = '%';
  209. X            tbuf[1] = *format;
  210. X            tbuf[2] = '\0';
  211. X            break;
  212. X        }
  213. X        i = strlen(tbuf);
  214. X        if (i)
  215. X            if (s + i < endp - 1) {
  216. X                strcpy(s, tbuf);
  217. X                s += i;
  218. X            } else
  219. X                return 0;
  220. X    }
  221. Xout:
  222. X    if (s < endp && *format == '\0') {
  223. X        *s = '\0';
  224. X        return (s - start);
  225. X    } else
  226. X        return 0;
  227. X}
  228. SHAR_EOF
  229. echo 'File strftime.c is complete' &&
  230. chmod 0644 strftime.c ||
  231. echo 'restore of strftime.c failed'
  232. Wc_c="`wc -c < 'strftime.c'`"
  233. test 5590 -eq "$Wc_c" ||
  234.     echo 'strftime.c: original size 5590, current size' "$Wc_c"
  235. rm -f _shar_wnt_.tmp
  236. fi
  237. # ============= strftime.3 ==============
  238. if test -f 'strftime.3' -a X"$1" != X"-c"; then
  239.     echo 'x - skipping strftime.3 (File already exists)'
  240.     rm -f _shar_wnt_.tmp
  241. else
  242. > _shar_wnt_.tmp
  243. echo 'x - extracting strftime.3 (Text)'
  244. sed 's/^X//' << 'SHAR_EOF' > 'strftime.3' &&
  245. X.TH STRFTIME 3
  246. X.SH NAME
  247. Xstrftime \- generate formatted time information
  248. X.SH SYNOPSIS
  249. X.ft B
  250. X.nf
  251. X#include <sys/types.h>
  252. X#include <time.h>
  253. X.sp
  254. Xsize_t strftime(char *s, size_t maxsize, const char *format,
  255. X    const struct tm *timeptr);
  256. X.SH DESCRIPTION
  257. XThe following description is transcribed verbatim from the December 7, 1988
  258. Xdraft standard for ANSI C.
  259. XThis draft is essentially identical in technical content
  260. Xto the final version of the standard.
  261. X.LP
  262. XThe
  263. X.B strftime
  264. Xfunction places characters into the array pointed to by
  265. X.B s
  266. Xas controlled by the string pointed to by
  267. X.BR format .
  268. XThe format shall be a multibyte character sequence, beginning and ending in
  269. Xits initial shift state.
  270. XThe
  271. X.B format
  272. Xstring consists of zero or more conversion specifiers and ordinary
  273. Xmultibyte characters.  A conversion specifier consists of a
  274. X.B %
  275. Xcharacter followed by a character that determines the behavior of the
  276. Xconversion specifier.
  277. XAll ordinary multibyte characters (including the terminating null
  278. Xcharacter) are copied unchanged into the array.
  279. XIf copying takes place between objects that overlap the behavior is
  280. Xundefined.
  281. XNo more than
  282. X.B maxsize
  283. Xcharacters are placed into the array.
  284. XEach conversion specifier is replaced by appropriate characters as described
  285. Xin the following list.
  286. XThe appropriate characters are determined by the
  287. X.B LC_TIME
  288. Xcategory of the current locale and by the values contained in the
  289. Xstructure pointed to by
  290. X.BR timeptr .
  291. X.TP
  292. X.B %a
  293. Xis replaced by the locale's abbreviated weekday name.
  294. X.TP
  295. X.B %A
  296. Xis replaced by the locale's full weekday name.
  297. X.TP
  298. X.B %b
  299. Xis replaced by the locale's abbreviated month name.
  300. X.TP
  301. X.B %B
  302. Xis replaced by the locale's full month name.
  303. X.TP
  304. X.B %c
  305. Xis replaced by the locale's appropriate date and time representation.
  306. X.TP
  307. X.B %d
  308. Xis replaced by the day of the month as a decimal number
  309. X.RB ( 01 - 31 ).
  310. X.TP
  311. X.B %H
  312. Xis replaced by the hour (24-hour clock) as a decimal number
  313. X.RB ( 00 - 23 ).
  314. X.TP
  315. X.B %I
  316. Xis replaced by the hour (12-hour clock) as a decimal number
  317. X.RB ( 01 - 12 ).
  318. X.TP
  319. X.B %j
  320. Xis replaced by the day of the year as a decimal number
  321. X.RB ( 001 - 366 ).
  322. X.TP
  323. X.B %m
  324. Xis replaced by the month as a decimal number
  325. X.RB ( 01 - 12 ).
  326. X.TP
  327. X.B %M
  328. Xis replaced by the minute as a decimal number
  329. X.RB ( 00 - 59 ).
  330. X.TP
  331. X.B %p
  332. Xis replaced by the locale's equivalent of the AM/PM designations associated
  333. Xwith a 12-hour clock.
  334. X.TP
  335. X.B %S
  336. Xis replaced by the second as a decimal number
  337. X.RB ( 00 - 61 ).
  338. X.TP
  339. X.B %U
  340. Xis replaced by the week number of the year (the first Sunday as the first
  341. Xday of week 1) as a decimal number
  342. X.RB ( 00 - 53 ).
  343. X.TP
  344. X.B %w
  345. Xis replaced by the weekday as a decimal number
  346. X.RB [ "0 " (Sunday)- 6 ].
  347. X.TP
  348. X.B %W
  349. Xis replaced by the week number of the year (the first Monday as the first
  350. Xday of week 1) as a decimal number
  351. X.RB ( 00 - 53 ).
  352. X.TP
  353. X.B %x
  354. Xis replaced by the locale's appropriate date representation.
  355. X.TP
  356. X.B %X
  357. Xis replaced by the locale's appropriate time representation.
  358. X.TP
  359. X.B %y
  360. Xis replaced by the year without century as a decimal number
  361. X.RB ( 00 - 99 ).
  362. X.TP
  363. X.B %Y
  364. Xis replaced by the year with century as a decimal number.
  365. X.TP
  366. X.B %z
  367. Xis replaced by the time zone name or abbreviation, or by no characters if
  368. Xno time zone is determinable.
  369. X.TP
  370. X.B %%
  371. Xis replaced by
  372. X.BR % .
  373. X.LP
  374. XIf a conversion specifier is not one of the above, the behavior is
  375. Xundefined.
  376. X.SH RETURNS
  377. XIf the total number of resulting characters including the terminating null
  378. Xcharacter is not more than
  379. X.BR maxsize ,
  380. Xthe
  381. X.B strftime
  382. Xfunction returns the number of characters placed into the array pointed to
  383. Xby
  384. X.B s
  385. Xnot including the terminating null character.
  386. XOtherwise, zero is returned and the contents of the array are indeterminate.
  387. X.SH NON-ANSI EXTENSIONS
  388. XIf
  389. X.B SYSV_EXT
  390. Xis defined when the routine is compiled, then the following additional
  391. Xconversions will be available.
  392. XThese are borrowed from the System V
  393. X.IR cftime (3)
  394. Xand
  395. X.IR ascftime (3)
  396. Xroutines.
  397. X.TP
  398. X.B %D
  399. Xis equivalent to specifying
  400. X.BR %m/%d/%y .
  401. X.TP
  402. X.B %e
  403. Xis replaced by the day of the month,
  404. Xpadded with a blank if it is only one digit.
  405. X.TP
  406. X.B %h
  407. Xis equivalent to
  408. X.BR %b ,
  409. Xabove.
  410. X.TP
  411. X.B %n
  412. Xis replaced with a newline character (\s-1ASCII LF\s+1).
  413. X.TP
  414. X.B %r
  415. Xis equivalent to specifying
  416. X.BR "%I:%M:%S %p" .
  417. X.TP
  418. X.B %R
  419. Xis equivalent to specifying
  420. X.BR %H:%M: .
  421. X.TP
  422. X.B %T
  423. Xis equivalent to specifying
  424. X.BR %H:%M:%S .
  425. X.TP
  426. X.B %t
  427. Xis replaced with a \s-1TAB\s+1 character.
  428. X.SH SEE ALSO
  429. Xtime(2), ctime(3), localtime(3)
  430. X.SH BUGS
  431. XThis version does not handle multibyte characters or pay attention to the
  432. Xsetting of the
  433. X.B LC_TIME
  434. Xenvironment variable.
  435. X.LP
  436. XIt is not clear what is ``appropriate'' for the C locale; the values
  437. Xreturned are a best guess on the author's part.
  438. X.SH AUTHOR
  439. X.nf
  440. XArnold Robbins
  441. XAudioFAX, Inc.
  442. XSuite 200
  443. X2000 Powers Ferry Road
  444. XMarietta, GA. 30067
  445. XU.S.A.
  446. XINTERNET: arnold@audiofax.com
  447. XUUCP:     emory!audfax!arnold
  448. XPhone:    +1 404 933 7600
  449. XFax-box:  +1 404 618 4581
  450. X.fi
  451. X.SH ACKNOWLEDGEMENTS
  452. XThanks to Geoff Clare <gwc@root.co.uk> for helping debug earlier
  453. Xversions of this routine.
  454. SHAR_EOF
  455. chmod 0644 strftime.3 ||
  456. echo 'restore of strftime.3 failed'
  457. Wc_c="`wc -c < 'strftime.3'`"
  458. test 4976 -eq "$Wc_c" ||
  459.     echo 'strftime.3: original size 4976, current size' "$Wc_c"
  460. rm -f _shar_wnt_.tmp
  461. fi
  462. # ============= xmotd.c ==============
  463. if test -f 'xmotd.c' -a X"$1" != X"-c"; then
  464.     echo 'x - skipping xmotd.c (File already exists)'
  465.     rm -f _shar_wnt_.tmp
  466. else
  467. > _shar_wnt_.tmp
  468. echo 'x - extracting xmotd.c (Text)'
  469. sed 's/^X//' << 'SHAR_EOF' > 'xmotd.c' &&
  470. X/*
  471. X *  Project   : NNTP (RFC 977) extension
  472. X *  Module    : xmotd.c
  473. X *  Author    : I.Lea
  474. X *  Created   : 26-09-92
  475. X *  Updated   : 27-09-92
  476. X *  Notes     : Add a command to display a motd (message of the day) file
  477. X *              Ideas borrowed from NEWGROUPS nntp command
  478. X *              posted by Tim Iverson to alt.sources in mid'91.
  479. X *  Copyright : (c) Copyright 1992 by Iain Lea
  480. X *              You may  freely  copy or  redistribute  this software,
  481. X *              so  long as there is no profit made from its use, sale
  482. X *              trade or  reproduction.  You may not change this copy-
  483. X *              right notice, and it must be included in any copy made
  484. X */
  485. X
  486. X#include "common.h"
  487. X
  488. X#ifdef XMOTD
  489. X
  490. X#include "time.h"
  491. X
  492. X#undef    DEBUG_XMOTD        /* set to define to turn on more debug info */
  493. X
  494. X#ifdef __STDC__
  495. Xvoid xmotd (int argc, char *argv[]);
  496. X#else
  497. Xvoid xmotd ();
  498. X#endif
  499. X
  500. X/*
  501. X * Usage: XMOTD date time ["GMT"]
  502. X *
  503. X * Display a motd file if newer than given date and time
  504. X *
  505. X *  This command is NOT documented in RFC977.
  506. X */
  507. X
  508. Xvoid xmotd(argc, argv)
  509. X    int        argc;
  510. X    char        *argv[];
  511. X{
  512. X    char        line[NNTP_STRLEN];
  513. X    register char    *cp;
  514. X    int        i;
  515. X    FILE        *fp;
  516. X    long        old_date = 0L;
  517. X    long        new_date = 0L;
  518. X    struct stat    sb;
  519. X    
  520. X    if (argc < 3) {
  521. Xprintf("%d Usage: XMOTD yymmdd hhmmss [\"GMT\"].\r\n",
  522. X            ERR_CMDSYN);
  523. X        (void) fflush(stdout);
  524. X        return;
  525. X    }
  526. X
  527. X#if defined(SYSLOG) && defined(DEBUG_XMOTD)
  528. X        syslog(LOG_INFO, "%s xmotd %s %s", hostname, argv[1], argv[2]);
  529. X#endif
  530. X
  531. X    fp = fopen(XMOTD_FILE, "r");
  532. X    if (fp == NULL) {
  533. X#ifdef SYSLOG
  534. X        syslog(LOG_ERR, "xmotd: fopen %s: %m", XMOTD_FILE);
  535. X#endif
  536. X        printf("%d XMOTD Cannot open %s\r\n", ERR_XMOTD, XMOTD_FILE);
  537. X        (void) fflush(stdout);
  538. X        return;
  539. X    }
  540. X
  541. X    /*        YYMMDD            HHMMSS    */
  542. X    if (strlen(argv[1]) != 6 || strlen(argv[2]) != 6) {
  543. X        printf("%d Date/time must be in form YYMMDD HHMMSS.\r\n",
  544. X            ERR_CMDSYN);
  545. X        (void) fflush(stdout);
  546. X        (void) fclose(fp);
  547. X        return;
  548. X    }
  549. X
  550. X    (void) strcpy(line, argv[1]);            /* yymmdd */
  551. X    (void) strcat(line, argv[2]);            /* hhmmss */
  552. X
  553. X    new_date = dtol(line);
  554. X    if (new_date < 0) {
  555. X        printf("%d Invalid date specification.\r\n", ERR_CMDSYN);
  556. X        (void) fflush(stdout);
  557. X        (void) fclose(fp);
  558. X        return;
  559. X    }
  560. X
  561. X    argc -= 3;
  562. X    argv += 3;
  563. X
  564. X    if (argc > 0 && !strcasecmp(*argv, "GMT")) { /* We store stuff in GMT */
  565. X            ++argv;            /* anyway, so this is */
  566. X            --argc;            /* a "noop" */
  567. X    } else                     /* But that means not GMT */
  568. X        new_date = local_to_gmt(new_date);    /* is a definite "op" */
  569. X
  570. X    /*
  571. X     *  stat() motd file and find mtime for comparison
  572. X     */
  573. X    if (stat (XMOTD_FILE, &sb) != -1) {
  574. X        old_date = sb.st_mtime;
  575. X    }
  576. X    
  577. X#if defined(SYSLOG) && defined(DEBUG_XMOTD)
  578. X        syslog(LOG_INFO, "Motd file time=[%ld] request=[%ld]\r\n", 
  579. X            old_date, new_date);
  580. X#endif
  581. X
  582. X    printf("%d Motd file since %s follows.\r\n", OK_XMOTD, line);
  583. X
  584. X#if defined(SYSLOG) && defined(DEBUG_XMOTD)
  585. X        syslog(LOG_INFO, "Motd file since %s %s follows.\r\n", line);
  586. X#endif
  587. X    if (new_date < old_date) {
  588. X        while (fgets(line, sizeof(line), fp) != NULL) {
  589. X            if ((cp = index(line, '\n')) != NULL)
  590. X                *cp = '\0';
  591. X            putline(line);
  592. X        }
  593. X    }
  594. X    putchar('.');
  595. X    putchar('\r');
  596. X    putchar('\n');
  597. X    (void) fflush(stdout);
  598. X    (void) fclose(fp);
  599. X}
  600. X
  601. X#endif    /* XMOTD */
  602. SHAR_EOF
  603. chmod 0644 xmotd.c ||
  604. echo 'restore of xmotd.c failed'
  605. Wc_c="`wc -c < 'xmotd.c'`"
  606. test 3149 -eq "$Wc_c" ||
  607.     echo 'xmotd.c: original size 3149, current size' "$Wc_c"
  608. rm -f _shar_wnt_.tmp
  609. fi
  610. rm -f _shar_seq_.tmp
  611. echo You have unpacked the last part
  612. exit 0
  613.  
  614. --
  615. NAMES  Iain Lea    Iain.Lea%anl433.uucp@Germany.EU.net
  616. SNAIL  Siemens AG, ANL A433SZ, Gruendlacher Str. 248, 8510 Fuerth, Germany.
  617. PHONE  +49-911-3089-407 (work) +49-911-331963 (home) +49-911-3089-290 (FAX)  
  618.