Annotation of coherent/g/usr/lib/uucp/tay104/chat.c, revision 1.1

1.1     ! root        1: /* chat.c
        !             2:    Chat routine for the UUCP package.
        !             3: 
        !             4:    Copyright (C) 1991, 1992 Ian Lance Taylor
        !             5: 
        !             6:    This file is part of the Taylor UUCP package.
        !             7: 
        !             8:    This program is free software; you can redistribute it and/or
        !             9:    modify it under the terms of the GNU General Public License as
        !            10:    published by the Free Software Foundation; either version 2 of the
        !            11:    License, or (at your option) any later version.
        !            12: 
        !            13:    This program is distributed in the hope that it will be useful, but
        !            14:    WITHOUT ANY WARRANTY; without even the implied warranty of
        !            15:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            16:    General Public License for more details.
        !            17: 
        !            18:    You should have received a copy of the GNU General Public License
        !            19:    along with this program; if not, write to the Free Software
        !            20:    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        !            21: 
        !            22:    The author of the program may be contacted at [email protected] or
        !            23:    c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
        !            24:    */
        !            25: 
        !            26: #include "uucp.h"
        !            27: 
        !            28: #if USE_RCS_ID
        !            29: const char chat_rcsid[] = "$Id: chat.c,v 1.1 93/07/30 07:52:38 bin Exp Locker: bin $";
        !            30: #endif
        !            31: 
        !            32: #include <ctype.h>
        !            33: #include <errno.h>
        !            34: 
        !            35: #include "uudefs.h"
        !            36: #include "uuconf.h"
        !            37: #include "conn.h"
        !            38: #include "prot.h"
        !            39: #include "system.h"
        !            40: 
        !            41: /* Local functions.  */
        !            42: 
        !            43: static int icexpect P((struct sconnection *qconn, int cstrings,
        !            44:                       char **azstrings, size_t *aclens,
        !            45:                       int ctimeout, boolean fstrip));
        !            46: static boolean fcsend P((struct sconnection *qconn, pointer puuconf,
        !            47:                         const char *zsend,
        !            48:                         const struct uuconf_system *qsys,
        !            49:                         const struct uuconf_dialer *qdial,
        !            50:                         const char *zphone,
        !            51:                         boolean ftranslate, boolean fstrip));
        !            52: static boolean fcecho_send_strip P((struct sconnection *qconn,
        !            53:                                    const char *z, size_t clen));
        !            54: static boolean fcecho_send_nostrip P((struct sconnection  *qconn,
        !            55:                                      const char *z, size_t clen));
        !            56: static boolean fcecho_send P((struct sconnection *qconn, const char *z,
        !            57:                              size_t clen, boolean fstrip));
        !            58: static boolean fcphone P((struct sconnection *qconn,
        !            59:                          pointer puuconf,
        !            60:                          const struct uuconf_dialer *qdial,
        !            61:                          const char *zphone,
        !            62:                          boolean (*pfwrite) P((struct sconnection *qc,
        !            63:                                                const char *zwrite,
        !            64:                                                size_t cwrite)),
        !            65:                          boolean ftranslate, boolean *pfquote));
        !            66: static boolean fctranslate P((pointer puuconf, const char *zphone,
        !            67:                              const char **pzprefix,
        !            68:                              const char **pzsuffix));
        !            69: static boolean fcprogram P((struct sconnection *qconn, pointer puuconf,
        !            70:                            char **pzprogram,
        !            71:                            const struct uuconf_system *qsys,
        !            72:                            const struct uuconf_dialer *qdial,
        !            73:                            const char *zphone, const char *zport,
        !            74:                            long ibaud));
        !            75: 
        !            76: /* Run a chat script with the other system.  The chat script is a
        !            77:    series of expect send pairs.  We wait for the expect string to show
        !            78:    up, and then we send the send string.  The chat string for a system
        !            79:    holds the expect and send strings separated by a single space.  */
        !            80: 
        !            81: boolean
        !            82: fchat (qconn, puuconf, qchat, qsys, qdial, zphone, ftranslate, zport, ibaud)
        !            83:      struct sconnection *qconn;
        !            84:      pointer puuconf;
        !            85:      const struct uuconf_chat *qchat;
        !            86:      const struct uuconf_system *qsys;
        !            87:      const struct uuconf_dialer *qdial;
        !            88:      const char *zphone;
        !            89:      boolean ftranslate;
        !            90:      const char *zport;
        !            91:      long ibaud;
        !            92: {
        !            93:   int cstrings;
        !            94:   char **azstrings;
        !            95:   size_t *aclens;
        !            96:   char **pzchat;
        !            97:   char *zbuf;
        !            98:   size_t cbuflen;
        !            99:   boolean fret;
        !           100:   int i;
        !           101: 
        !           102:   /* First run the program, if any.  */
        !           103:   if (qchat->uuconf_pzprogram != NULL)
        !           104:     {
        !           105:       if (! fcprogram (qconn, puuconf, qchat->uuconf_pzprogram, qsys, qdial,
        !           106:                       zphone, zport, ibaud))
        !           107:        return FALSE;
        !           108:     }
        !           109: 
        !           110:   /* If there's no chat script, we're done.  */
        !           111:   if (qchat->uuconf_pzchat == NULL)
        !           112:     return TRUE;
        !           113: 
        !           114:   if (qchat->uuconf_pzfail == NULL)
        !           115:     {
        !           116:       cstrings = 1;
        !           117:       azstrings = (char **) xmalloc (sizeof (char *));
        !           118:       aclens = (size_t *) xmalloc (sizeof (size_t));
        !           119:     }
        !           120:   else
        !           121:     {
        !           122:       char **pz;
        !           123: 
        !           124:       /* We leave string number 0 for the chat script.  */
        !           125:       cstrings = 1;
        !           126:       for (pz = qchat->uuconf_pzfail; *pz != NULL; pz++)
        !           127:        ++cstrings;
        !           128: 
        !           129:       azstrings = (char **) xmalloc (cstrings * sizeof (char *));
        !           130:       aclens = (size_t *) xmalloc (cstrings * sizeof (size_t));
        !           131: 
        !           132:       /* Get the strings into the array, and handle all the escape
        !           133:         characters.  */
        !           134:       for (cstrings = 1, pz = qchat->uuconf_pzfail;
        !           135:           *pz != NULL;
        !           136:           cstrings++, pz++)
        !           137:        {
        !           138:          azstrings[cstrings] = zbufcpy (*pz);
        !           139:          aclens[cstrings] = cescape (azstrings[cstrings]);
        !           140:        }
        !           141:     }
        !           142: 
        !           143:   cbuflen = 0;
        !           144:   zbuf = NULL;
        !           145:   fret = TRUE;
        !           146: 
        !           147:   pzchat = qchat->uuconf_pzchat;
        !           148: 
        !           149:   while (*pzchat != NULL)
        !           150:     {
        !           151:       size_t clen;
        !           152: 
        !           153:       /* Loop over subexpects and subsends.  */
        !           154:       while (TRUE)
        !           155:        {
        !           156:          /* Copy the expect string into the buffer so that we can
        !           157:             modify it in cescape.  */
        !           158:          clen = strlen (*pzchat);
        !           159:          if (clen >= cbuflen)
        !           160:            {
        !           161:              ubuffree (zbuf);
        !           162:              zbuf = zbufalc (clen + 1);
        !           163:              cbuflen = clen;
        !           164:            }
        !           165:          memcpy (zbuf, *pzchat, clen + 1);
        !           166: 
        !           167:          azstrings[0] = zbuf;
        !           168:          if (azstrings[0][0] == '-')
        !           169:            ++azstrings[0];
        !           170:          aclens[0] = cescape (azstrings[0]);
        !           171: 
        !           172:          if (aclens[0] == 0
        !           173:              || (aclens[0] == 2
        !           174:                  && strcmp (azstrings[0], "\"\"") == 0))
        !           175:            {
        !           176:              /* There is no subexpect sequence.  If there is a
        !           177:                 subsend sequence we move on to it.  Otherwise we let
        !           178:                 this expect succeed.  This is somewhat inconsistent,
        !           179:                 but it seems to be the traditional approach.  */
        !           180:              if (pzchat[1] == NULL || pzchat[1][0] != '-')
        !           181:                break;
        !           182:            }
        !           183:          else
        !           184:            {
        !           185:              int istr;
        !           186: 
        !           187:              istr = icexpect (qconn, cstrings, azstrings, aclens,
        !           188:                               qchat->uuconf_ctimeout,
        !           189:                               qchat->uuconf_fstrip);
        !           190: 
        !           191:              /* If we found the string, break out of the
        !           192:                 subexpect/subsend loop.  */
        !           193:              if (istr == 0)
        !           194:                break;
        !           195: 
        !           196:              /* If we got an error, return FALSE.  */
        !           197:              if (istr < -1)
        !           198:                {
        !           199:                  fret = FALSE;
        !           200:                  break;
        !           201:                }
        !           202: 
        !           203:              /* If we found a failure string, log it and get out.  */
        !           204:              if (istr > 0)
        !           205:                {
        !           206:                  ulog (LOG_ERROR, "Chat script failed: Got \"%s\"",
        !           207:                        qchat->uuconf_pzfail[istr - 1]);
        !           208:                  fret = FALSE;
        !           209:                  break;
        !           210:                }
        !           211: 
        !           212:              /* We timed out; look for a send subsequence.  If none,
        !           213:                 the chat script has failed.  */
        !           214:              if (pzchat[1] == NULL || pzchat[1][0] != '-')
        !           215:                {
        !           216:                  ulog (LOG_ERROR, "Timed out in chat script");
        !           217:                  fret = FALSE;
        !           218:                  break;
        !           219:                }
        !           220:            }
        !           221: 
        !           222:          /* Send the send subsequence without the leading '-'.  A
        !           223:             \"\" will send nothing.  An empty string will send a
        !           224:             carriage return.  */
        !           225:          ++pzchat;
        !           226:          if (! fcsend (qconn, puuconf, *pzchat + 1, qsys, qdial, zphone,
        !           227:                        ftranslate, qchat->uuconf_fstrip))
        !           228:            {
        !           229:              fret = FALSE;
        !           230:              break;
        !           231:            }
        !           232: 
        !           233:          /* If there is no expect subsequence, we are done.  */
        !           234:          if (pzchat[1] == NULL || pzchat[1][0] != '-')
        !           235:            break;
        !           236: 
        !           237:          /* Move on to next expect subsequence.  */
        !           238:          ++pzchat;
        !           239:        }
        !           240: 
        !           241:       if (! fret)
        !           242:        break;
        !           243: 
        !           244:       /* Move on to the send string.  If there is none, we have
        !           245:         succeeded.  */
        !           246:       do
        !           247:        {
        !           248:          ++pzchat;
        !           249:        }
        !           250:       while (*pzchat != NULL && (*pzchat)[0] == '-');
        !           251: 
        !           252:       if (*pzchat == NULL)
        !           253:        break;
        !           254: 
        !           255:       if (**pzchat != '\0')
        !           256:        {
        !           257:          if (! fcsend (qconn, puuconf, *pzchat, qsys, qdial, zphone,
        !           258:                        ftranslate, qchat->uuconf_fstrip))
        !           259:            {
        !           260:              fret = FALSE;
        !           261:              break;
        !           262:            }
        !           263:        }
        !           264: 
        !           265:       ++pzchat;
        !           266:     }
        !           267: 
        !           268:   ubuffree (zbuf);
        !           269:   for (i = 1; i < cstrings; i++)
        !           270:     ubuffree (azstrings[i]);
        !           271:   xfree ((pointer) azstrings);
        !           272:   xfree ((pointer) aclens);
        !           273: 
        !           274:   return fret;
        !           275: }
        !           276: 
        !           277: /* Read characters and wait for one of a set of memory strings to come
        !           278:    in.  This returns the index into the array of the string that
        !           279:    arrives, or -1 on timeout, or -2 on error.  */
        !           280: 
        !           281: static int
        !           282: icexpect (qconn, cstrings, azstrings, aclens, ctimeout, fstrip)
        !           283:      struct sconnection *qconn;
        !           284:      int cstrings;
        !           285:      char **azstrings;
        !           286:      size_t *aclens;
        !           287:      int ctimeout;
        !           288:      boolean fstrip;
        !           289: {
        !           290:   int i;
        !           291:   size_t cmax;
        !           292:   char *zhave;
        !           293:   size_t chave;
        !           294:   long iendtime;
        !           295: #if DEBUG > 1
        !           296:   int cchars;
        !           297:   int iolddebug;
        !           298: #endif
        !           299: 
        !           300:   cmax = aclens[0];
        !           301:   for (i = 1; i < cstrings; i++)
        !           302:     if (cmax < aclens[i])
        !           303:       cmax = aclens[i];
        !           304: 
        !           305:   zhave = zbufalc (cmax);
        !           306:   chave = 0;
        !           307: 
        !           308:   iendtime = ixsysdep_time ((long *) NULL) + ctimeout;
        !           309: 
        !           310: #if DEBUG > 1
        !           311:   cchars = 0;
        !           312:   iolddebug = iDebug;
        !           313:   if (FDEBUGGING (DEBUG_CHAT))
        !           314:     {
        !           315:       udebug_buffer ("icexpect: Looking for", azstrings[0],
        !           316:                     aclens[0]);
        !           317:       ulog (LOG_DEBUG_START, "icexpect: Got \"");
        !           318:       iDebug &=~ (DEBUG_INCOMING | DEBUG_PORT);
        !           319:     }
        !           320: #endif
        !           321: 
        !           322:   while (TRUE)
        !           323:     {
        !           324:       int bchar;
        !           325: 
        !           326:       /* If we have no more time, get out.  */
        !           327:       if (ctimeout <= 0)
        !           328:        {
        !           329: #if DEBUG > 1
        !           330:          if (FDEBUGGING (DEBUG_CHAT))
        !           331:            {
        !           332:              ulog (LOG_DEBUG_END, "\" (timed out)");
        !           333:              iDebug = iolddebug;
        !           334:            }
        !           335: #endif
        !           336:          ubuffree (zhave);
        !           337:          return -1;
        !           338:        }
        !           339: 
        !           340:       /* Read one character at a time.  We could use a more complex
        !           341:         algorithm to read in larger batches, but it's probably not
        !           342:         worth it.  If the buffer is full, shift it left; we already
        !           343:         know that no string matches, and the buffer holds the largest
        !           344:         string, so this can't lose a match.  */
        !           345:       if (chave >= cmax)
        !           346:        {
        !           347:          size_t imove;
        !           348: 
        !           349:          for (imove = 0; imove < cmax - 1; imove++)
        !           350:            zhave[imove] = zhave[imove + 1];
        !           351:          --chave;
        !           352:        }
        !           353: 
        !           354:       /* The timeout/error return values from breceive_char are the
        !           355:         same as for this function.  */
        !           356:       bchar = breceive_char (qconn, ctimeout, TRUE);
        !           357:       if (bchar < 0)
        !           358:        {
        !           359: #if DEBUG > 1
        !           360:          if (FDEBUGGING (DEBUG_CHAT))
        !           361:            {
        !           362:              /* If there was an error, it will probably be logged in
        !           363:                 the middle of our string, but this is only debugging
        !           364:                 so it's not a big deal.  */
        !           365:              ulog (LOG_DEBUG_END, "\" (%s)",
        !           366:                    bchar == -1 ? "timed out" : "error");
        !           367:              iDebug = iolddebug;
        !           368:            }
        !           369: #endif
        !           370:          ubuffree (zhave);
        !           371:          return bchar;
        !           372:        }
        !           373: 
        !           374:       /* Strip the parity bit if desired.  */
        !           375:       if (fstrip)
        !           376:        bchar &= 0x7f;
        !           377: 
        !           378:       zhave[chave] = (char) bchar;
        !           379:       ++chave;
        !           380: 
        !           381: #if DEBUG > 1
        !           382:       if (FDEBUGGING (DEBUG_CHAT))
        !           383:        {
        !           384:          char ab[5];
        !           385: 
        !           386:          ++cchars;
        !           387:          if (cchars > 60)
        !           388:            {
        !           389:              ulog (LOG_DEBUG_END, "\"");
        !           390:              ulog (LOG_DEBUG_START, "icexpect: Got \"");
        !           391:              cchars = 0;
        !           392:            }
        !           393:          (void) cdebug_char (ab, bchar);
        !           394:          ulog (LOG_DEBUG_CONTINUE, "%s", ab);
        !           395:        }
        !           396: #endif
        !           397: 
        !           398:       /* See if any of the strings can be found in the buffer.  Since
        !           399:         we read one character at a time, the string can only be found
        !           400:         at the end of the buffer.  */
        !           401:       for (i = 0; i < cstrings; i++)
        !           402:        {
        !           403:          if (aclens[i] <= chave
        !           404:              && memcmp (zhave + chave - aclens[i], azstrings[i],
        !           405:                         aclens[i]) == 0)
        !           406:            {
        !           407: #if DEBUG > 1
        !           408:              if (FDEBUGGING (DEBUG_CHAT))
        !           409:                {
        !           410:                  if (i == 0)
        !           411:                    ulog (LOG_DEBUG_END, "\" (found it)");
        !           412:                  else
        !           413:                    {
        !           414:                      ulog (LOG_DEBUG_END, "\"");
        !           415:                      udebug_buffer ("icexpect: Found", azstrings[i],
        !           416:                                     aclens[i]);
        !           417:                    }
        !           418:                  iDebug = iolddebug;
        !           419:                }
        !           420: #endif
        !           421:              ubuffree (zhave);
        !           422:              return i;
        !           423:            }
        !           424:        }
        !           425: 
        !           426:       ctimeout = (int) (iendtime - ixsysdep_time ((long *) NULL));
        !           427:     }
        !           428: }
        !           429: 
        !           430: #if DEBUG > 1
        !           431: 
        !           432: /* Debugging function for fcsend.  This takes the fquote variable, the
        !           433:    length of the string (0 if this an informational string which can
        !           434:    be printed directly) and the string itself.  It returns the new
        !           435:    value for fquote.  The fquote variable is TRUE if the debugging
        !           436:    output is in the middle of a quoted string.  */
        !           437: 
        !           438: static size_t cCsend_chars;
        !           439: static int iColddebug;
        !           440: 
        !           441: static boolean fcsend_debug P((boolean, size_t, const char *));
        !           442: 
        !           443: static boolean
        !           444: fcsend_debug (fquote, clen, zbuf)
        !           445:      boolean fquote;
        !           446:      size_t clen;
        !           447:      const char *zbuf;
        !           448: {
        !           449:   size_t cwas;
        !           450: 
        !           451:   if (! FDEBUGGING (DEBUG_CHAT))
        !           452:     return TRUE;
        !           453: 
        !           454:   cwas = cCsend_chars;
        !           455:   if (clen > 0)
        !           456:     cCsend_chars += clen;
        !           457:   else
        !           458:     cCsend_chars += strlen (zbuf);
        !           459:   if (cCsend_chars > 60 && cwas > 10)
        !           460:     {
        !           461:       ulog (LOG_DEBUG_END, "%s", fquote ? "\"" : "");
        !           462:       fquote = FALSE;
        !           463:       ulog (LOG_DEBUG_START, "fcsend: Writing");
        !           464:       cCsend_chars = 0;
        !           465:     }
        !           466: 
        !           467:   if (clen == 0)
        !           468:     {
        !           469:       ulog (LOG_DEBUG_CONTINUE, "%s %s", fquote ? "\"" : "", zbuf);
        !           470:       return FALSE;
        !           471:     }
        !           472:   else
        !           473:     {
        !           474:       int i;
        !           475: 
        !           476:       if (! fquote)
        !           477:        ulog (LOG_DEBUG_CONTINUE, " \"");
        !           478:       for (i = 0; i < clen; i++)
        !           479:        {
        !           480:          char ab[5];
        !           481: 
        !           482:          (void) cdebug_char (ab, zbuf[i]);
        !           483:          ulog (LOG_DEBUG_CONTINUE, "%s", ab);
        !           484:        }
        !           485: 
        !           486:       return TRUE;
        !           487:     }
        !           488: }
        !           489: 
        !           490: /* Finish up the debugging information for fcsend.  */
        !           491: 
        !           492: static void ucsend_debug_end P((boolean, boolean));
        !           493: 
        !           494: static void
        !           495: ucsend_debug_end (fquote, ferr)
        !           496:      boolean fquote;
        !           497:      boolean ferr;
        !           498: {
        !           499:   if (! FDEBUGGING (DEBUG_CHAT))
        !           500:     return;
        !           501: 
        !           502:   if (fquote)
        !           503:     ulog (LOG_DEBUG_CONTINUE, "\"");
        !           504: 
        !           505:   if (ferr)
        !           506:     ulog (LOG_DEBUG_CONTINUE, " (error)");
        !           507: 
        !           508:   ulog (LOG_DEBUG_END, "%s", "");
        !           509: 
        !           510:   iDebug = iColddebug;
        !           511: }
        !           512: 
        !           513: #else /* DEBUG <= 1 */
        !           514: 
        !           515: /* Use macro definitions to make fcsend look neater.  */
        !           516: 
        !           517: #define fcsend_debug(fquote, clen, zbuf) TRUE
        !           518: 
        !           519: #define ucsend_debug_end(fquote, ferror)
        !           520: 
        !           521: #endif /* DEBUG <= 1 */
        !           522: 
        !           523: /* Send a string out.  This has to parse escape sequences as it goes.
        !           524:    Note that it handles the dialer escape sequences (\e, \E, \D, \T)
        !           525:    although they make no sense for chatting with a system.  */
        !           526: 
        !           527: static boolean
        !           528: fcsend (qconn, puuconf, z, qsys, qdial, zphone, ftranslate, fstrip)
        !           529:      struct sconnection *qconn;
        !           530:      pointer puuconf;
        !           531:      const char *z;
        !           532:      const struct uuconf_system *qsys;
        !           533:      const struct uuconf_dialer *qdial;
        !           534:      const char *zphone;
        !           535:      boolean ftranslate;
        !           536:      boolean fstrip;
        !           537: {
        !           538:   boolean fnocr;
        !           539:   boolean (*pfwrite) P((struct sconnection *, const char *, size_t));
        !           540:   char *zcallout_login;
        !           541:   char *zcallout_pass;
        !           542:   boolean fquote;
        !           543: 
        !           544:   if (strcmp (z, "\"\"") == 0)
        !           545:     return TRUE;
        !           546: 
        !           547:   fnocr = FALSE;
        !           548:   pfwrite = fconn_write;
        !           549:   zcallout_login = NULL;
        !           550:   zcallout_pass = NULL;
        !           551: 
        !           552: #if DEBUG > 1
        !           553:   if (FDEBUGGING (DEBUG_CHAT))
        !           554:     {
        !           555:       ulog (LOG_DEBUG_START, "fcsend: Writing");
        !           556:       fquote = FALSE;
        !           557:       cCsend_chars = 0;
        !           558:       iColddebug = iDebug;
        !           559:       iDebug &=~ (DEBUG_OUTGOING | DEBUG_PORT);
        !           560:     }
        !           561: #endif
        !           562: 
        !           563:   while (*z != '\0')
        !           564:     {
        !           565:       const char *zlook;
        !           566:       boolean fsend;
        !           567:       char bsend;
        !           568: 
        !           569:       zlook = z + strcspn ((char *) z, "\\BE");
        !           570: 
        !           571:       if (zlook > z)
        !           572:        {
        !           573:          size_t c;
        !           574: 
        !           575:          c = zlook - z;
        !           576:          fquote = fcsend_debug (fquote, c, z);
        !           577:          if (! (*pfwrite) (qconn, z, c))
        !           578:            {
        !           579:              ucsend_debug_end (fquote, TRUE);
        !           580:              return FALSE;
        !           581:            }
        !           582:        }
        !           583: 
        !           584:       if (*zlook == '\0')
        !           585:        break;
        !           586: 
        !           587:       z = zlook;
        !           588: 
        !           589:       fsend = FALSE;
        !           590:       switch (*z)
        !           591:        {
        !           592:        case 'B':
        !           593:          if (strncmp (z, "BREAK", 5) == 0)
        !           594:            {
        !           595:              fquote = fcsend_debug (fquote, (size_t) 0, "break");
        !           596:              if (! fconn_break (qconn))
        !           597:                {
        !           598:                  ucsend_debug_end (fquote, TRUE);
        !           599:                  return FALSE;
        !           600:                }
        !           601:              fnocr = TRUE;
        !           602:              z += 5;
        !           603:            }
        !           604:          else
        !           605:            {
        !           606:              fsend = TRUE;
        !           607:              bsend = 'B';
        !           608:              ++z;
        !           609:            }
        !           610:          break;
        !           611:        case 'E':
        !           612:          if (strncmp (z, "EOT", 3) == 0)
        !           613:            {
        !           614:              fsend = TRUE;
        !           615:              bsend = '\004';
        !           616:              fnocr = TRUE;
        !           617:              z += 3;
        !           618:            }
        !           619:          else
        !           620:            {
        !           621:              fsend = TRUE;
        !           622:              bsend = 'E';
        !           623:              ++z;
        !           624:            }
        !           625:          break;
        !           626:        case '\\':
        !           627:          ++z;
        !           628:          switch (*z)
        !           629:            {
        !           630:            case '-':
        !           631:              fsend = TRUE;
        !           632:              bsend = '-';
        !           633:              break;
        !           634:            case 'b':
        !           635:              fsend = TRUE;
        !           636:              bsend = '\b';
        !           637:              break;
        !           638:            case 'c':
        !           639:              fnocr = TRUE;
        !           640:              break;
        !           641:            case 'd':
        !           642:              fquote = fcsend_debug (fquote, (size_t) 0, "sleep");
        !           643:              usysdep_sleep (2);
        !           644:              break;
        !           645:            case 'e':
        !           646:              fquote = fcsend_debug (fquote, (size_t) 0, "echo-check-off");
        !           647:              pfwrite = fconn_write;
        !           648:              break;
        !           649:            case 'E':
        !           650:              fquote = fcsend_debug (fquote, (size_t) 0, "echo-check-on");
        !           651:              if (fstrip)
        !           652:                pfwrite = fcecho_send_strip;
        !           653:              else
        !           654:                pfwrite = fcecho_send_nostrip;
        !           655:              break;
        !           656:            case 'K':
        !           657:              fquote = fcsend_debug (fquote, (size_t) 0, "break");
        !           658:              if (! fconn_break (qconn))
        !           659:                {
        !           660:                  ucsend_debug_end (fquote, TRUE);
        !           661:                  return FALSE;
        !           662:                }
        !           663:              break;
        !           664:            case 'n':
        !           665:              fsend = TRUE;
        !           666:              bsend = '\n';
        !           667:              break;
        !           668:            case 'N':
        !           669:              fsend = TRUE;
        !           670:              bsend = '\0';
        !           671:              break;
        !           672:            case 'p':
        !           673:              fquote = fcsend_debug (fquote, (size_t) 0, "pause");
        !           674:              usysdep_pause ();
        !           675:              break;
        !           676:            case 'r':
        !           677:              fsend = TRUE;
        !           678:              bsend = '\r';
        !           679:              break;
        !           680:            case 's':
        !           681:              fsend = TRUE;
        !           682:              bsend = ' ';
        !           683:              break;
        !           684:            case 't':
        !           685:              fsend = TRUE;
        !           686:              bsend = '\t';
        !           687:              break;
        !           688:            case '\0':
        !           689:              --z;
        !           690:              /* Fall through.  */
        !           691:            case '\\':
        !           692:              fsend = TRUE;
        !           693:              bsend = '\\';
        !           694:              break;
        !           695:            case '0': case '1': case '2': case '3': case '4':
        !           696:            case '5': case '6': case '7': case '8': case '9':
        !           697:              fsend = TRUE;
        !           698:              bsend = *z - '0';
        !           699:              if (z[1] >= '0' && z[1] <= '7')
        !           700:                bsend = (char) (8 * bsend + *++z - '0');
        !           701:              if (z[1] >= '0' && z[1] <= '7')
        !           702:                bsend = (char) (8 * bsend + *++z - '0');
        !           703:              break;
        !           704:            case 'x':
        !           705:              fsend = TRUE;
        !           706:              bsend = 0;
        !           707:              while (isxdigit (BUCHAR (z[1])))
        !           708:                {
        !           709:                  if (isdigit (BUCHAR (z[1])))
        !           710:                    bsend = (char) (16 * bsend + *++z - '0');
        !           711:                  else if (isupper (BUCHAR (z[1])))
        !           712:                    bsend = (char) (16 * bsend + *++z - 'A');
        !           713:                  else
        !           714:                    bsend = (char) (16 * bsend + *++z - 'a');
        !           715:                }
        !           716:              break;
        !           717:            case 'L':
        !           718:              {
        !           719:                const char *zlog;
        !           720: 
        !           721:                if (qsys == NULL)
        !           722:                  {
        !           723:                    ucsend_debug_end (fquote, TRUE);
        !           724:                    ulog (LOG_ERROR, "Illegal use of \\L");
        !           725:                    return FALSE;
        !           726:                  }
        !           727:                zlog = qsys->uuconf_zcall_login;
        !           728:                if (zlog == NULL)
        !           729:                  {
        !           730:                    ucsend_debug_end (fquote, TRUE);
        !           731:                    ulog (LOG_ERROR, "No login defined");
        !           732:                    return FALSE;
        !           733:                  }
        !           734:                if (zlog[0] == '*' && zlog[1] == '\0')
        !           735:                  {
        !           736:                    if (zcallout_login == NULL)
        !           737:                      {
        !           738:                        int iuuconf;
        !           739: 
        !           740:                        iuuconf = uuconf_callout (puuconf, qsys,
        !           741:                                                  &zcallout_login,
        !           742:                                                  &zcallout_pass);
        !           743:                        if (iuuconf == UUCONF_NOT_FOUND
        !           744:                            || zcallout_login == NULL)
        !           745:                          {
        !           746:                            ucsend_debug_end (fquote, TRUE);
        !           747:                            ulog (LOG_ERROR, "No login defined");
        !           748:                            return FALSE;
        !           749:                          }
        !           750:                        else if (iuuconf != UUCONF_SUCCESS)
        !           751:                          {
        !           752:                            ucsend_debug_end (fquote, TRUE);
        !           753:                            ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
        !           754:                            return FALSE;
        !           755:                          }
        !           756:                      }
        !           757:                    zlog = zcallout_login;
        !           758:                  }
        !           759:                fquote = fcsend_debug (fquote, (size_t) 0, "login");
        !           760:                fquote = fcsend_debug (fquote, strlen (zlog), zlog);
        !           761:                if (! (*pfwrite) (qconn, zlog, strlen (zlog)))
        !           762:                  {
        !           763:                    ucsend_debug_end (fquote, TRUE);
        !           764:                    return FALSE;
        !           765:                  }
        !           766:              }
        !           767:              break;
        !           768:            case 'P':
        !           769:              {
        !           770:                const char *zpass;
        !           771: 
        !           772:                if (qsys == NULL)
        !           773:                  {
        !           774:                    ucsend_debug_end (fquote, TRUE);
        !           775:                    ulog (LOG_ERROR, "Illegal use of \\P");
        !           776:                    return FALSE;
        !           777:                  }
        !           778:                zpass = qsys->uuconf_zcall_password;
        !           779:                if (zpass == NULL)
        !           780:                  {
        !           781:                    ucsend_debug_end (fquote, TRUE);
        !           782:                    ulog (LOG_ERROR, "No password defined");
        !           783:                    return FALSE;
        !           784:                  }
        !           785:                if (zpass[0] == '*' && zpass[1] == '\0')
        !           786:                  {
        !           787:                    if (zcallout_pass == NULL)
        !           788:                      {
        !           789:                        int iuuconf;
        !           790: 
        !           791:                        iuuconf = uuconf_callout (puuconf, qsys,
        !           792:                                                  &zcallout_login,
        !           793:                                                  &zcallout_pass);
        !           794:                        if (iuuconf == UUCONF_NOT_FOUND
        !           795:                            || zcallout_pass == NULL)
        !           796:                          {
        !           797:                            ucsend_debug_end (fquote, TRUE);
        !           798:                            ulog (LOG_ERROR, "No password defined");
        !           799:                            return FALSE;
        !           800:                          }
        !           801:                        else if (iuuconf != UUCONF_SUCCESS)
        !           802:                          {
        !           803:                            ucsend_debug_end (fquote, TRUE);
        !           804:                            ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
        !           805:                            return FALSE;
        !           806:                          }
        !           807:                      }
        !           808:                    zpass = zcallout_pass;
        !           809:                  }
        !           810:                fquote = fcsend_debug (fquote, (size_t) 0, "password");
        !           811:                fquote = fcsend_debug (fquote, strlen (zpass), zpass);
        !           812:                if (! (*pfwrite) (qconn, zpass, strlen (zpass)))
        !           813:                  {
        !           814:                    ucsend_debug_end (fquote, TRUE);
        !           815:                    return FALSE;
        !           816:                  }
        !           817:              }
        !           818:              break;
        !           819:            case 'D':
        !           820:              if (qdial == NULL || zphone == NULL)
        !           821:                {
        !           822:                  ucsend_debug_end (fquote, TRUE);
        !           823:                  ulog (LOG_ERROR, "Illegal use of \\D");
        !           824:                  return FALSE;
        !           825:                }
        !           826:              fquote = fcsend_debug (fquote, (size_t) 0, "\\D");
        !           827:              if (! fcphone (qconn, puuconf, qdial, zphone, pfwrite,
        !           828:                             ftranslate, &fquote))
        !           829:                {
        !           830:                  ucsend_debug_end (fquote, TRUE);
        !           831:                  return FALSE;
        !           832:                }
        !           833:              break;
        !           834:            case 'T':
        !           835:              if (qdial == NULL || zphone == NULL)
        !           836:                {
        !           837:                  ucsend_debug_end (fquote, TRUE);
        !           838:                  ulog (LOG_ERROR, "Illegal use of \\T");
        !           839:                  return FALSE;
        !           840:                }
        !           841:              fquote = fcsend_debug (fquote, (size_t) 0, "\\T");
        !           842:              if (! fcphone (qconn, puuconf, qdial, zphone, pfwrite, TRUE,
        !           843:                             &fquote))
        !           844:                {
        !           845:                  ucsend_debug_end (fquote, TRUE);
        !           846:                  return FALSE;
        !           847:                }
        !           848:              break;
        !           849:            case 'M':
        !           850:              if (qdial == NULL)
        !           851:                {
        !           852:                  ucsend_debug_end (fquote, TRUE);
        !           853:                  ulog (LOG_ERROR, "Illegal use of \\M");
        !           854:                  return FALSE;
        !           855:                }
        !           856:              fquote = fcsend_debug (fquote, (size_t) 0, "ignore-carrier");
        !           857:              if (! fconn_carrier (qconn, FALSE))
        !           858:                {
        !           859:                  ucsend_debug_end (fquote, TRUE);
        !           860:                  return FALSE;
        !           861:                }
        !           862:              break;
        !           863:            case 'm':
        !           864:              if (qdial == NULL)
        !           865:                {
        !           866:                  ucsend_debug_end (fquote, TRUE);
        !           867:                  ulog (LOG_ERROR, "Illegal use of \\m");
        !           868:                  return FALSE;
        !           869:                }
        !           870:              if (qdial->uuconf_fcarrier)
        !           871:                {
        !           872:                  fquote = fcsend_debug (fquote, (size_t) 0, "need-carrier");
        !           873:                  if (! fconn_carrier (qconn, TRUE))
        !           874:                    {
        !           875:                      ucsend_debug_end (fquote, TRUE);
        !           876:                      return FALSE;
        !           877:                    }
        !           878:                }
        !           879:              break;
        !           880:            default:
        !           881:              /* This error message will screw up any debugging
        !           882:                 information, but it's easily avoidable.  */
        !           883:              ulog (LOG_ERROR,
        !           884:                    "Unrecognized escape sequence \\%c in send string",
        !           885:                    *z);
        !           886:              fsend = TRUE;
        !           887:              bsend = *z;
        !           888:              break;
        !           889:            }
        !           890:          ++z;
        !           891:          break;
        !           892: #if DEBUG > 0
        !           893:        default:
        !           894:          ulog (LOG_FATAL, "fcsend: Can't happen");
        !           895:          break;
        !           896: #endif
        !           897:        }
        !           898:       
        !           899:       if (fsend)
        !           900:        {
        !           901:          fquote = fcsend_debug (fquote, (size_t) 1, &bsend);
        !           902:          if (! (*pfwrite) (qconn, &bsend, (size_t) 1))
        !           903:            {
        !           904:              ucsend_debug_end (fquote, TRUE);
        !           905:              return FALSE;
        !           906:            }
        !           907:        }
        !           908:     }
        !           909: 
        !           910:   xfree ((pointer) zcallout_login);
        !           911:   xfree ((pointer) zcallout_pass);
        !           912: 
        !           913:   /* Output a final carriage return, unless there was a \c.  Don't
        !           914:      bother to check for an echo.  */
        !           915:   if (! fnocr)
        !           916:     {
        !           917:       char b;
        !           918: 
        !           919:       b = '\r';
        !           920:       fquote = fcsend_debug (fquote, (size_t) 1, &b);
        !           921:       if (! fconn_write (qconn, &b, (size_t) 1))
        !           922:        {
        !           923:          ucsend_debug_end (fquote, TRUE);
        !           924:          return FALSE;
        !           925:        }
        !           926:     }
        !           927: 
        !           928:   ucsend_debug_end (fquote, FALSE);
        !           929: 
        !           930:   return TRUE;
        !           931: }
        !           932: 
        !           933: /* Write out a phone number with optional dialcode translation.  The
        !           934:    pfquote argument is only used for debugging.  */
        !           935: 
        !           936: static boolean
        !           937: fcphone (qconn, puuconf, qdial, zphone, pfwrite, ftranslate, pfquote)
        !           938:      struct sconnection *qconn;
        !           939:      pointer puuconf;
        !           940:      const struct uuconf_dialer *qdial;
        !           941:      const char *zphone;
        !           942:      boolean (*pfwrite) P((struct sconnection *qc, const char *zwrite,
        !           943:                           size_t cwrite));
        !           944:      boolean ftranslate;
        !           945:      boolean *pfquote;
        !           946: {
        !           947:   const char *zprefix, *zsuffix;
        !           948: 
        !           949:   if (ftranslate)
        !           950:     {
        !           951:       if (! fctranslate (puuconf, zphone, &zprefix, &zsuffix))
        !           952:        return FALSE;
        !           953:     }
        !           954:   else
        !           955:     {
        !           956:       zprefix = zphone;
        !           957:       zsuffix = NULL;
        !           958:     }
        !           959: 
        !           960:   while (zprefix != NULL)
        !           961:     {
        !           962:       while (TRUE)
        !           963:        {
        !           964:          const char *z;
        !           965:          const char *zstr;
        !           966: 
        !           967:          z = zprefix + strcspn ((char *) zprefix, "=-");
        !           968:          if (z > zprefix)
        !           969:            {
        !           970:              size_t clen;
        !           971: 
        !           972:              clen = z - zprefix;
        !           973:              *pfquote = fcsend_debug (*pfquote, clen, zprefix);
        !           974:              if (! (*pfwrite) (qconn, zprefix, clen))
        !           975:                return FALSE;
        !           976:            }
        !           977: 
        !           978:          if (*z == '=')
        !           979:            zstr = qdial->uuconf_zdialtone;
        !           980:          else if (*z == '-')
        !           981:            zstr = qdial->uuconf_zpause;
        !           982:          else                  /* *z == '\0' */
        !           983:            break;
        !           984: 
        !           985:          if (zstr != NULL)
        !           986:            {
        !           987:              *pfquote = fcsend_debug (*pfquote, strlen (zstr), zstr);
        !           988:              if (! (*pfwrite) (qconn, zstr, strlen (zstr)))
        !           989:                return FALSE;
        !           990:            }
        !           991: 
        !           992:          zprefix = z + 1;
        !           993:        }
        !           994: 
        !           995:       zprefix = zsuffix;
        !           996:       zsuffix = NULL;
        !           997:     }
        !           998: 
        !           999:   return TRUE;
        !          1000: }
        !          1001: 
        !          1002: /* Given a phone number, run it through dial code translation
        !          1003:    returning two strings.  */
        !          1004: 
        !          1005: static boolean
        !          1006: fctranslate (puuconf, zphone, pzprefix, pzsuffix)
        !          1007:      pointer puuconf;
        !          1008:      const char *zphone;
        !          1009:      const char **pzprefix;
        !          1010:      const char **pzsuffix;
        !          1011: {
        !          1012:   int iuuconf;
        !          1013:   char *zdialcode, *zto;
        !          1014:   const char *zfrom;
        !          1015:   char *ztrans;
        !          1016: 
        !          1017:   *pzprefix = zphone;
        !          1018:   *pzsuffix = NULL;
        !          1019: 
        !          1020:   zdialcode = zbufalc (strlen (zphone) + 1);
        !          1021:   zfrom = zphone;
        !          1022:   zto = zdialcode;
        !          1023:   while (*zfrom != '\0' && isalpha (BUCHAR (*zfrom)))
        !          1024:     *zto++ = *zfrom++;
        !          1025:   *zto = '\0';
        !          1026: 
        !          1027:   if (*zdialcode == '\0')
        !          1028:     {
        !          1029:       ubuffree (zdialcode);
        !          1030:       return TRUE;
        !          1031:     }
        !          1032: 
        !          1033:   iuuconf = uuconf_dialcode (puuconf, zdialcode, &ztrans);
        !          1034: 
        !          1035:   ubuffree (zdialcode);
        !          1036: 
        !          1037:   if (iuuconf == UUCONF_NOT_FOUND)
        !          1038:     return TRUE;
        !          1039:   else if (iuuconf != UUCONF_SUCCESS)
        !          1040:     {
        !          1041:       ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
        !          1042:       return FALSE;
        !          1043:     }
        !          1044:   else
        !          1045:     {
        !          1046:       /* We really should figure out a way to free up ztrans here.  */
        !          1047:       *pzprefix = ztrans;
        !          1048:       *pzsuffix = zfrom;
        !          1049:       return TRUE;
        !          1050:     }
        !          1051: }
        !          1052: 
        !          1053: /* Write out a string making sure the each character is echoed back.
        !          1054:    There are two versions of this function, one which strips the
        !          1055:    parity bit from the characters and one which does not.  This is so
        !          1056:    that I can use a single function pointer in fcsend, and to avoid
        !          1057:    using any static variables so that I can put chat scripts in a
        !          1058:    library some day.  */
        !          1059: 
        !          1060: static boolean
        !          1061: fcecho_send_strip (qconn, zwrite, cwrite)
        !          1062:      struct sconnection *qconn;
        !          1063:      const char *zwrite;
        !          1064:      size_t cwrite;
        !          1065: {
        !          1066:   return fcecho_send (qconn, zwrite, cwrite, TRUE);
        !          1067: }
        !          1068: 
        !          1069: static boolean
        !          1070: fcecho_send_nostrip (qconn, zwrite, cwrite)
        !          1071:      struct sconnection *qconn;
        !          1072:      const char *zwrite;
        !          1073:      size_t cwrite;
        !          1074: {
        !          1075:   return fcecho_send (qconn, zwrite, cwrite, FALSE);
        !          1076: }
        !          1077: 
        !          1078: static boolean
        !          1079: fcecho_send (qconn, zwrite, cwrite, fstrip)
        !          1080:      struct sconnection *qconn;
        !          1081:      const char *zwrite;
        !          1082:      size_t cwrite;
        !          1083:      boolean fstrip;
        !          1084: {
        !          1085:   const char *zend;
        !          1086: 
        !          1087:   zend = zwrite + cwrite;
        !          1088: 
        !          1089:   for (; zwrite < zend; zwrite++)
        !          1090:     {
        !          1091:       int b;
        !          1092:       char bwrite;
        !          1093: 
        !          1094:       bwrite = *zwrite;
        !          1095:       if (! fconn_write (qconn, &bwrite, (size_t) 1))
        !          1096:        return FALSE;
        !          1097:       if (fstrip)
        !          1098:        bwrite &= 0x7f;
        !          1099:       do
        !          1100:        {
        !          1101:          /* We arbitrarily wait five seconds for the echo.  */
        !          1102:          b = breceive_char (qconn, 5, TRUE);
        !          1103:          /* Now b == -1 on timeout, -2 on error.  */
        !          1104:          if (b < 0)
        !          1105:            {
        !          1106:              if (b == -1)
        !          1107:                ulog (LOG_ERROR, "Character not echoed");
        !          1108:              return FALSE;
        !          1109:            }
        !          1110:          if (fstrip)
        !          1111:            b &= 0x7f;
        !          1112:        }
        !          1113:       while (b != BUCHAR (bwrite));
        !          1114:     }
        !          1115: 
        !          1116:   return TRUE;
        !          1117: }
        !          1118: 
        !          1119: /* Run a chat program.  Expand any escape sequences and call a system
        !          1120:    dependent program to run it.  */
        !          1121: 
        !          1122: static boolean
        !          1123: fcprogram (qconn, puuconf, pzprogram, qsys, qdial, zphone, zport, ibaud)
        !          1124:      struct sconnection *qconn;
        !          1125:      pointer puuconf;
        !          1126:      char **pzprogram;
        !          1127:      const struct uuconf_system *qsys;
        !          1128:      const struct uuconf_dialer *qdial;
        !          1129:      const char *zphone;
        !          1130:      const char *zport;
        !          1131:      long ibaud;
        !          1132: {
        !          1133:   size_t cargs;
        !          1134:   char **pzpass, **pzarg;
        !          1135:   char **pz;
        !          1136:   char *zcallout_login;
        !          1137:   char *zcallout_pass;
        !          1138:   boolean fret;
        !          1139: 
        !          1140:   cargs = 1;
        !          1141:   for (pz = pzprogram; *pz != NULL; pz++)
        !          1142:     ++cargs;
        !          1143: 
        !          1144:   pzpass = (char **) xmalloc (cargs * sizeof (char *));
        !          1145: 
        !          1146:   zcallout_login = NULL;
        !          1147:   zcallout_pass = NULL;
        !          1148:   fret = TRUE;
        !          1149: 
        !          1150:   /* Copy the string into memory expanding escape sequences.  */
        !          1151:   for (pz = pzprogram, pzarg = pzpass; *pz != NULL; pz++, pzarg++)
        !          1152:     {
        !          1153:       const char *zfrom;
        !          1154:       size_t calc, clen;
        !          1155:       char *zto;
        !          1156: 
        !          1157:       if (strchr (*pz, '\\') == NULL)
        !          1158:        {
        !          1159:          *pzarg = zbufcpy (*pz);
        !          1160:          continue;
        !          1161:        }
        !          1162:       
        !          1163:       *pzarg = NULL;
        !          1164:       zto = NULL;
        !          1165:       calc = 0;
        !          1166:       clen = 0;
        !          1167: 
        !          1168:       for (zfrom = *pz; *zfrom != '\0'; zfrom++)
        !          1169:        {
        !          1170:          const char *zadd = NULL;
        !          1171:          size_t cadd;
        !          1172:          char abadd[15];
        !          1173: 
        !          1174:          if (*zfrom != '\\')
        !          1175:            {
        !          1176:              if (clen + 2 > calc)
        !          1177:                {
        !          1178:                  char *znew;
        !          1179: 
        !          1180:                  calc = clen + 50;
        !          1181:                  znew = zbufalc (calc);
        !          1182:                  memcpy (znew, *pzarg, clen);
        !          1183:                  ubuffree (*pzarg);
        !          1184:                  *pzarg = znew;
        !          1185:                  zto = znew + clen;
        !          1186:                }
        !          1187:              *zto++ = *zfrom;
        !          1188:              ++clen;
        !          1189:              continue;
        !          1190:            }
        !          1191: 
        !          1192:          ++zfrom;
        !          1193:          switch (*zfrom)
        !          1194:            {
        !          1195:            case '\0':
        !          1196:              --zfrom;
        !          1197:              /* Fall through.  */
        !          1198:            case '\\':
        !          1199:              zadd = "\\";
        !          1200:              break;
        !          1201:            case 'L':
        !          1202:              {
        !          1203:                const char *zlog;
        !          1204: 
        !          1205:                if (qsys == NULL)
        !          1206:                  {
        !          1207:                    ulog (LOG_ERROR, "chat-program: Illegal use of \\L");
        !          1208:                    fret = FALSE;
        !          1209:                    break;
        !          1210:                  }
        !          1211:                zlog = qsys->uuconf_zcall_login;
        !          1212:                if (zlog == NULL)
        !          1213:                  {
        !          1214:                    ulog (LOG_ERROR, "chat-program: No login defined");
        !          1215:                    fret = FALSE;
        !          1216:                    break;
        !          1217:                  }
        !          1218:                if (zlog[0] == '*' && zlog[1] == '\0')
        !          1219:                  {
        !          1220:                    if (zcallout_login == NULL)
        !          1221:                      {
        !          1222:                        int iuuconf;
        !          1223: 
        !          1224:                        iuuconf = uuconf_callout (puuconf, qsys,
        !          1225:                                                  &zcallout_login,
        !          1226:                                                  &zcallout_pass);
        !          1227:                        if (iuuconf == UUCONF_NOT_FOUND
        !          1228:                            || zcallout_login == NULL)
        !          1229:                          {
        !          1230:                            ulog (LOG_ERROR,
        !          1231:                                  "chat-program: No login defined");
        !          1232:                            fret = FALSE;
        !          1233:                            break;
        !          1234:                          }
        !          1235:                        else if (iuuconf != UUCONF_SUCCESS)
        !          1236:                          {
        !          1237:                            ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
        !          1238:                            fret = FALSE;
        !          1239:                            break;
        !          1240:                          }
        !          1241:                      }
        !          1242:                    zlog = zcallout_login;
        !          1243:                  }
        !          1244:                zadd = zlog;
        !          1245:              }
        !          1246:              break;
        !          1247:            case 'P':
        !          1248:              {
        !          1249:                const char *zpass;
        !          1250: 
        !          1251:                if (qsys == NULL)
        !          1252:                  {
        !          1253:                    ulog (LOG_ERROR, "chat-program: Illegal use of \\P");
        !          1254:                    fret = FALSE;
        !          1255:                    break;
        !          1256:                  }
        !          1257:                zpass = qsys->uuconf_zcall_password;
        !          1258:                if (zpass == NULL)
        !          1259:                  {
        !          1260:                    ulog (LOG_ERROR, "chat-program: No password defined");
        !          1261:                    fret = FALSE;
        !          1262:                    break;
        !          1263:                  }
        !          1264:                if (zpass[0] == '*' && zpass[1] == '\0')
        !          1265:                  {
        !          1266:                    if (zcallout_pass == NULL)
        !          1267:                      {
        !          1268:                        int iuuconf;
        !          1269: 
        !          1270:                        iuuconf = uuconf_callout (puuconf, qsys,
        !          1271:                                                  &zcallout_login,
        !          1272:                                                  &zcallout_pass);
        !          1273:                        if (iuuconf == UUCONF_NOT_FOUND
        !          1274:                            || zcallout_pass == NULL)
        !          1275:                          {
        !          1276:                            ulog (LOG_ERROR,
        !          1277:                                  "chat-program: No password defined");
        !          1278:                            fret = FALSE;
        !          1279:                            break;
        !          1280:                          }
        !          1281:                        else if (iuuconf != UUCONF_SUCCESS)
        !          1282:                          {
        !          1283:                            ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
        !          1284:                            fret = FALSE;
        !          1285:                            break;
        !          1286:                          }
        !          1287:                      }
        !          1288:                    zpass = zcallout_pass;
        !          1289:                  }
        !          1290:                zadd = zpass;
        !          1291:              }
        !          1292:              break;
        !          1293:            case 'D':
        !          1294:              if (qdial == NULL || zphone == NULL)
        !          1295:                {
        !          1296:                  ulog (LOG_ERROR, "chat-program: Illegal use of \\D");
        !          1297:                  fret = FALSE;
        !          1298:                  break;
        !          1299:                }
        !          1300:              zadd = zphone;
        !          1301:              break;
        !          1302:            case 'T':
        !          1303:              {
        !          1304:                const char *zprefix, *zsuffix;
        !          1305: 
        !          1306:                if (qdial == NULL || zphone == NULL)
        !          1307:                  {
        !          1308:                    ulog (LOG_ERROR, "chat-program: Illegal use of \\T");
        !          1309:                    fret = FALSE;
        !          1310:                    break;
        !          1311:                  }
        !          1312: 
        !          1313:                if (! fctranslate (puuconf, zphone, &zprefix, &zsuffix))
        !          1314:                  {
        !          1315:                    fret = FALSE;
        !          1316:                    break;
        !          1317:                  }
        !          1318: 
        !          1319:                if (zsuffix == NULL)
        !          1320:                  zadd = zprefix;
        !          1321:                else
        !          1322:                  {
        !          1323:                    size_t cprefix;
        !          1324: 
        !          1325:                    cprefix = strlen (zprefix);
        !          1326:                    if (clen + cprefix + 1 > calc)
        !          1327:                      {
        !          1328:                        char *znew;
        !          1329: 
        !          1330:                        calc = clen + cprefix + 20;
        !          1331:                        znew = zbufalc (calc);
        !          1332:                        memcpy (znew, *pzarg, clen);
        !          1333:                        ubuffree (*pzarg);
        !          1334:                        *pzarg = znew;
        !          1335:                        zto = znew + clen;
        !          1336:                      }
        !          1337:                    memcpy (zto, zprefix, cprefix);
        !          1338:                    zto += cprefix;
        !          1339:                    clen += cprefix;
        !          1340:                    zadd = zsuffix;
        !          1341:                  }
        !          1342:              }
        !          1343:              break;
        !          1344:            case 'Y':
        !          1345:              if (zLdevice == NULL && zport == NULL)
        !          1346:                {
        !          1347:                  ulog (LOG_ERROR, "chat-program: Illegal use of \\Y");
        !          1348:                  fret = FALSE;
        !          1349:                  break;
        !          1350:                }
        !          1351:              /* zLdevice will generally make more sense than zport, but
        !          1352:                 it might not be set yet.  */
        !          1353:              zadd = zLdevice;
        !          1354:              if (zadd == NULL)
        !          1355:                zadd = zport;
        !          1356:              break;
        !          1357:            case 'Z':
        !          1358:              if (qsys == NULL)
        !          1359:                {
        !          1360:                  ulog (LOG_ERROR, "chat-program: Illegal use of \\Z");
        !          1361:                  fret = FALSE;
        !          1362:                  break;
        !          1363:                }
        !          1364:              zadd = qsys->uuconf_zname;
        !          1365:              break;
        !          1366:            case 'S':
        !          1367:              {
        !          1368:                if (ibaud == 0)
        !          1369:                  {
        !          1370:                    ulog (LOG_ERROR, "chat-program: Illegal use of \\S");
        !          1371:                    fret = FALSE;
        !          1372:                    break;
        !          1373:                  }
        !          1374:                sprintf (abadd, "%ld", ibaud);
        !          1375:                zadd = abadd;
        !          1376:              }
        !          1377:              break;
        !          1378:            default:
        !          1379:              {
        !          1380:                ulog (LOG_ERROR,
        !          1381:                      "chat-program: Unrecognized escape sequence \\%c",
        !          1382:                      *zfrom);
        !          1383:                abadd[0] = *zfrom;
        !          1384:                abadd[1] = '\0';
        !          1385:                zadd = abadd;
        !          1386:              }
        !          1387:              break;
        !          1388:            }
        !          1389: 
        !          1390:          if (! fret)
        !          1391:            break;
        !          1392: 
        !          1393:          cadd = strlen (zadd);
        !          1394:          if (clen + cadd + 1 > calc)
        !          1395:            {
        !          1396:              char *znew;
        !          1397: 
        !          1398:              calc = clen + cadd + 20;
        !          1399:              znew = zbufalc (calc);
        !          1400:              memcpy (znew, *pzarg, clen);
        !          1401:              ubuffree (*pzarg);
        !          1402:              *pzarg = znew;
        !          1403:              zto = znew + clen;
        !          1404:            }
        !          1405:          memcpy (zto, zadd, cadd + 1);
        !          1406:          zto += cadd;
        !          1407:          clen += cadd;
        !          1408:        }
        !          1409: 
        !          1410:       if (! fret)
        !          1411:        break;
        !          1412: 
        !          1413:       *zto++ = '\0';
        !          1414:       ++clen;
        !          1415:     }
        !          1416: 
        !          1417:   *pzarg = NULL;
        !          1418: 
        !          1419:   if (fret)
        !          1420:     fret = fconn_run_chat (qconn, pzpass);
        !          1421: 
        !          1422:   for (pz = pzpass; *pz != NULL; pz++)
        !          1423:     ubuffree (*pz);
        !          1424:   xfree ((pointer) pzpass);
        !          1425:   xfree ((pointer) zcallout_login);
        !          1426:   xfree ((pointer) zcallout_pass);
        !          1427: 
        !          1428:   return fret;
        !          1429: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.