home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume27 / clc / part13 < prev    next >
Encoding:
Text File  |  1993-11-28  |  31.0 KB  |  1,229 lines

  1. Newsgroups: comp.sources.unix
  2. From: panos@anchor.cs.colorado.edu (Panos Tsirigotis)
  3. Subject: v27i119: clc - C Libraries Collection, Part13/20
  4. References: <1.754527080.23891@gw.home.vix.com>
  5. Sender: unix-sources-moderator@gw.home.vix.com
  6. Approved: vixie@gw.home.vix.com
  7.  
  8. Submitted-By: panos@anchor.cs.colorado.edu (Panos Tsirigotis)
  9. Posting-Number: Volume 27, Issue 119
  10. Archive-Name: clc/part13
  11.  
  12. #! /bin/sh
  13. # This is a shell archive.  Remove anything before this line, then unpack
  14. # it by saving it into a file and typing "sh file".  To overwrite existing
  15. # files, type "sh file -c".  You can also feed this as standard input via
  16. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  17. # will see the following message at the end:
  18. #        "End of archive 13 (of 20)."
  19. # Contents:  libconf libs/src/sio/sio.h libs/src/str/strs.c
  20. #   libs/src/xlog/xlog.3
  21. # Wrapped by panos@eclipse on Sun Nov 28 14:48:17 1993
  22. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  23. if test -f 'libconf' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'libconf'\"
  25. else
  26. echo shar: Extracting \"'libconf'\" \(7097 characters\)
  27. sed "s/^X//" >'libconf' <<'END_OF_FILE'
  28. X#!/bin/sh
  29. X
  30. X#
  31. X# Copyright (c) 1993 by Panagiotis Tsirigotis
  32. X#
  33. X
  34. X#
  35. X# $Id: libconf,v 1.1 93/11/26 10:42:45 panos Exp $
  36. X#
  37. X
  38. X#
  39. X# XXX:    a lot of the autoconfiguration stuff would be much less verbose
  40. X#            if we could assume that /bin/sh supports functions. In a future
  41. X#            version we may choose to make that assumption, or assume that
  42. X#            there is also some other shell available (for example, ksh)
  43. X#            that supports functions.
  44. X#
  45. X
  46. Xscript_name=`basename $0`
  47. Xusage="Usage: $script_name [-libc pathname] [-v]"
  48. X
  49. X#
  50. X# The $echo variable should have the pathname for an 'echo' command
  51. X# that understands the -n option.
  52. X#
  53. Xecho=echo
  54. X
  55. Xinc=/usr/include
  56. Xnm_defined_var=D
  57. Xnm_defined_func=T
  58. X
  59. X#
  60. X# Get the options, if any
  61. X#
  62. Xwhile test $# -gt 0
  63. Xdo
  64. X    case "$1" in
  65. X        -*) option=$1 ; shift ;;
  66. X        *) echo $usage ; exit 1
  67. X    esac
  68. X
  69. X    case "$option" in
  70. X        -libc)
  71. X            if test $# -eq 0 ; then
  72. X               $echo "$script_name: Argument missing. Exiting..."
  73. X               exit 1
  74. X            fi
  75. X            libc="$1"
  76. X            shift
  77. X            if test ! -r "$libc" ; then
  78. X               $echo "$script_name: File is not readable: $libc"
  79. X               exit 1
  80. X            fi
  81. X            ;;
  82. X
  83. X        -v)    verbose=yes
  84. X                ;;
  85. X
  86. X        -*)    echo $usage ; exit 1
  87. X    esac
  88. Xdone
  89. X
  90. X
  91. X#######################################################################
  92. X# Get namelist of C library
  93. X#######################################################################
  94. X$echo "Obtaining name list of C library for autoconfiguration"
  95. X
  96. Xif test "$libc" = "" ; then
  97. X    if test -r /lib/libc.a ; then
  98. X        libc=/lib/libc.a
  99. X    else
  100. X        if test -r /usr/lib/libc.a ; then
  101. X            libc=/usr/lib/libc.a
  102. X        else
  103. X            $echo -n "Please enter the pathname of the C library -> "
  104. X            read libc
  105. X            if test "$libc" = "" -o ! -r "$libc" ; then
  106. X                $echo "$script_name: bad pathname. Exiting..."
  107. X                exit 1
  108. X            fi
  109. X        fi
  110. X    fi
  111. Xfi
  112. Xnmfile=/tmp/libc.nm.$$
  113. Xnm $libc > $nmfile 2>/dev/null
  114. Xif test $? -ne 0 ; then
  115. X    if test ! -s $nmfile ; then
  116. X        $echo "Couldn't get the namelist of C library. Exiting..."
  117. X        rm -f $nmfile
  118. X        exit 1
  119. X    else     # name list file is not empty
  120. X        $echo "WARNING: The 'nm' command returned a non-zero exit status"
  121. X        $echo "WARNING: so the namelist obtained from the C library may be inco
  122. Xmplete"
  123. X        $echo "Continuing with determination of configuration flags"
  124. X    fi
  125. Xfi
  126. X
  127. X
  128. X#######################################################################
  129. X#
  130. X# TIMER library configuration.
  131. X#
  132. X#######################################################################
  133. X
  134. X#
  135. X# Determine supported signal handing
  136. X#
  137. Xlookfor=sigaction
  138. Xif test "$verbose" ; then $echo "Looking for $lookfor" ; fi
  139. Xfound=`grep $lookfor $nmfile | egrep "$nm_defined_func"`
  140. Xif test "$found" ; then
  141. X    signal_handling=posix
  142. Xelse
  143. X    lookfor=sigvec
  144. X    if test "$verbose" ; then $echo "Looking for $lookfor" ; fi
  145. X    found=`grep $lookfor $nmfile | egrep "$nm_defined_func"`
  146. X    if test "$found" ; then
  147. X        signal_handling=bsd
  148. X    else
  149. X        signal_handling=simple
  150. X    fi
  151. Xfi
  152. X
  153. X
  154. X#
  155. X# Check for setitimer(2)
  156. X#
  157. Xlookfor=setitimer
  158. Xif test "$verbose" ; then $echo "Looking for $lookfor" ; fi
  159. Xfound=`grep $lookfor $nmfile | egrep "$nm_defined_func"`
  160. Xif test "$found" ; then
  161. X    case "$signal_handling" in
  162. X        posix)    timer_defs= ;;
  163. X        bsd)        timer_defs=-DNO_POSIX_SIGS ;;
  164. X        simple)    no_timers=yes
  165. X    esac
  166. Xelse
  167. X    no_timers=yes
  168. Xfi
  169. X
  170. X
  171. X#######################################################################
  172. X#
  173. X# XLOG library configuration.
  174. X#
  175. X#######################################################################
  176. X
  177. X#
  178. X# Check for syslog(3)
  179. X#
  180. Xlookfor=syslog
  181. Xif test "$verbose" ; then $echo "Looking for $lookfor" ; fi
  182. Xfound=`grep $lookfor $nmfile | egrep "$nm_defined_func"`
  183. Xif test "$found" = "" ; then v=-DNO_SYSLOG ; else v= ; fi
  184. Xxlog_defs="$xlog_defs $v"
  185. X
  186. X#
  187. X# Look for syslog.h
  188. X#
  189. Xv=
  190. Xif test -r $inc/sys/syslog.h ; then
  191. X    v=-DSYSLOG_IN_SYS
  192. X    if test -r $inc/syslog.h ; then
  193. X        cmp -s $inc/syslog.h $inc/sys/syslog.h
  194. X        if test $? -eq 0 ; then v= ; fi
  195. X    fi
  196. Xfi
  197. Xxlog_defs="$xlog_defs $v"
  198. X
  199. X
  200. X#######################################################################
  201. X#
  202. X# MISC library configuration.
  203. X#
  204. X#######################################################################
  205. X
  206. X#
  207. X# Check for new directory types
  208. X#
  209. Xif test -r $inc/dirent.h ; then v= ; else v=-DOLD_DIR ; fi
  210. Xmisc_defs="$misc_defs $v"
  211. X
  212. X#
  213. X# Check for ftw(3)
  214. X#
  215. Xif test -r $inc/ftw.h ; then v= ; else v=-D__FTWX_NO_FTW ; fi
  216. Xmisc_defs="$misc_defs $v"
  217. X
  218. X
  219. X#######################################################################
  220. X#
  221. X# SIO library configuration.
  222. X#
  223. X# Note that we do not try to find out if the system actually supports
  224. X# a generic mmap system call (i.e. an mmap capable of mapping regular
  225. X# files).
  226. X#
  227. X#######################################################################
  228. X
  229. Xlookfor=on_exit
  230. Xif test "$verbose" ; then $echo "Looking for $lookfor" ; fi
  231. Xfound=`grep $lookfor $nmfile | egrep "$nm_defined_func"`
  232. Xif test "$found" ; then v=-DHAS_ONEXIT ; else v= ; fi
  233. Xsio_defs="$sio_defs $v"
  234. X
  235. Xlookfor=atexit
  236. Xif test "$verbose" ; then $echo "Looking for $lookfor" ; fi
  237. Xfound=`grep $lookfor $nmfile | egrep "$nm_defined_func"`
  238. Xif test "$found" ; then v=-DHAS_ATEXIT ; else v= ; fi
  239. Xsio_defs="$sio_defs $v"
  240. X
  241. Xlookfor=memcpy
  242. Xif test "$verbose" ; then $echo "Looking for $lookfor" ; fi
  243. Xfound=`grep $lookfor $nmfile | egrep "$nm_defined_func"`
  244. Xif test "$found" ; then v=-DHAS_MEMOPS ; else v= ; fi
  245. Xsio_defs="$sio_defs $v"
  246. X
  247. Xlookfor=bcopy
  248. Xif test "$verbose" ; then $echo "Looking for $lookfor" ; fi
  249. Xfound=`grep $lookfor $nmfile | egrep "$nm_defined_func"`
  250. Xif test "$found" ; then v=-DHAS_BCOPY ; else v= ; fi
  251. Xsio_defs="$sio_defs $v"
  252. X
  253. Xlookfor=isatty
  254. Xif test "$verbose" ; then $echo "Looking for $lookfor" ; fi
  255. Xfound=`grep $lookfor $nmfile | egrep "$nm_defined_func"`
  256. Xif test "$found" ; then has_isatty=-DHAS_ISATTY ; else has_isatty= ; fi
  257. Xsio_defs="$sio_defs $has_isatty"
  258. X
  259. Xrm -f $nmfile
  260. X
  261. X#
  262. X# Inform the user about our findings.
  263. X#
  264. Xsio_defs=`echo $sio_defs`
  265. Xif test "$sio_defs" ; then
  266. X    echo
  267. X    $echo "For the SIO library, set the following preprocessor flags:"
  268. X    $echo "$sio_defs"
  269. X    if test "$has_isatty" = "" ; then
  270. X        echo "Your system does not have the isatty(3) function which is"
  271. X        echo "required by the SIO library. A replacement can be provided"
  272. X        echo "by determining if your system supports BSD or System V tty"
  273. X        echo "handling. In the former case, use the flag -DHAS_BSDTTY, and"
  274. X        echo "in the latter, use the flag -DHAS_SYSVTTY"
  275. X    fi
  276. Xfi
  277. X
  278. Xxlog_defs=`echo $xlog_defs`
  279. Xecho
  280. Xif test "$xlog_defs" ; then
  281. X    $echo "For the XLOG library, set the following preprocessor flags:"
  282. X    $echo "$xlog_defs"
  283. Xelse
  284. X    echo "No flags need to be set for the XLOG library"
  285. Xfi
  286. X
  287. Xmisc_defs=`echo $misc_defs`
  288. Xecho
  289. Xif test "$misc_defs" ; then
  290. X    $echo "For the MISC library, set the following preprocessor flags:"
  291. X    $echo "$misc_defs"
  292. Xelse
  293. X    echo "No flags need to be set for the MISC library"
  294. Xfi
  295. X
  296. Xif test "$no_times" = "" ; then
  297. X    timer_defs=`echo $timer_defs`
  298. X    echo
  299. X    if test "$timer_defs" ; then
  300. X        $echo "For the TIMER library, set the following preprocessor flags:"
  301. X        $echo "$timer_defs"
  302. X    else
  303. X        echo "No flags need to be set for the TIMER library"
  304. X    fi
  305. Xelse
  306. X    echo "Your system does not support the necessary facilities needed"
  307. X    echo "by the timer library, so that library cannot be compiled"
  308. Xfi
  309. END_OF_FILE
  310. if test 7097 -ne `wc -c <'libconf'`; then
  311.     echo shar: \"'libconf'\" unpacked with wrong size!
  312. fi
  313. chmod +x 'libconf'
  314. # end of 'libconf'
  315. fi
  316. if test -f 'libs/src/sio/sio.h' -a "${1}" != "-c" ; then 
  317.   echo shar: Will not clobber existing file \"'libs/src/sio/sio.h'\"
  318. else
  319. echo shar: Extracting \"'libs/src/sio/sio.h'\" \(6642 characters\)
  320. sed "s/^X//" >'libs/src/sio/sio.h' <<'END_OF_FILE'
  321. X/*
  322. X * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
  323. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  324. X * and conditions for redistribution.
  325. X */
  326. X
  327. X/*
  328. X * $Id: sio.h,v 8.1 1993/03/13 01:13:58 panos Exp $
  329. X */
  330. X
  331. X#ifndef __SIO_H
  332. X#define __SIO_H
  333. X
  334. X#include <errno.h>
  335. X#include <varargs.h>
  336. X
  337. X/*
  338. X * Naming conventions:
  339. X *        1) SIO functions and macros have names starting with a capital S
  340. X *        2) SIO constants meant to be used by user programs have 
  341. X *            names starting with SIO_
  342. X *        3) Internal functions, struct identifiers, enum identifiers 
  343. X *            etc. have names starting with __sio
  344. X *        4) Internal constants and macros have names starting with __SIO
  345. X */
  346. X
  347. X
  348. X/*
  349. X * external constants
  350. X *
  351. X * SIO_FLUSH_ALL: flush all output streams
  352. X * SIO_EOF:    eof on stream
  353. X * SIO_ERR: operation failed
  354. X */
  355. X#define SIO_FLUSH_ALL                (-1)
  356. X#define SIO_EOF                        (-2)
  357. X#define SIO_ERR                        (-1)
  358. X
  359. X/*
  360. X * Undo types
  361. X */
  362. X#define SIO_UNDO_LINE        0
  363. X#define SIO_UNDO_CHAR        1
  364. X
  365. X/*
  366. X * Buffering types
  367. X */
  368. X#define SIO_FULLBUF            0
  369. X#define SIO_LINEBUF            1
  370. X#define SIO_NOBUF                2
  371. X
  372. X/*
  373. X * Descriptor for an input stream
  374. X */
  375. Xstruct __sio_input_descriptor
  376. X{
  377. X    /*
  378. X     * buf:        points to the buffer area.
  379. X     *                When doing memory mapping, it is equal to the unit 
  380. X     *                from which we are reading. When doing buffered I/O
  381. X     *                it points to the primary buffer.
  382. X     */
  383. X    char *buf ;
  384. X    unsigned buffer_size ;
  385. X
  386. X    char *start ;                 /* start of valid buffer contents       */
  387. X    char *end ;                   /* end of valid buffer contents + 1     */
  388. X    char *nextb ;                 /* pointer to next byte to read/write     */
  389. X                                            /* Always:  start <= nextb < end            */
  390. X
  391. X    unsigned line_length ;
  392. X    int max_line_length ;
  393. X    int tied_fd ;
  394. X
  395. X    int memory_mapped ;                /* flag to denote if we use                */
  396. X                                            /* memory mapping                                */
  397. X} ;
  398. X
  399. Xtypedef struct __sio_input_descriptor __sio_id_t ;
  400. X
  401. X
  402. X/*
  403. X * Descriptor for an output stream
  404. X */
  405. Xstruct __sio_output_descriptor
  406. X{
  407. X    /*
  408. X     * buf:        points to the buffer area.
  409. X     * buf_end: is equal to buf + buffer_size
  410. X     */
  411. X    char *buf ;
  412. X    char *buf_end ;
  413. X
  414. X    unsigned buffer_size ;
  415. X
  416. X    char *start ;                 /* start of valid buffer contents       */
  417. X                                            /* (used by the R and W functions)         */
  418. X    char *nextb ;                 /* pointer to next byte to read/write  */
  419. X                                            /* Always:  start <= nextb < buf_end    */
  420. X    int buftype ;                        /* type of buffering                         */
  421. X} ;
  422. X
  423. Xtypedef struct __sio_output_descriptor __sio_od_t ;
  424. X
  425. X
  426. X
  427. X/*
  428. X * Stream types
  429. X */
  430. Xenum __sio_stream { __SIO_INPUT_STREAM, __SIO_OUTPUT_STREAM } ;
  431. X
  432. X
  433. X/*
  434. X * General descriptor
  435. X */
  436. Xstruct __sio_descriptor
  437. X{
  438. X    union
  439. X    {
  440. X        __sio_id_t input_descriptor ;
  441. X        __sio_od_t output_descriptor ;
  442. X    } descriptor ;
  443. X    enum __sio_stream stream_type ;
  444. X    int initialized ;
  445. X} ;
  446. X
  447. Xtypedef struct __sio_descriptor __sio_descriptor_t ;
  448. X
  449. X
  450. X/*
  451. X * The array of descriptors (as many as available file descriptors)
  452. X */
  453. Xextern __sio_descriptor_t *__sio_descriptors ;
  454. X
  455. Xextern int errno ;
  456. X
  457. X
  458. X/*
  459. X * Internally used macros
  460. X */
  461. X#define __SIO_FD_INITIALIZED( fd )        (__sio_descriptors[ fd ].initialized)
  462. X#define __SIO_ID( fd )    (__sio_descriptors[ fd ].descriptor.input_descriptor)
  463. X#define __SIO_OD( fd )    (__sio_descriptors[ fd ].descriptor.output_descriptor)
  464. X#define __SIO_MUST_FLUSH( od, ch )                                                    \
  465. X                    ( (od).buftype != SIO_FULLBUF &&                                    \
  466. X                        ( (od).buftype == SIO_NOBUF || ch == '\n' ) )
  467. X
  468. X
  469. X/*
  470. X * SIO Macros:
  471. X *
  472. X *        SIOLINELEN( fd )
  473. X *        SIOMAXLINELEN( fd )
  474. X *        Sputchar( fd, c )
  475. X *        Sgetchar( fd )
  476. X *
  477. X * NOTE: The maximum line size depends on whether the descriptor
  478. X *            was originally memory mapped. If it was, then the maximum
  479. X *            line size will be the map_unit_size (a function of the system
  480. X *            page size and PAGES_MAPPED). Otherwise, it will be either the
  481. X *            optimal block size as reported by stat(2) or SIO_BUFFER_SIZE.
  482. X */
  483. X
  484. X#define SIOLINELEN( fd )      __SIO_ID( fd ).line_length
  485. X#define SIOMAXLINELEN( fd )                                                                    \
  486. X    (                                                                                                    \
  487. X        __SIO_FD_INITIALIZED( fd )                                                                \
  488. X            ? (                                                                                         \
  489. X                 (__sio_descriptors[ fd ].stream_type == __SIO_INPUT_STREAM)        \
  490. X                    ? __SIO_ID( fd ).max_line_length                                            \
  491. X                    : ( errno = EBADF, SIO_ERR )                                                \
  492. X              )                                                                                        \
  493. X            : (        /* not initialized; initialize it for input */                    \
  494. X                 (__sio_init( &__sio_descriptors[ fd ], fd, __SIO_INPUT_STREAM )    \
  495. X                                                                                    == SIO_ERR)        \
  496. X                    ? SIO_ERR                                                                        \
  497. X                    : __SIO_ID( fd ).max_line_length                                            \
  498. X              )                                                                                        \
  499. X    )
  500. X
  501. X
  502. X
  503. X/*
  504. X * Adds a character to a buffer, returns the character or SIO_ERR
  505. X */
  506. X#define  __SIO_ADDCHAR( od, fd, c )                                  \
  507. X     ( od.buftype == SIO_FULLBUF )                                   \
  508. X         ? (int) ( *(od.nextb)++ = (unsigned char) (c) )             \
  509. X         : ( od.buftype == SIO_LINEBUF )                             \
  510. X               ? ( ( *(od.nextb) = (unsigned char) (c) ) != '\n' )   \
  511. X                     ? (int) *(od.nextb)++                           \
  512. X                     : Sputc( fd, *(od.nextb) )                      \
  513. X               : Sputc( fd, c )
  514. X
  515. X
  516. X/*
  517. X * The Sgetchar/Sputchar macros depend on the fact that the fields 
  518. X *                 nextb, buf_end, end
  519. X * are 0 if a stream descriptor is not being used or has not yet been
  520. X * initialized.
  521. X * This is true initially because of the static allocation of the
  522. X * descriptor array, and Sdone must make sure that it is true
  523. X * after I/O on a descriptor is over.
  524. X */
  525. X#define Sputchar( fd, c )                                                        \
  526. X        (                                                                                \
  527. X            ( __SIO_OD( fd ).nextb < __SIO_OD( fd ).buf_end )            \
  528. X                ? ( __SIO_ADDCHAR( __SIO_OD( fd ), fd, c ) )                \
  529. X                : Sputc( fd, c )                                                    \
  530. X        )
  531. X
  532. X#define Sgetchar( fd )                                                    \
  533. X        (                                                                        \
  534. X            ( __SIO_ID( fd ).nextb < __SIO_ID( fd ).end )        \
  535. X                ? (int) *__SIO_ID( fd ).nextb++                         \
  536. X                : Sgetc( fd )                                                \
  537. X        )
  538. X
  539. X
  540. X#ifdef __ARGS
  541. X#undef __ARGS
  542. X#endif
  543. X
  544. X#ifdef PROTOTYPES
  545. X#    define __ARGS( s )                    s
  546. X#else
  547. X#    define __ARGS( s )                    ()
  548. X#endif
  549. X
  550. X/*
  551. X * The Read functions
  552. X */
  553. Xint Sread __ARGS( ( int fd, char *buf, int nbytes ) ) ;
  554. Xint Sgetc __ARGS( ( int fd ) ) ;
  555. Xchar *Srdline __ARGS( ( int fd ) ) ;
  556. Xchar *Sfetch __ARGS( ( int fd, long *length ) ) ;
  557. X
  558. X/*
  559. X * The Write functions
  560. X */
  561. Xint Swrite __ARGS( ( int fd, char *buf, int nbytes ) ) ;
  562. Xint Sputc __ARGS( ( int fd, char c ) ) ;
  563. Xint Sprint __ARGS( ( int fd, char *format, ... ) ) ;
  564. Xint Sprintv __ARGS( ( int fd, char *format, va_list ) ) ;
  565. X
  566. X/*
  567. X * other functions
  568. X */
  569. Xint Sdone __ARGS( ( int fd ) ) ;
  570. Xint Sundo __ARGS( ( int fd, int type ) ) ;
  571. Xint Sflush __ARGS( ( int fd ) ) ;
  572. Xint Sclose __ARGS( ( int fd ) ) ;
  573. Xint Sbuftype __ARGS( ( int fd, int type ) ) ;
  574. X
  575. X#endif /* __SIO_H */
  576. X
  577. END_OF_FILE
  578. if test 6642 -ne `wc -c <'libs/src/sio/sio.h'`; then
  579.     echo shar: \"'libs/src/sio/sio.h'\" unpacked with wrong size!
  580. fi
  581. # end of 'libs/src/sio/sio.h'
  582. fi
  583. if test -f 'libs/src/str/strs.c' -a "${1}" != "-c" ; then 
  584.   echo shar: Will not clobber existing file \"'libs/src/str/strs.c'\"
  585. else
  586. echo shar: Extracting \"'libs/src/str/strs.c'\" \(6391 characters\)
  587. sed "s/^X//" >'libs/src/str/strs.c' <<'END_OF_FILE'
  588. X/*
  589. X * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
  590. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  591. X * and conditions for redistribution.
  592. X */
  593. X
  594. Xstatic char RCSid[] = "$Id: strs.c,v 3.1 1993/06/13 02:50:39 panos Exp $" ;
  595. X
  596. X#include <ctype.h>
  597. X#include <memory.h>
  598. X#include <varargs.h>
  599. X
  600. Xchar *malloc() ;
  601. X
  602. X#include "ss_impl.h"
  603. X
  604. X/*
  605. X * NOTE: The brute force method (with the __strs_bfops) must be always 
  606. X *         available so that we can switch to it if another method fails.
  607. X */
  608. Xextern struct ss_ops __strs_bfops ;
  609. Xextern struct ss_ops __strs_rkops ;
  610. Xextern struct ss_ops __strs_kmpops ;
  611. Xextern struct ss_ops __strs_sbmops ;
  612. Xextern struct ss_ops __strs_bmhops ;
  613. Xextern struct ss_ops __strs_soops ;
  614. X
  615. X/*
  616. X * NOTE: This table is arranged according to increasing method number.
  617. X *            This allows quick indexing into it using the user-provided
  618. X *            method as a hint:
  619. X *                if ( selection_table[ user_method ].method == user_method )
  620. X *                    FOUND
  621. X *                else
  622. X *                    DO SEQUENTIAL SEARCH
  623. X *            This allows both quick access and a change of method numbers
  624. X *            in the future without requiring recompilation of programs in
  625. X *            order to work with new versions of the library.
  626. X */
  627. Xstatic struct ss_select selection_table[] =
  628. X    {
  629. X        { STRS_BF,                    &__strs_bfops        },
  630. X        { STRS_RK,                    &__strs_rkops        },
  631. X        { STRS_KMP,                    &__strs_kmpops        },
  632. X        { STRS_SBM,                    &__strs_sbmops        },
  633. X        { STRS_BMH,                    &__strs_bmhops        },
  634. X        { STRS_SO,                    &__strs_soops        },
  635. X        { 0,                            0                        }
  636. X    } ;
  637. X
  638. Xstatic char identity_map[ ALPHABET_SIZE ] ;
  639. Xstatic char upper_to_lower_map[ ALPHABET_SIZE ] ;
  640. X
  641. Xstatic int tables_initialized ;
  642. X
  643. X/*
  644. X * This header is returned when an empty pattern is given to strs_setup.
  645. X * The rest of the functions check ss_patlen and do nothing if that is zero.
  646. X * ss_patlen in this header will be initialized to zero.
  647. X */
  648. Xstatic header_s empty_pattern_header ;
  649. X
  650. X
  651. XPRIVATE void initialize_tables()
  652. X{
  653. X    int i ;
  654. X
  655. X    for ( i = 0 ; i < sizeof( upper_to_lower_map ) ; i++ )
  656. X    {
  657. X        if ( isascii( i ) && isupper( i ) )
  658. X            upper_to_lower_map[ i ] = i + 'a' - 'A' ;
  659. X        else
  660. X            upper_to_lower_map[ i ] = i ;
  661. X        identity_map[ i ] = i ;
  662. X    }
  663. X}
  664. X
  665. X
  666. X/*
  667. X * Initializes header
  668. X *
  669. X * Note that 'pattern' does not need to be a NUL-terminated string.
  670. X */
  671. XPRIVATE int init( hp, flags, pattern, patlen )
  672. X    register header_s        *hp ;
  673. X    int                        flags ;
  674. X    char                        *pattern ;
  675. X    int                        patlen ;
  676. X{
  677. X    int requested_method = SS_GETMETHOD( flags ) ;
  678. X    register struct ss_select *selp ;
  679. X
  680. X    if ( ! tables_initialized )
  681. X    {
  682. X        initialize_tables() ;
  683. X        tables_initialized = TRUE ;
  684. X    }
  685. X
  686. X    /*
  687. X     * Initialize header fields
  688. X     */
  689. X    SS_FLAGS( hp ) = SS_GETFLAGS( flags ) ;
  690. X    SS_PATLEN( hp ) = patlen ;
  691. X    if ( SS_SWITCH( hp ) && patlen < 4 )
  692. X        SS_OPS( hp ) = &__strs_bfops ;        /* brute force */
  693. X    else
  694. X    {
  695. X        /*
  696. X         * Determine ops
  697. X         */
  698. X        if ( selection_table[ requested_method ].sel_method == requested_method )
  699. X            selp = &selection_table[ requested_method ] ;
  700. X        else
  701. X            for ( selp = &selection_table[ 0 ] ; selp->sel_ops ; selp++ )
  702. X                if ( requested_method == selp->sel_method )
  703. X                    break ;
  704. X        if ( selp->sel_ops )
  705. X            SS_OPS( hp ) = selp->sel_ops ;
  706. X        else if ( SS_SWITCH( hp ) )
  707. X            SS_OPS( hp ) = &__strs_bfops ;        /* brute force */
  708. X        else
  709. X            return( SS_ERR ) ;
  710. X    }
  711. X
  712. X    if ( SS_MALLOC( hp ) )
  713. X    {
  714. X        SS_PATTERN( hp ) = malloc( (unsigned)SS_PATLEN( hp ) ) ;
  715. X        if ( SS_PATTERN( hp ) == CHAR_NULL )
  716. X        {
  717. X            (void) free( (char *)hp ) ;
  718. X            return( SS_ERR ) ;
  719. X        }
  720. X        (void) memcpy( SS_PATTERN( hp ), pattern, (int)SS_PATLEN( hp ) ) ;
  721. X    }
  722. X    else
  723. X        SS_PATTERN( hp ) = pattern ;
  724. X
  725. X    /*
  726. X     * If the user asked for case-insensitive search, we create our own
  727. X     * copy of the pattern in lower case. If the pattern is malloc'ed
  728. X     * we overwrite, otherwise we malloc some memory and clear the
  729. X     * STRS_NOMALLOC flag.
  730. X     */
  731. X    if ( SS_IGNCASE( hp ) )
  732. X    {
  733. X        char *new_pattern ;
  734. X        register int i ;
  735. X
  736. X        SS_SETMAP( hp, upper_to_lower_map ) ;
  737. X
  738. X        if ( SS_MALLOC( hp ) )
  739. X            new_pattern = SS_PATTERN( hp ) ;
  740. X        else
  741. X        {
  742. X            new_pattern = malloc( (unsigned)SS_PATLEN( hp ) + 1 ) ;
  743. X            if ( new_pattern == CHAR_NULL )
  744. X                return( SS_ERR ) ;
  745. X            SS_SETMALLOC( hp ) ;            /* clears the STRS_NOMALLOC flag */
  746. X        }
  747. X        for ( i = 0 ; i < SS_PATLEN( hp ) ; i++ )
  748. X            new_pattern[ i ] = SS_MAP( hp, SS_PATTERN( hp )[ i ] ) ;
  749. X        SS_PATTERN( hp ) = new_pattern ;
  750. X    }
  751. X    else
  752. X        SS_SETMAP( hp, identity_map ) ;
  753. X
  754. X    for ( ;; )
  755. X    {
  756. X        if ( SS_SETUP( hp ) == SS_OK )
  757. X            return( SS_OK ) ;
  758. X        else
  759. X        {
  760. X            if ( ! SS_SWITCH( hp ) || SS_OPS( hp ) == &__strs_bfops )
  761. X            {
  762. X                if ( SS_MALLOC( hp ) )
  763. X                    (void) free( (char *)hp ) ;
  764. X                return( SS_ERR ) ;
  765. X            }
  766. X            SS_OPS( hp ) = &__strs_bfops ;
  767. X        }
  768. X    }
  769. X}
  770. X
  771. X
  772. X/*
  773. X * Finalize header
  774. X */
  775. XPRIVATE void fini( hp )
  776. X    header_s *hp ;
  777. X{
  778. X    SS_DONE( hp ) ;
  779. X    if ( SS_MALLOC( hp ) )
  780. X        (void) free( SS_PATTERN( hp ) ) ;
  781. X}
  782. X
  783. X
  784. X/*
  785. X * Create a search handle
  786. X */
  787. Xstrs_h strs_setup( flags, pattern, va_alist )
  788. X    int    flags ;
  789. X    char    *pattern ;
  790. X    va_dcl
  791. X{
  792. X    header_s        *hp ;
  793. X    int            patlen ;
  794. X    va_list        ap ;
  795. X
  796. X    hp = HP( malloc( sizeof( *hp ) ) ) ;
  797. X    if ( hp == NULL )
  798. X        return( NULL_HANDLE ) ;
  799. X    
  800. X    if ( flags & STRS_PATLEN )
  801. X    {
  802. X        va_start( ap ) ;
  803. X        patlen = va_arg( ap, int ) ;
  804. X        va_end( ap ) ;
  805. X    }
  806. X    else
  807. X        patlen = strlen( pattern ) ;
  808. X
  809. X    if ( patlen == 0 )
  810. X        return( (strs_h) &empty_pattern_header ) ;
  811. X
  812. X    if ( init( hp, flags, pattern, patlen ) == SS_OK )
  813. X        return( (strs_h)hp ) ;
  814. X    else
  815. X    {
  816. X        free( (char *)hp ) ;
  817. X        return( NULL_HANDLE ) ;
  818. X    }
  819. X}
  820. X
  821. X
  822. X/*
  823. X * Destroy a search handle
  824. X */
  825. Xvoid strs_done( handle )
  826. X    strs_h handle ;
  827. X{
  828. X    header_s *hp = HP( handle ) ;
  829. X
  830. X    if ( SS_PATLEN( hp ) != 0 )
  831. X    {
  832. X        fini( hp ) ;
  833. X        (void) free( (char *) handle ) ;
  834. X    }
  835. X}
  836. X
  837. X
  838. Xchar *strs_match( handle, str, len )
  839. X    strs_h    handle ;
  840. X    char        *str ;
  841. X    int        len ;
  842. X{
  843. X    register header_s *hp = HP( handle ) ;
  844. X
  845. X    if ( SS_PATLEN( hp ) == 0 )
  846. X        return( str ) ;
  847. X    if ( SS_PATLEN( hp ) > len )
  848. X        return( CHAR_NULL ) ;
  849. X    return( SS_MATCH( hp, str, len ) ) ;
  850. X}
  851. X
  852. X
  853. X
  854. Xchar *strs_search( flags, str, len, pattern, va_alist )
  855. X    int    flags ;
  856. X    char    *str ;
  857. X    int    len ;
  858. X    char    *pattern ;            /* NUL-terminated */
  859. X    va_dcl
  860. X{
  861. X    header_s        t_header ;
  862. X    char            *p ;
  863. X    int            patlen ;
  864. X    va_list        ap ;
  865. X
  866. X    if ( flags & STRS_PATLEN )
  867. X    {
  868. X        va_start( ap ) ;
  869. X        patlen = va_arg( ap, int ) ;
  870. X        va_end( ap ) ;
  871. X    }
  872. X    else
  873. X        patlen = strlen( pattern ) ;
  874. X
  875. X    if ( patlen == 0 )
  876. X        return( str ) ;
  877. X
  878. X    if ( patlen > len )
  879. X        return( CHAR_NULL ) ;
  880. X
  881. X    if ( init( &t_header, flags | STRS_NOMALLOC, pattern, patlen ) == SS_OK )
  882. X    {
  883. X        p = SS_MATCH( &t_header, str, len ) ;
  884. X        fini( &t_header ) ;
  885. X        return( p ) ;
  886. X    }
  887. X    else
  888. X        return( CHAR_NULL ) ;
  889. X}
  890. X
  891. X
  892. END_OF_FILE
  893. if test 6391 -ne `wc -c <'libs/src/str/strs.c'`; then
  894.     echo shar: \"'libs/src/str/strs.c'\" unpacked with wrong size!
  895. fi
  896. # end of 'libs/src/str/strs.c'
  897. fi
  898. if test -f 'libs/src/xlog/xlog.3' -a "${1}" != "-c" ; then 
  899.   echo shar: Will not clobber existing file \"'libs/src/xlog/xlog.3'\"
  900. else
  901. echo shar: Extracting \"'libs/src/xlog/xlog.3'\" \(7434 characters\)
  902. sed "s/^X//" >'libs/src/xlog/xlog.3' <<'END_OF_FILE'
  903. X.\"(c) Copyright 1992, 1993 by Panagiotis Tsirigotis
  904. X.\"All rights reserved.  The file named COPYRIGHT specifies the terms 
  905. X.\"and conditions for redistribution.
  906. X.\"
  907. X.\" $Id: xlog.3,v 2.4 1993/10/28 01:36:29 panos Exp $
  908. X.TH XLOG 3X "15 June 1993"
  909. Xxlog_parms, xlog_create, xlog_destroy, xlog_write, xlog_control -- general purpose logging facility
  910. X.SH SYNOPSIS
  911. X.LP
  912. X.nf
  913. X.ft B
  914. X#include "xlog.h"
  915. X.LP
  916. X.ft B
  917. Xxlog_h xlog_create( type, id, flags, ... )
  918. Xxlog_e type ;
  919. Xchar *id ;
  920. Xint flags ;
  921. X.LP
  922. X.ft B
  923. Xint xlog_parms( type, ... )
  924. Xxlog_e type ;
  925. X.LP
  926. X.ft B
  927. Xvoid xlog_destroy( xlog )
  928. Xxlog_h xlog ;
  929. X.LP
  930. X.ft B
  931. Xvoid xlog_write( xlog, buf, len, flags, ... )
  932. Xxlog_h xlog ;
  933. Xchar buf[] ;
  934. Xint len ;
  935. Xint flags ;
  936. X.LP
  937. X.ft B
  938. Xint xlog_control( xlog, cmd, ... )
  939. Xxlog_h xlog ;
  940. Xxlog_cmd_e cmd ;
  941. X.SH DESCRIPTION
  942. XThe purpose of this library is to provide a general purpose logging facility
  943. Xby providing
  944. X.I xlogs,
  945. Xlogging objects that may be connected to various existent logging facilities.
  946. XCurrently, the only logging facilities supported are
  947. X.I "syslog(3)"
  948. Xand logging to files.
  949. XLog entries are timestamped lines which may contain arbitrary information.
  950. X.\" ********************* xlog_create ***********************
  951. X.LP
  952. X.B xlog_create()
  953. Xcreates a new xlog of the specified
  954. X.I type.
  955. XPossible type values are:
  956. X.RS
  957. X.TP 20
  958. X.SB XLOG_SYSLOG
  959. XVarargs: \fIint facility, int priority\fP.
  960. XThe xlog will be connected to 
  961. X.I "syslog(3)." 
  962. X.I facility
  963. Xdetermines the syslog facility to use for logged messages and 
  964. X.I priority
  965. Xis the default message priority.
  966. X.TP
  967. X.SB XLOG_FILELOG
  968. XVarargs: \fIchar *pathname, int flags [, int flags]\fP.
  969. XThe xlog will be connected to the file identified by
  970. X.I pathname.
  971. XThe variable part of the argument list has the same semantics as the
  972. Xargument list of the
  973. X.I "open(2)"
  974. Xsystem call.
  975. X.RE
  976. X.LP
  977. XAll xlogs have an id, specified by the 
  978. X.I id 
  979. Xargument. The
  980. X.I flags
  981. Xargument is formed by ORing one or more of the following constants:
  982. X.RS
  983. X.TP 20
  984. X.SB XLOG_NO_ERRNO
  985. Xdo not replace 
  986. X.I "%m" 
  987. Xwith an explanation of the current value of errno.
  988. X.TP
  989. X.SB XLOG_NO_SIZECHECK
  990. X.I "(XLOG_FILELOG only)"
  991. Xdo not perform size checks on the file.
  992. X.TP
  993. X.SB XLOG_PRINT_ID
  994. Xprecede each log entry with the xlog id
  995. X.TP
  996. X.SB XLOG_PRINT_PID
  997. Xprecede each log entry with the process id
  998. X(the process id will follow the xlog id)
  999. X.RE
  1000. X.LP
  1001. XFlags that do not apply to the xlog are ignored.
  1002. XThe contant
  1003. X.SM XLOG_NOFLAGS
  1004. Xcan be used if you don't want to specify any flags.
  1005. X.\" ********************* xlog_parms ***********************
  1006. X.LP
  1007. X.B xlog_parms()
  1008. Xsets default parameters for the specified xlog
  1009. X.I type:
  1010. X.RS
  1011. X.TP 20
  1012. X.SB XLOG_SYSLOG
  1013. X3 arguments are expected which correspond one-to-one to the arguments of 
  1014. X.I "openlog(3)."
  1015. XThe defaults, in case this function is not used, are:
  1016. X"XLOG", LOG_PID + LOG_NOWAIT, LOG_USER
  1017. X.TP
  1018. X.SB XLOG_FILELOG
  1019. XNo action.
  1020. X.RE
  1021. X.LP
  1022. X.B xlog_parms()
  1023. Xshould be invoked before any xlogs of the specified type
  1024. Xare created.
  1025. X.\" ********************* xlog_destroy ***********************
  1026. X.LP
  1027. X.B xlog_destroy()
  1028. Xdestroys an xlog. The action taken depends on the type of the xlog:
  1029. X.RS
  1030. X.TP 20
  1031. X.SB XLOG_SYSLOG
  1032. Xif this is the last xlog using syslog, then
  1033. X.I "closelog(3)"
  1034. Xis invoked.
  1035. X.TP
  1036. X.SB XLOG_FILELOG
  1037. XThe file is closed.
  1038. X.RE
  1039. X.\" ********************* xlog_control ***********************
  1040. X.LP
  1041. X.B xlog_control()
  1042. Xapplies control operations to an xlog. Certain operations are common to
  1043. Xall xlogs while others are type-specific. The common ones are:
  1044. X.RS
  1045. X.TP 15
  1046. X.SB XLOG_LINK
  1047. XArgument list: \fIxlog_h link_to\fP.
  1048. XLink the specified xlog to the one provided as argument.
  1049. X(if the argument is
  1050. X.SM NULL
  1051. Xany existent link is severed).
  1052. XLinking xlogs has the effect that if one finds an error it uses the
  1053. Xother to report it.
  1054. X.TP
  1055. X.SB XLOG_CALLBACK
  1056. XArgument list: \fIvoid (*callback)(), void *arg\fP.
  1057. XThis function will be invoked in case of error while writing a log
  1058. Xentry. It will be given
  1059. X3 arguments: the xlog handle, an integer that indicates the type
  1060. Xof error and the
  1061. X.I arg 
  1062. Xspecified in this call. Possible errors include:
  1063. X.RS
  1064. X.TP 15
  1065. X.SB XLOG_ENOMEM
  1066. Xlack of memory
  1067. X.TP
  1068. X.SB XLOG_EOPEN
  1069. X.I "open(2)"
  1070. Xfailed
  1071. X.TP
  1072. X.SB XLOG_EFSTAT
  1073. X.I "fstat(2)"
  1074. Xfailed
  1075. X.TP
  1076. X.SB XLOG_ESIZE
  1077. Xhard limit exceeded
  1078. X.RE
  1079. X.TP
  1080. X.SB XLOG_SETFLAG
  1081. XArgument list: \fIint flag, int *value\fP.
  1082. XThe value of
  1083. X.I flag
  1084. X(one of those listed before) is set according to
  1085. X.I "*value"
  1086. Xwhich should be either 0 or 1.
  1087. XThe old flag value is placed in 
  1088. X.I "*value."
  1089. X.TP
  1090. X.SB XLOG_GETFLAG
  1091. XArgument list: \fIint flag, int *value\fP.
  1092. XThe value of 
  1093. X.I flag
  1094. X(one of those listed before) is placed in
  1095. X.I "*value."
  1096. X.RE
  1097. X.LP
  1098. XThe type-specific operations have the following semantics when the
  1099. Xoperation is applied to an incompatible xlog: if the operation returns
  1100. Xa result to the caller (for example, check \fPXLOG_GETFD\fP), the
  1101. Xoperation will be considered to have failed, otherwise the operation
  1102. Xwill be considered successful.
  1103. X.LP
  1104. XXlogs of type
  1105. X.B XLOG_SYSLOG
  1106. Xalso support the following operations:
  1107. X.RS
  1108. X.TP 15
  1109. X.SB XLOG_FACILITY
  1110. XArgument list: \fIint facility\fP.
  1111. XSets the syslog facility to the specified value.
  1112. X.TP
  1113. X.SB XLOG_LEVEL
  1114. XArgument list: \fIint level\fP.
  1115. XSets the default syslog level for this xlog to the specified value.
  1116. X.TP
  1117. X.SB XLOG_PREEXEC
  1118. XArgument list: \fIvoid\fP.
  1119. XPrepares the xlog for an impending exec operation
  1120. X.TP
  1121. X.SB XLOG_POSTEXEC
  1122. XArgument list: \fIvoid\fP.
  1123. XInforms the xlog that the exec failed
  1124. X.RE
  1125. X.LP
  1126. XXlogs of type
  1127. X.B XLOG_FILELOG
  1128. Xalso support the following operations:
  1129. X.RS
  1130. X.TP 15
  1131. X.SB XLOG_LIMITS
  1132. XArgument list: \fIunsigned soft_limit, unsigned hard_limit\fP.
  1133. XSets soft and hard limits on the size of the file.
  1134. XWhen any of the limits is exceeded a message is sent to the linked xlog.
  1135. X(if there is no linked xlog, no message is sent)
  1136. XWhen the soft limit is exceeded a warning message is sent to the linked xlog
  1137. X(if the linked xlog is of the
  1138. X.SB XLOG_SYSLOG
  1139. Xtype, the message will be sent at the
  1140. X.I LOG_ALERT
  1141. Xlevel).
  1142. XIf the exceeded limit is the hard limit, logging is terminated.
  1143. XThe actual file size is checked every time this operation is applied to
  1144. Xthe file.
  1145. XIf logging was terminated because the hard limit was exceeded and
  1146. Xthis operation increases the hard limit beyond the actual file size,
  1147. Xlogging will be resumed.
  1148. X.TP
  1149. X.SB XLOG_SIZECHECK
  1150. XArgument list: \fIvoid\fP.
  1151. XChecks the actual file size.
  1152. X.TP
  1153. X.SB XLOG_GETFD
  1154. XArgument list: \fIint *value\fP.
  1155. XPlaces in
  1156. X.I "*value"
  1157. Xthe file descriptor of the log file.
  1158. X.RE
  1159. X.\" ********************* xlog_write ***********************
  1160. X.LP
  1161. X.B xlog_write()
  1162. Xwrites a message to the specified xlog. A
  1163. X.SM NEWLINE
  1164. Xis always appended to the message.
  1165. XThe first occurrence of "%m" in
  1166. X.I buf
  1167. Xis replaced by a string explaining the current value of
  1168. X.I errno.
  1169. XThe
  1170. X.I flags
  1171. Xargument is formed in the same way as in 
  1172. X.B xlog_create().
  1173. XOne additional constant is available:
  1174. X.RS
  1175. X.TP 20
  1176. X.SB XLOG_SET_LEVEL
  1177. X.I "(XLOG_SYSLOG only)"
  1178. Xthe next argument is an integer that should be used as the syslog level
  1179. Xfor this message instead of the default level of the xlog.
  1180. X.RE
  1181. X.SH "RETURN VALUES"
  1182. X.B xlog_create()
  1183. Xreturns an xlog handle or
  1184. X.SM NULL
  1185. Xif it fails.
  1186. X.LP
  1187. X.B xlog_control()
  1188. Xreturns an error code (it returns
  1189. X.SM XLOG_ENOERROR
  1190. Xif it is successful).
  1191. X.LP
  1192. X.B xlog_parms()
  1193. Xreturns an error code (it returns
  1194. X.SM XLOG_ENOERROR
  1195. Xif it is successful).
  1196. X.SH "SEE ALSO"
  1197. Xopenlog(3), syslog(3), closelog(3)
  1198. X.SH BUGS
  1199. X.LP
  1200. XOnly the first occurrence of
  1201. X.I "%m"
  1202. Xis replaced by an errno explanation.
  1203. X.LP
  1204. XThere is no check for cycles when linking xlogs. In particular it is
  1205. Xpossible to link a xlog to itself.
  1206. END_OF_FILE
  1207. if test 7434 -ne `wc -c <'libs/src/xlog/xlog.3'`; then
  1208.     echo shar: \"'libs/src/xlog/xlog.3'\" unpacked with wrong size!
  1209. fi
  1210. # end of 'libs/src/xlog/xlog.3'
  1211. fi
  1212. echo shar: End of archive 13 \(of 20\).
  1213. cp /dev/null ark13isdone
  1214. MISSING=""
  1215. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do
  1216.     if test ! -f ark${I}isdone ; then
  1217.     MISSING="${MISSING} ${I}"
  1218.     fi
  1219. done
  1220. if test "${MISSING}" = "" ; then
  1221.     echo You have unpacked all 20 archives.
  1222.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1223. else
  1224.     echo You still need to unpack the following archives:
  1225.     echo "        " ${MISSING}
  1226. fi
  1227. ##  End of shell archive.
  1228. exit 0
  1229.