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

1.1     ! root        1: /* rec.c
        !             2:    Routines to receive a file.
        !             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 rec_rcsid[] = "$Id: rec.c,v 1.1 93/07/30 07:53:56 bin Exp Locker: bin $";
        !            30: #endif
        !            31: 
        !            32: #include <errno.h>
        !            33: 
        !            34: #include "uudefs.h"
        !            35: #include "uuconf.h"
        !            36: #include "system.h"
        !            37: #include "prot.h"
        !            38: #include "trans.h"
        !            39: 
        !            40: /* If the other side does not tell us the size of a file it wants to
        !            41:    send us, we assume it is this long.  This is only used for free
        !            42:    space checking.  */
        !            43: #define CASSUMED_FILE_SIZE (10240)
        !            44: 
        !            45: /* We keep this information in the pinfo field of the stransfer
        !            46:    structure.  */
        !            47: struct srecinfo
        !            48: {
        !            49:   /* Local user to send mail to (may be NULL).  */
        !            50:   char *zmail;
        !            51:   /* Full file name.  */
        !            52:   char *zfile;
        !            53:   /* Temporary file name.  */
        !            54:   char *ztemp;
        !            55:   /* TRUE if this is a spool directory file.  */
        !            56:   boolean fspool;
        !            57:   /* TRUE if this was a local request.  */
        !            58:   boolean flocal;
        !            59:   /* TRUE if the file has been completely received.  */
        !            60:   boolean freceived;
        !            61:   /* TRUE if remote request has been replied to.  */
        !            62:   boolean freplied;
        !            63:   /* TRUE if we moved the file to the final destination.  */
        !            64:   boolean fmoved;
        !            65: };
        !            66: 
        !            67: /* This structure is kept in the pinfo field if we are refusing a
        !            68:    remote request.  */
        !            69: struct srecfailinfo
        !            70: {
        !            71:   /* Reason for refusal.  */
        !            72:   enum tfailure twhy;
        !            73:   /* TRUE if we have sent the reason for refusal.  */
        !            74:   boolean fsent;
        !            75:   /* TRUE if we have seen the end of the file.  */
        !            76:   boolean freceived;
        !            77: };
        !            78: 
        !            79: /* Local functions.  */
        !            80: 
        !            81: static void urrec_free P((struct stransfer *qtrans));
        !            82: static boolean flocal_rec_fail P((struct stransfer *qtrans,
        !            83:                                  struct scmd *qcmd,
        !            84:                                  const struct uuconf_system *qsys,
        !            85:                                  const char *zwhy));
        !            86: static boolean flocal_rec_send_request P((struct stransfer *qtrans,
        !            87:                                          struct sdaemon *qdaemon));
        !            88: static boolean flocal_rec_await_reply P((struct stransfer *qtrans,
        !            89:                                         struct sdaemon *qdaemon,
        !            90:                                         const char *zdata,
        !            91:                                         size_t cdata));
        !            92: static boolean fremote_send_reply P((struct stransfer *qtrans,
        !            93:                                     struct sdaemon *qdaemon));
        !            94: static boolean fremote_send_fail P((struct sdaemon *qdaemon,
        !            95:                                    struct scmd *qcmd,
        !            96:                                    enum tfailure twhy,
        !            97:                                    int iremote));
        !            98: static boolean fremote_send_fail_send P((struct stransfer *qtrans,
        !            99:                                         struct sdaemon *qdaemon));
        !           100: static boolean fremote_discard P((struct stransfer *qtrans,
        !           101:                                  struct sdaemon *qdaemon,
        !           102:                                  const char *zdata, size_t cdata));
        !           103: static boolean frec_file_end P((struct stransfer *qtrans,
        !           104:                                struct sdaemon *qdaemon,
        !           105:                                const char *zdata, size_t cdata));
        !           106: static boolean frec_file_send_confirm P((struct stransfer *qtrans,
        !           107:                                         struct sdaemon *qdaemon));
        !           108: 
        !           109: /* Free up a receive stransfer structure.  */
        !           110: 
        !           111: static void
        !           112: urrec_free (qtrans)
        !           113:      struct stransfer *qtrans;
        !           114: {
        !           115:   struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo;
        !           116: 
        !           117:   if (qinfo != NULL)
        !           118:     {
        !           119:       ubuffree (qinfo->zmail);
        !           120:       ubuffree (qinfo->zfile);
        !           121:       ubuffree (qinfo->ztemp);
        !           122:       xfree (qtrans->pinfo);
        !           123:     }
        !           124: 
        !           125:   utransfree (qtrans);
        !           126: }       
        !           127: 
        !           128: /* Set up a request for a file from the remote system.  This may be
        !           129:    called before the remote system has been called.
        !           130: 
        !           131:    This is the order of function calls:
        !           132: 
        !           133:    flocal_rec_file_init --> fqueue_local
        !           134:    flocal_rec_send_request (send R ...) --> fqueue_receive
        !           135:    flocal_rec_await_reply (open file, call pffile) --> fqueue_receive
        !           136:    receive file
        !           137:    frec_file_end (close and move file, call pffile) --> fqueue_send
        !           138:    frec_file_send_confirm (send CY)
        !           139:    */
        !           140: 
        !           141: boolean
        !           142: flocal_rec_file_init (qdaemon, qcmd)
        !           143:      struct sdaemon *qdaemon;
        !           144:      struct scmd *qcmd;
        !           145: {
        !           146:   const struct uuconf_system *qsys;
        !           147:   boolean fspool;
        !           148:   char *zfile;
        !           149:   struct srecinfo *qinfo;
        !           150:   struct stransfer *qtrans;
        !           151: 
        !           152:   qsys = qdaemon->qsys;
        !           153: 
        !           154:   /* Make sure we are permitted to transfer files.  */
        !           155:   if (qdaemon->fcaller
        !           156:       ? ! qsys->uuconf_fcall_transfer
        !           157:       : ! qsys->uuconf_fcalled_transfer)
        !           158:     {
        !           159:       /* This case will have been checked by uucp or uux, but it could
        !           160:         have changed.  */
        !           161:       if (! qsys->uuconf_fcall_transfer
        !           162:          && ! qsys->uuconf_fcalled_transfer)
        !           163:        return flocal_rec_fail ((struct stransfer *) NULL, qcmd, qsys,
        !           164:                                "not permitted to request files");
        !           165:       return TRUE;
        !           166:     }
        !           167: 
        !           168:   fspool = fspool_file (qcmd->zto);
        !           169: 
        !           170:   if (fspool)
        !           171:     {
        !           172:       pointer puuconf;
        !           173:       int iuuconf;
        !           174:       const char *zlocalname;
        !           175:       struct uuconf_system slocalsys;
        !           176: 
        !           177:       /* Normal users are not allowed to request files to be received
        !           178:         into the spool directory.  To support uux forwarding, we use
        !           179:         the special option '9'.  This permits a file to be received
        !           180:         into the spool directory for the local system only without
        !           181:         the usual checking.  This is only done for local requests, of
        !           182:         course.  */
        !           183:       if (qcmd->zto[0] != 'D'
        !           184:          || strchr (qcmd->zoptions, '9') == NULL)
        !           185:        return flocal_rec_fail ((struct stransfer *) NULL, qcmd, qsys,
        !           186:                                "not permitted to receive");
        !           187: 
        !           188:       puuconf = qdaemon->puuconf;
        !           189:       iuuconf = uuconf_localname (puuconf, &zlocalname);
        !           190:       if (iuuconf == UUCONF_NOT_FOUND)
        !           191:        {
        !           192:          zlocalname = zsysdep_localname ();
        !           193:          if (zlocalname == NULL)
        !           194:            return FALSE;
        !           195:        }
        !           196:       else if (iuuconf != UUCONF_SUCCESS)
        !           197:        {
        !           198:          ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
        !           199:          return FALSE;
        !           200:        }
        !           201: 
        !           202:       iuuconf = uuconf_system_info (puuconf, zlocalname, &slocalsys);
        !           203:       if (iuuconf == UUCONF_NOT_FOUND)
        !           204:        {
        !           205:          iuuconf = uuconf_system_local (puuconf, &slocalsys);
        !           206:          if (iuuconf != UUCONF_SUCCESS)
        !           207:            {
        !           208:              ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
        !           209:              return FALSE;
        !           210:            }
        !           211:        }
        !           212:       else if (iuuconf != UUCONF_SUCCESS)
        !           213:        {
        !           214:          ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
        !           215:          return FALSE;
        !           216:        }
        !           217: 
        !           218:       zfile = zsysdep_spool_file_name (&slocalsys, qcmd->zto, qcmd->pseq);
        !           219: 
        !           220:       (void) uuconf_system_free (puuconf, &slocalsys);
        !           221: 
        !           222:       if (zfile == NULL)
        !           223:        return FALSE;
        !           224:     }
        !           225:   else
        !           226:     {
        !           227:       zfile = zsysdep_add_base (qcmd->zto, qcmd->zfrom);
        !           228:       if (zfile == NULL)
        !           229:        return FALSE;
        !           230: 
        !           231:       /* Check permissions.  */
        !           232:       if (! fin_directory_list (zfile, qsys->uuconf_pzlocal_receive,
        !           233:                                qsys->uuconf_zpubdir, TRUE,
        !           234:                                FALSE, qcmd->zuser))
        !           235:        {
        !           236:          ubuffree (zfile);
        !           237:          return flocal_rec_fail ((struct stransfer *) NULL, qcmd, qsys,
        !           238:                                  "not permitted to receive");
        !           239:        }
        !           240: 
        !           241:       /* The 'f' option means that directories should not
        !           242:         be created if they do not already exist.  */
        !           243:       if (strchr (qcmd->zoptions, 'f') == NULL)
        !           244:        {
        !           245:          if (! fsysdep_make_dirs (zfile, TRUE))
        !           246:            {
        !           247:              ubuffree (zfile);
        !           248:              return flocal_rec_fail ((struct stransfer *) NULL, qcmd,
        !           249:                                      qsys, "cannot create directories");
        !           250:            }
        !           251:        }
        !           252:     }
        !           253: 
        !           254:   qinfo = (struct srecinfo *) xmalloc (sizeof (struct srecinfo));
        !           255:   if (strchr (qcmd->zoptions, 'm') == NULL)
        !           256:     qinfo->zmail = NULL;
        !           257:   else
        !           258:     qinfo->zmail = zbufcpy (qcmd->zuser);
        !           259:   qinfo->zfile = zfile;
        !           260:   qinfo->ztemp = NULL;
        !           261:   qinfo->fspool = fspool;
        !           262:   qinfo->flocal = TRUE;
        !           263:   qinfo->freceived = FALSE;
        !           264:   qinfo->freplied = TRUE;
        !           265: 
        !           266:   qtrans = qtransalc (qcmd);
        !           267:   qtrans->psendfn = flocal_rec_send_request;
        !           268:   qtrans->pinfo = (pointer) qinfo;
        !           269: 
        !           270:   return fqueue_local (qdaemon, qtrans);
        !           271: }
        !           272: 
        !           273: /* Report an error for a local receive request.  */
        !           274: 
        !           275: static boolean
        !           276: flocal_rec_fail (qtrans, qcmd, qsys, zwhy)
        !           277:      struct stransfer *qtrans;
        !           278:      struct scmd *qcmd;
        !           279:      const struct uuconf_system *qsys;
        !           280:      const char *zwhy;
        !           281: {
        !           282:   if (zwhy != NULL)
        !           283:     {
        !           284:       ulog (LOG_ERROR, "%s: %s", qcmd->zfrom, zwhy);
        !           285:       (void) fmail_transfer (FALSE, qcmd->zuser, (const char *) NULL, zwhy,
        !           286:                             qcmd->zfrom, qsys->uuconf_zname,
        !           287:                             qcmd->zto, (const char *) NULL,
        !           288:                             (const char *) NULL);
        !           289:       (void) fsysdep_did_work (qcmd->pseq);
        !           290:     }
        !           291:   if (qtrans != NULL)
        !           292:     urrec_free (qtrans);
        !           293:   return TRUE;
        !           294: }
        !           295: 
        !           296: /* This is called when we are ready to send the actual request to the
        !           297:    other system.  */
        !           298: 
        !           299: static boolean
        !           300: flocal_rec_send_request (qtrans, qdaemon)
        !           301:      struct stransfer *qtrans;
        !           302:      struct sdaemon *qdaemon;
        !           303: {
        !           304:   struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo;
        !           305:   long cbytes, cbytes2;
        !           306:   size_t clen;
        !           307:   char *zsend;
        !           308:   boolean fret;
        !           309: 
        !           310:   qinfo->ztemp = zsysdep_receive_temp (qdaemon->qsys, qinfo->zfile,
        !           311:                                       (const char *) NULL);
        !           312:   if (qinfo->ztemp == NULL)
        !           313:     {
        !           314:       urrec_free (qtrans);
        !           315:       return FALSE;
        !           316:     }
        !           317: 
        !           318:   /* Check the amount of free space available for both the temporary
        !           319:      file and the real file.  */
        !           320:   cbytes = csysdep_bytes_free (qinfo->ztemp);
        !           321:   cbytes2 = csysdep_bytes_free (qinfo->zfile);
        !           322:   if (cbytes < cbytes2)
        !           323:     cbytes = cbytes2;
        !           324:   if (cbytes != -1)
        !           325:     {
        !           326:       cbytes -= qdaemon->qsys->uuconf_cfree_space;
        !           327:       if (cbytes < 0)
        !           328:        cbytes = 0;
        !           329:     }
        !           330: 
        !           331:   if (qdaemon->clocal_size != -1
        !           332:       && (cbytes == -1 || qdaemon->clocal_size < cbytes))
        !           333:     cbytes = qdaemon->clocal_size;
        !           334: 
        !           335:   /* We send the string
        !           336:      R from to user options
        !           337: 
        !           338:      We put a dash in front of options.  If we are talking to a
        !           339:      counterpart, we also send the maximum size file we are prepared
        !           340:      to accept, as returned by esysdep_open_receive.  */
        !           341:   clen = (strlen (qtrans->s.zfrom) + strlen (qtrans->s.zto)
        !           342:          + strlen (qtrans->s.zuser) + strlen (qtrans->s.zoptions) + 30);
        !           343:   zsend = zbufalc (clen);
        !           344:   if ((qdaemon->ifeatures & FEATURE_SIZES) == 0)
        !           345:     sprintf (zsend, "R %s %s %s -%s", qtrans->s.zfrom, qtrans->s.zto,
        !           346:             qtrans->s.zuser, qtrans->s.zoptions);
        !           347:   else if ((qdaemon->ifeatures & FEATURE_V103) == 0)
        !           348:     sprintf (zsend, "R %s %s %s -%s 0x%lx", qtrans->s.zfrom, qtrans->s.zto,
        !           349:             qtrans->s.zuser, qtrans->s.zoptions, (unsigned long) cbytes);
        !           350:   else
        !           351:     sprintf (zsend, "R %s %s %s -%s %ld", qtrans->s.zfrom, qtrans->s.zto,
        !           352:             qtrans->s.zuser, qtrans->s.zoptions, cbytes);
        !           353: 
        !           354:   fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, zsend, qtrans->ilocal,
        !           355:                                        qtrans->iremote);
        !           356:   ubuffree (zsend);
        !           357:   if (! fret)
        !           358:     {
        !           359:       urrec_free (qtrans);
        !           360:       return FALSE;
        !           361:     }
        !           362: 
        !           363:   qtrans->fcmd = TRUE;
        !           364:   qtrans->precfn = flocal_rec_await_reply;
        !           365: 
        !           366:   return fqueue_receive (qdaemon, qtrans);
        !           367: }
        !           368: 
        !           369: /* This is called when a reply is received for the request.  */
        !           370: 
        !           371: /*ARGSUSED*/
        !           372: static boolean
        !           373: flocal_rec_await_reply (qtrans, qdaemon, zdata, cdata)
        !           374:      struct stransfer *qtrans;
        !           375:      struct sdaemon *qdaemon;
        !           376:      const char *zdata;
        !           377:      size_t cdata;
        !           378: {
        !           379:   struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo;
        !           380:   long crestart;
        !           381:   const char *zlog;
        !           382: 
        !           383:   if (zdata[0] != 'R'
        !           384:       || (zdata[1] != 'Y' && zdata[1] != 'N'))
        !           385:     {
        !           386:       ulog (LOG_ERROR, "%s: bad response to receive request: \"%s\"",
        !           387:            qtrans->s.zfrom, zdata);
        !           388:       urrec_free (qtrans);
        !           389:       return FALSE;
        !           390:     }
        !           391: 
        !           392:   if (zdata[1] == 'N')
        !           393:     {
        !           394:       boolean fnever;
        !           395:       const char *zerr;
        !           396: 
        !           397:       fnever = TRUE;
        !           398:       if (zdata[2] == '2')
        !           399:        zerr = "no such file";
        !           400:       else if (zdata[2] == '6')
        !           401:        {
        !           402:          /* We sent over the maximum file size we were prepared to
        !           403:             receive, and the remote system is telling us that the
        !           404:             file is larger than that.  Try again later.  It would be
        !           405:             better if we could know whether there will ever be enough
        !           406:             room.  */
        !           407:          zerr = "too large to receive now";
        !           408:          fnever = FALSE;
        !           409:        }
        !           410:       else
        !           411:        zerr = "unknown reason";
        !           412: 
        !           413:       if (fnever)
        !           414:        return flocal_rec_fail (qtrans, &qtrans->s, qdaemon->qsys, zerr);
        !           415: 
        !           416:       ulog (LOG_ERROR, "%s: %s", qtrans->s.zfrom, zerr);
        !           417: 
        !           418:       urrec_free (qtrans);
        !           419: 
        !           420:       return TRUE;
        !           421:     }
        !           422: 
        !           423:   /* The mode should have been sent as "RY 0%o".  If it wasn't, we use
        !           424:      0666.  */
        !           425:   qtrans->s.imode = (unsigned int) strtol ((char *) (zdata + 2),
        !           426:                                           (char **) NULL, 8);
        !           427:   if (qtrans->s.imode == 0)
        !           428:     qtrans->s.imode = 0666;
        !           429: 
        !           430:   /* Open the file to receive into.  We just ignore any restart count,
        !           431:      since we have no way to tell it to the other side.  SVR4 may have
        !           432:      some way to do this, but I don't know what it is.  */
        !           433:   qtrans->e = esysdep_open_receive (qdaemon->qsys, qinfo->zfile,
        !           434:                                    (const char *) NULL, qinfo->ztemp,
        !           435:                                    &crestart);
        !           436:   if (! ffileisopen (qtrans->e))
        !           437:     return flocal_rec_fail (qtrans, &qtrans->s, qdaemon->qsys,
        !           438:                            "cannot open file");
        !           439: 
        !           440:   if (qinfo->fspool)
        !           441:     zlog = qtrans->s.zto;
        !           442:   else
        !           443:     zlog = qinfo->zfile;
        !           444:   qtrans->zlog = zbufalc (sizeof "Receiving " + strlen (zlog));
        !           445:   sprintf (qtrans->zlog, "Receiving %s", zlog);
        !           446: 
        !           447:   if (qdaemon->qproto->pffile != NULL)
        !           448:     {
        !           449:       boolean fhandled;
        !           450: 
        !           451:       if (! (*qdaemon->qproto->pffile) (qdaemon, qtrans, TRUE, FALSE,
        !           452:                                        (long) -1, &fhandled))
        !           453:        {
        !           454:          (void) ffileclose (qtrans->e);
        !           455:          return flocal_rec_fail (qtrans, &qtrans->s, qdaemon->qsys,
        !           456:                                  (const char *) NULL);
        !           457:        }
        !           458:       if (fhandled)
        !           459:        return TRUE;
        !           460:     }
        !           461: 
        !           462:   qtrans->frecfile = TRUE;
        !           463:   qtrans->psendfn = frec_file_send_confirm;
        !           464:   qtrans->precfn = frec_file_end;
        !           465: 
        !           466:   return fqueue_receive (qdaemon, qtrans);
        !           467: }
        !           468: 
        !           469: /* Make sure there is still enough disk space available to receive a
        !           470:    file.  */
        !           471: 
        !           472: boolean
        !           473: frec_check_free (qtrans, cfree_space)
        !           474:      struct stransfer *qtrans;
        !           475:      long cfree_space;
        !           476: {
        !           477:   struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo;
        !           478:   long cfree1, cfree2;
        !           479: 
        !           480:   cfree1 = csysdep_bytes_free (qinfo->ztemp);
        !           481:   cfree2 = csysdep_bytes_free (qinfo->zfile);
        !           482:   if (cfree1 < cfree2)
        !           483:     cfree1 = cfree2;
        !           484:   if (cfree1 != -1 && cfree1 < cfree_space)
        !           485:     {
        !           486:       ulog (LOG_ERROR, "%s: too big to receive now", qinfo->zfile);
        !           487:       return FALSE;
        !           488:     }
        !           489: 
        !           490:   return TRUE;
        !           491: }
        !           492: 
        !           493: /* A remote request to send a file to the local system, meaning that
        !           494:    we are going to receive a file.
        !           495: 
        !           496:    If we are using a protocol which does not support multiple
        !           497:    channels, the remote system will not start sending us the file
        !           498:    until it has received our confirmation.  In that case, the order of
        !           499:    functions is as follows:
        !           500: 
        !           501:    fremote_send_file_init (open file) --> fqueue_remote
        !           502:    fremote_send_reply (send SY, call pffile) --> fqueue_receive
        !           503:    receive file
        !           504:    frec_file_end (close and move file, call pffile) --> fqueue_send
        !           505:    frec_file_send_confirm (send CY)
        !           506: 
        !           507:    If the protocol supports multiple channels, then the remote system
        !           508:    will start sending the file immediately after the send request.
        !           509:    That means that the data may come in before remote_send_reply is
        !           510:    called, so frec_file_end may be called before fremote_send_reply.
        !           511:    Note that this means the pffile entry points may be called in
        !           512:    reverse order for such a protocol.
        !           513: 
        !           514:    If the send request is rejected, via fremote_send_fail, and the
        !           515:    protocol supports multiple channels, we must accept and discard
        !           516:    data until a zero byte buffer is received from the other side,
        !           517:    indicating that it has received our rejection.
        !           518: 
        !           519:    This code also handles execution requests, which are very similar
        !           520:    to send requests.  */
        !           521: 
        !           522: boolean
        !           523: fremote_send_file_init (qdaemon, qcmd, iremote)
        !           524:      struct sdaemon *qdaemon;
        !           525:      struct scmd *qcmd;
        !           526:      int iremote;
        !           527: {
        !           528:   const struct uuconf_system *qsys;
        !           529:   boolean fspool;
        !           530:   char *zfile;
        !           531:   openfile_t e;
        !           532:   char *ztemp;
        !           533:   long cbytes, cbytes2;
        !           534:   long crestart;
        !           535:   struct srecinfo *qinfo;
        !           536:   struct stransfer *qtrans;
        !           537:   const char *zlog;
        !           538: 
        !           539:   qsys = qdaemon->qsys;
        !           540: 
        !           541:   if (! qsys->uuconf_frec_request)
        !           542:     {
        !           543:       ulog (LOG_ERROR, "%s: not permitted to receive files from remote",
        !           544:            qcmd->zfrom);
        !           545:       return fremote_send_fail (qdaemon, qcmd, FAILURE_PERM, iremote);
        !           546:     }
        !           547:                  
        !           548:   fspool = fspool_file (qcmd->zto);
        !           549: 
        !           550:   /* We don't accept remote command files.  An execution request may
        !           551:      only send a simple data file.  */
        !           552:   if ((fspool && qcmd->zto[0] == 'C')
        !           553:       || (qcmd->bcmd == 'E'
        !           554:          && (! fspool || qcmd->zto[0] != 'D')))
        !           555:     {
        !           556:       ulog (LOG_ERROR, "%s: not permitted to receive", qcmd->zfrom);
        !           557:       return fremote_send_fail (qdaemon, qcmd, FAILURE_PERM, iremote);
        !           558:     }
        !           559: 
        !           560:   /* See if we have already received this file in a previous
        !           561:      conversation.  */
        !           562:   if (fsysdep_already_received (qsys, qcmd->zto, qcmd->ztemp))
        !           563:     return fremote_send_fail (qdaemon, qcmd, FAILURE_RECEIVED, iremote);
        !           564: 
        !           565:   if (fspool)
        !           566:     {
        !           567:       zfile = zsysdep_spool_file_name (qsys, qcmd->zto, (pointer) NULL);
        !           568:       if (zfile == NULL)
        !           569:        return FALSE;
        !           570:     }
        !           571:   else
        !           572:     {
        !           573:       zfile = zsysdep_local_file (qcmd->zto, qsys->uuconf_zpubdir);
        !           574:       if (zfile != NULL)
        !           575:        {
        !           576:          char *zadd;
        !           577: 
        !           578:          zadd = zsysdep_add_base (zfile, qcmd->zfrom);
        !           579:          ubuffree (zfile);
        !           580:          zfile = zadd;
        !           581:        }
        !           582:       if (zfile == NULL)
        !           583:        return FALSE;
        !           584: 
        !           585:       /* Check permissions.  */
        !           586:       if (! fin_directory_list (zfile, qsys->uuconf_pzremote_receive,
        !           587:                                qsys->uuconf_zpubdir, TRUE,
        !           588:                                FALSE, (const char *) NULL))
        !           589:        {
        !           590:          ulog (LOG_ERROR, "%s: not permitted to receive", zfile);
        !           591:          ubuffree (zfile);
        !           592:          return fremote_send_fail (qdaemon, qcmd, FAILURE_PERM, iremote);
        !           593:        }
        !           594: 
        !           595:       if (strchr (qcmd->zoptions, 'f') == NULL)
        !           596:        {
        !           597:          if (! fsysdep_make_dirs (zfile, TRUE))
        !           598:            {
        !           599:              ubuffree (zfile);
        !           600:              return fremote_send_fail (qdaemon, qcmd, FAILURE_OPEN,
        !           601:                                        iremote);
        !           602:            }
        !           603:        }
        !           604:     }
        !           605: 
        !           606:   ztemp = zsysdep_receive_temp (qsys, zfile, qcmd->ztemp);
        !           607: 
        !           608:   /* Adjust the number of bytes we are prepared to receive according
        !           609:      to the amount of free space we are supposed to leave available
        !           610:      and the maximum file size we are permitted to transfer.  */
        !           611:   cbytes = csysdep_bytes_free (ztemp);
        !           612:   cbytes2 = csysdep_bytes_free (zfile);
        !           613:   if (cbytes < cbytes2)
        !           614:     cbytes = cbytes2;
        !           615: 
        !           616:   if (cbytes != -1)
        !           617:     {
        !           618:       cbytes -= qsys->uuconf_cfree_space;
        !           619:       if (cbytes < 0)
        !           620:        cbytes = 0;
        !           621:     }
        !           622: 
        !           623:   if (qdaemon->cremote_size != -1
        !           624:       && (cbytes == -1 || qdaemon->cremote_size < cbytes))
        !           625:     cbytes = qdaemon->cremote_size;
        !           626: 
        !           627:   /* If the number of bytes we are prepared to receive is less than
        !           628:      the file size, we must fail.  If the remote did not tell us the
        !           629:      file size, arbitrarily assumed that it is 10240 bytes.  */
        !           630:   if (cbytes != -1)
        !           631:     {
        !           632:       long csize;
        !           633: 
        !           634:       csize = qcmd->cbytes;
        !           635:       if (csize == -1)
        !           636:        csize = CASSUMED_FILE_SIZE;
        !           637:       if (cbytes < csize)
        !           638:        {
        !           639:          ulog (LOG_ERROR, "%s: too big to receive", zfile);
        !           640:          ubuffree (ztemp);
        !           641:          ubuffree (zfile);
        !           642:          return fremote_send_fail (qdaemon, qcmd, FAILURE_SIZE, iremote);
        !           643:        }
        !           644:     }
        !           645: 
        !           646:   /* Open the file to receive into.  This may find an old copy of the
        !           647:      file, which will be used for file restart if the other side
        !           648:      supports it.  */
        !           649:   e = esysdep_open_receive (qsys, zfile, qcmd->ztemp, ztemp, &crestart);
        !           650:   if (! ffileisopen (e))
        !           651:     {
        !           652:       ubuffree (ztemp);
        !           653:       ubuffree (zfile);
        !           654:       return fremote_send_fail (qdaemon, qcmd, FAILURE_OPEN, iremote);
        !           655:     }
        !           656: 
        !           657:   if (crestart > 0)
        !           658:     {
        !           659:       if ((qdaemon->ifeatures & FEATURE_RESTART) == 0)
        !           660:        crestart = -1;
        !           661:       else
        !           662:        {
        !           663:          DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO,
        !           664:                          "fremote_send_file_init: Restarting receive from %ld",
        !           665:                          crestart);
        !           666:          if (! ffileseek (e, crestart))
        !           667:            {
        !           668:              ulog (LOG_ERROR, "seek: %s", strerror (errno));
        !           669:              (void) ffileclose (e);
        !           670:              ubuffree (ztemp);
        !           671:              ubuffree (zfile);
        !           672:              return FALSE;
        !           673:            }
        !           674:        }
        !           675:     }
        !           676: 
        !           677:   qinfo = (struct srecinfo *) xmalloc (sizeof (struct srecinfo));
        !           678:   if (strchr (qcmd->zoptions, 'n') == NULL)
        !           679:     qinfo->zmail = NULL;
        !           680:   else
        !           681:     qinfo->zmail = zbufcpy (qcmd->znotify);
        !           682:   qinfo->zfile = zfile;
        !           683:   qinfo->ztemp = ztemp;
        !           684:   qinfo->fspool = fspool;
        !           685:   qinfo->flocal = FALSE;
        !           686:   qinfo->freceived = FALSE;
        !           687:   qinfo->freplied = FALSE;
        !           688: 
        !           689:   qtrans = qtransalc (qcmd);
        !           690:   qtrans->psendfn = fremote_send_reply;
        !           691:   qtrans->precfn = frec_file_end;
        !           692:   qtrans->iremote = iremote;
        !           693:   qtrans->pinfo = (pointer) qinfo;
        !           694:   qtrans->frecfile = TRUE;
        !           695:   qtrans->e = e;
        !           696:   if (crestart > 0)
        !           697:     qtrans->ipos = crestart;
        !           698: 
        !           699:   if (qcmd->bcmd == 'E')
        !           700:     zlog = qcmd->zcmd;
        !           701:   else
        !           702:     {
        !           703:       if (qinfo->fspool)
        !           704:        zlog = qcmd->zto;
        !           705:       else
        !           706:        zlog = qinfo->zfile;
        !           707:     }
        !           708:   qtrans->zlog = zbufalc (sizeof "Receiving " + strlen (zlog));
        !           709:   sprintf (qtrans->zlog, "Receiving %s", zlog);
        !           710: 
        !           711:   return fqueue_remote (qdaemon, qtrans);
        !           712: }
        !           713: 
        !           714: /* Reply to a send request, and prepare to receive the file.  */
        !           715: 
        !           716: static boolean
        !           717: fremote_send_reply (qtrans, qdaemon)
        !           718:      struct stransfer *qtrans;
        !           719:      struct sdaemon *qdaemon;
        !           720: {
        !           721:   struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo;
        !           722:   char ab[50];
        !           723: 
        !           724:   ab[0] = qtrans->s.bcmd;
        !           725:   ab[1] = 'Y';
        !           726:   if (qtrans->ipos <= 0)
        !           727:     ab[2] = '\0';
        !           728:   else
        !           729:     sprintf (ab + 2, " 0x%lx", (unsigned long) qtrans->ipos);
        !           730: 
        !           731:   if (! (*qdaemon->qproto->pfsendcmd) (qdaemon, ab, qtrans->ilocal,
        !           732:                                       qtrans->iremote))
        !           733:     {
        !           734:       (void) ffileclose (qtrans->e);
        !           735:       (void) remove (qinfo->ztemp);
        !           736:       urrec_free (qtrans);
        !           737:       return FALSE;
        !           738:     }
        !           739: 
        !           740:   qinfo->freplied = TRUE;
        !           741: 
        !           742:   if (qdaemon->qproto->pffile != NULL)
        !           743:     {
        !           744:       boolean fhandled;
        !           745: 
        !           746:       if (! (*qdaemon->qproto->pffile) (qdaemon, qtrans, TRUE, FALSE,
        !           747:                                        (long) -1, &fhandled))
        !           748:        {
        !           749:          (void) ffileclose (qtrans->e);
        !           750:          (void) remove (qinfo->ztemp);
        !           751:          urrec_free (qtrans);
        !           752:          return FALSE;
        !           753:        }
        !           754:       if (fhandled)
        !           755:        return TRUE;
        !           756:     }
        !           757: 
        !           758:   /* If the file has been completely received, we just want to send
        !           759:      the final confirmation.  Otherwise, we must wait for the file
        !           760:      first.  */
        !           761:   qtrans->psendfn = frec_file_send_confirm;
        !           762:   if (qinfo->freceived)
        !           763:     return fqueue_send (qdaemon, qtrans);
        !           764:   else
        !           765:     return fqueue_receive (qdaemon, qtrans);
        !           766: }
        !           767: 
        !           768: /* If we can't receive a file, queue up a response to the remote
        !           769:    system.  */
        !           770: 
        !           771: static boolean
        !           772: fremote_send_fail (qdaemon, qcmd, twhy, iremote)
        !           773:      struct sdaemon *qdaemon;
        !           774:      struct scmd *qcmd;
        !           775:      enum tfailure twhy;
        !           776:      int iremote;
        !           777: {
        !           778:   struct srecfailinfo *qinfo;
        !           779:   struct stransfer *qtrans;
        !           780: 
        !           781:   qinfo = (struct srecfailinfo *) xmalloc (sizeof (struct srecfailinfo));
        !           782:   qinfo->twhy = twhy;
        !           783:   qinfo->fsent = FALSE;
        !           784: 
        !           785:   /* If the protocol does not support multiple channels (cchans <= 1),
        !           786:      then we have essentially already received the entire file.  */
        !           787:   qinfo->freceived = qdaemon->qproto->cchans <= 1;
        !           788: 
        !           789:   qtrans = qtransalc (qcmd);
        !           790:   qtrans->psendfn = fremote_send_fail_send;
        !           791:   qtrans->precfn = fremote_discard;
        !           792:   qtrans->iremote = iremote;
        !           793:   qtrans->pinfo = (pointer) qinfo;
        !           794: 
        !           795:   return fqueue_remote (qdaemon, qtrans);
        !           796: }
        !           797: 
        !           798: /* Send a failure string for a send command to the remote system;
        !           799:    this is called when we are ready to reply to the command.  */
        !           800: 
        !           801: static boolean
        !           802: fremote_send_fail_send (qtrans, qdaemon)
        !           803:      struct stransfer *qtrans;
        !           804:      struct sdaemon *qdaemon;
        !           805: {
        !           806:   struct srecfailinfo *qinfo = (struct srecfailinfo *) qtrans->pinfo;
        !           807:   char ab[4];
        !           808:   boolean fret;
        !           809: 
        !           810:   ab[0] = qtrans->s.bcmd;
        !           811:   ab[1] = 'N';
        !           812: 
        !           813:   switch (qinfo->twhy)
        !           814:     {
        !           815:     case FAILURE_PERM:
        !           816:       ab[2] = '2';
        !           817:       break;
        !           818:     case FAILURE_OPEN:
        !           819:       ab[2] = '4';
        !           820:       break;
        !           821:     case FAILURE_SIZE:
        !           822:       ab[2] = '6';
        !           823:       break;
        !           824:     case FAILURE_RECEIVED:
        !           825:       /* Remember this file as though we successfully received it;
        !           826:         when the other side acknowledges our rejection, we know that
        !           827:         we no longer have to remember that we received this file.  */
        !           828:       usent_receive_ack (qdaemon, qtrans);
        !           829:       ab[2] = '8';
        !           830:       break;
        !           831:     default:
        !           832:       ab[2] = '\0';
        !           833:       break;
        !           834:     }
        !           835:   
        !           836:   ab[3] = '\0';
        !           837: 
        !           838:   fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, ab, qtrans->ilocal,
        !           839:                                        qtrans->iremote);
        !           840: 
        !           841:   qinfo->fsent = TRUE;
        !           842: 
        !           843:   /* Wait for the end of file marker if we haven't gotten it yet.  */
        !           844:   if (! qinfo->freceived)
        !           845:     {
        !           846:       if (! fqueue_receive (qdaemon, qtrans))
        !           847:        fret = FALSE;
        !           848:     }
        !           849:   else
        !           850:     {
        !           851:       xfree (qtrans->pinfo);
        !           852:       utransfree (qtrans);
        !           853:     }
        !           854: 
        !           855:   return fret;
        !           856: }
        !           857: 
        !           858: /* Discard data until we reach the end of the file.  This is used for
        !           859:    a protocol with multiple channels, since the remote system may
        !           860:    start sending the file before the confirmation is sent.  If we
        !           861:    refuse the file, the remote system will get us back in synch by
        !           862:    sending an empty buffer, which is what we look for here.  */
        !           863: 
        !           864: /*ARGSUSED*/
        !           865: static boolean
        !           866: fremote_discard (qtrans, qdaemon, zdata, cdata)
        !           867:      struct stransfer *qtrans;
        !           868:      struct sdaemon *qdaemon;
        !           869:      const char *zdata;
        !           870:      size_t cdata;
        !           871: {
        !           872:   struct srecfailinfo *qinfo = (struct srecfailinfo *) qtrans->pinfo;
        !           873: 
        !           874:   DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO,
        !           875:                  "fremote_discard: Discarding %lu bytes",
        !           876:                  (unsigned long) cdata);
        !           877: 
        !           878:   if (cdata != 0)
        !           879:     return TRUE;
        !           880: 
        !           881:   qinfo->freceived = TRUE;
        !           882: 
        !           883:   /* If we have already sent the denial, we are done.  */
        !           884:   if (qinfo->fsent)
        !           885:     {
        !           886:       xfree (qtrans->pinfo);
        !           887:       utransfree (qtrans);
        !           888:     }
        !           889: 
        !           890:   return TRUE;
        !           891: }
        !           892: 
        !           893: /* This is called when a file has been completely received.  It sends
        !           894:    a response to the remote system.  */
        !           895: 
        !           896: /*ARGSUSED*/
        !           897: static boolean
        !           898: frec_file_end (qtrans, qdaemon, zdata, cdata)
        !           899:      struct stransfer *qtrans;
        !           900:      struct sdaemon *qdaemon;
        !           901:      const char *zdata;
        !           902:      size_t cdata;
        !           903: {
        !           904:   struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo;
        !           905:   const char *zerr;
        !           906:   boolean fnever;
        !           907: 
        !           908:   DEBUG_MESSAGE3 (DEBUG_UUCP_PROTO, "frec_file_end: %s to %s (freplied %s)",
        !           909:                  qtrans->s.zfrom, qtrans->s.zto,
        !           910:                  qinfo->freplied ? "TRUE" : "FALSE");
        !           911: 
        !           912:   if (qdaemon->qproto->pffile != NULL)
        !           913:     {
        !           914:       boolean fhandled;
        !           915: 
        !           916:       if (! (*qdaemon->qproto->pffile) (qdaemon, qtrans, FALSE, FALSE,
        !           917:                                        (long) -1, &fhandled))
        !           918:        {
        !           919:          (void) ffileclose (qtrans->e);
        !           920:          (void) remove (qinfo->ztemp);
        !           921:          urrec_free (qtrans);
        !           922:          return FALSE;
        !           923:        }
        !           924:       if (fhandled)
        !           925:        return TRUE;
        !           926:     }
        !           927: 
        !           928:   qinfo->freceived = TRUE;
        !           929: 
        !           930:   fnever = FALSE;
        !           931: 
        !           932:   if (! ffileclose (qtrans->e))
        !           933:     {
        !           934:       zerr = strerror (errno);
        !           935:       ulog (LOG_ERROR, "%s: close: %s", qtrans->s.zto, zerr);
        !           936:     }
        !           937:   else if (! fsysdep_move_file (qinfo->ztemp, qinfo->zfile, qinfo->fspool,
        !           938:                                FALSE, ! qinfo->fspool,
        !           939:                                (qinfo->flocal
        !           940:                                 ? qtrans->s.zuser
        !           941:                                 : (const char *) NULL)))
        !           942:     {
        !           943:       zerr = "could not move to final location";
        !           944:       ulog (LOG_ERROR, "%s: %s", qinfo->zfile, zerr);
        !           945:       fnever = TRUE;
        !           946:     }
        !           947:   else
        !           948:     {
        !           949:       if (! qinfo->fspool)
        !           950:        {
        !           951:          unsigned int imode;
        !           952: 
        !           953:          /* Unless we can change the ownership of the file, the only
        !           954:             choice to make about these bits is whether to set the
        !           955:             execute bit or not.  */
        !           956:          if ((qtrans->s.imode & 0111) != 0)
        !           957:            imode = 0777;
        !           958:          else
        !           959:            imode = 0666;
        !           960:          (void) fsysdep_change_mode (qinfo->zfile, imode);
        !           961:        }
        !           962:   
        !           963:       zerr = NULL;
        !           964:     }
        !           965: 
        !           966:   if (zerr != NULL)
        !           967:     (void) remove (qinfo->ztemp);
        !           968: 
        !           969:   ustats (zerr == NULL, qtrans->s.zuser, qdaemon->qsys->uuconf_zname,
        !           970:          FALSE, qtrans->cbytes, qtrans->isecs, qtrans->imicros,
        !           971:          qdaemon->fmaster);
        !           972: 
        !           973:   if (zerr == NULL)
        !           974:     {
        !           975:       if (qinfo->zmail != NULL && *qinfo->zmail != '\0')
        !           976:        (void) fmail_transfer (TRUE, qtrans->s.zuser, qinfo->zmail,
        !           977:                               (const char *) NULL,
        !           978:                               qtrans->s.zfrom, qdaemon->qsys->uuconf_zname,
        !           979:                               qtrans->s.zto, (const char *) NULL,
        !           980:                               (const char *) NULL);
        !           981: 
        !           982:       if (qtrans->s.pseq != NULL)
        !           983:        (void) fsysdep_did_work (qtrans->s.pseq);
        !           984: 
        !           985:       if (! qinfo->flocal)
        !           986:        {
        !           987:          /* Remember that we have received this file, so that if the
        !           988:             connection drops at this point we won't receive it again.
        !           989:             We could check the return value here, but if we return
        !           990:             FALSE we couldn't do anything but drop the connection,
        !           991:             which would hardly be reasonable.  Instead we trust that
        !           992:             the administrator will notice and handle any error
        !           993:             messages, which are very unlikely to occur if everything
        !           994:             is set up correctly.  */
        !           995:          (void) fsysdep_remember_reception (qdaemon->qsys, qtrans->s.zto,
        !           996:                                             qtrans->s.ztemp);
        !           997:        }
        !           998:     }
        !           999:   else
        !          1000:     {
        !          1001:       /* If the transfer failed, we send mail if it was requested
        !          1002:         locally and if it can never succeed.  */
        !          1003:       if (qinfo->flocal && fnever)
        !          1004:        {
        !          1005:          (void) fmail_transfer (FALSE, qtrans->s.zuser, qinfo->zmail,
        !          1006:                                 zerr, qtrans->s.zfrom,
        !          1007:                                 qdaemon->qsys->uuconf_zname,
        !          1008:                                 qtrans->s.zto, (const char *) NULL,
        !          1009:                                 (const char *) NULL);
        !          1010:          (void) fsysdep_did_work (qtrans->s.pseq);
        !          1011:        }
        !          1012:     }
        !          1013: 
        !          1014:   /* If this is an execution request, we must create the execution
        !          1015:      file itself.  */
        !          1016:   if (qtrans->s.bcmd == 'E' && zerr == NULL)
        !          1017:     {
        !          1018:       char *zxqt, *zxqtfile, *ztemp;
        !          1019:       FILE *e;
        !          1020:       boolean fbad;
        !          1021: 
        !          1022:       /* We get an execution file name by simply replacing the leading
        !          1023:         D in the received file name with an X.  This pretty much
        !          1024:         always has to work since we can always receive a file name
        !          1025:         starting with X, so the system dependent code must be
        !          1026:         prepared to see one.  */
        !          1027:       zxqt = zbufcpy (qtrans->s.zto);
        !          1028:       zxqt[0] = 'X';
        !          1029:       zxqtfile = zsysdep_spool_file_name (qdaemon->qsys, zxqt,
        !          1030:                                          (pointer) NULL);
        !          1031:       ubuffree (zxqt);
        !          1032: 
        !          1033:       if (zxqtfile == NULL)
        !          1034:        {
        !          1035:          urrec_free (qtrans);
        !          1036:          return FALSE;
        !          1037:        }
        !          1038: 
        !          1039:       /* We have to write via a temporary file, because otherwise
        !          1040:         uuxqt might pick up the file before we have finished writing
        !          1041:         it.  */
        !          1042:       e = NULL;
        !          1043:       ztemp = zsysdep_receive_temp (qdaemon->qsys, zxqtfile, "D.0");
        !          1044:       if (ztemp != NULL)
        !          1045:        e = esysdep_fopen (ztemp, FALSE, FALSE, TRUE);
        !          1046: 
        !          1047:       if (e == NULL)
        !          1048:        {
        !          1049:          ubuffree (zxqtfile);
        !          1050:          ubuffree (ztemp);
        !          1051:          urrec_free (qtrans);
        !          1052:          return FALSE;
        !          1053:        }
        !          1054: 
        !          1055:       fprintf (e, "U %s %s\n", qtrans->s.zuser, qdaemon->qsys->uuconf_zname);
        !          1056:       fprintf (e, "F %s\n", qtrans->s.zto);
        !          1057:       fprintf (e, "I %s\n", qtrans->s.zto);
        !          1058:       if (strchr (qtrans->s.zoptions, 'N') != NULL)
        !          1059:        fprintf (e, "N\n");
        !          1060:       if (strchr (qtrans->s.zoptions, 'Z') != NULL)
        !          1061:        fprintf (e, "Z\n");
        !          1062:       if (strchr (qtrans->s.zoptions, 'R') != NULL)
        !          1063:        fprintf (e, "R %s\n", qtrans->s.znotify);
        !          1064:       if (strchr (qtrans->s.zoptions, 'e') != NULL)
        !          1065:        fprintf (e, "e\n");
        !          1066:       fprintf (e, "C %s\n", qtrans->s.zcmd);
        !          1067: 
        !          1068:       fbad = FALSE;
        !          1069:       if (fclose (e) == EOF)
        !          1070:        {
        !          1071:          ulog (LOG_ERROR, "fclose: %s", strerror (errno));
        !          1072:          (void) remove (ztemp);
        !          1073:          fbad = TRUE;
        !          1074:        }
        !          1075: 
        !          1076:       if (! fbad)
        !          1077:        {
        !          1078:          if (! fsysdep_move_file (ztemp, zxqtfile, TRUE, FALSE, FALSE,
        !          1079:                                   (const char *) NULL))
        !          1080:            fbad = TRUE;
        !          1081:        }
        !          1082: 
        !          1083:       ubuffree (zxqtfile);
        !          1084:       ubuffree (ztemp);
        !          1085: 
        !          1086:       if (fbad)
        !          1087:        {
        !          1088:          urrec_free (qtrans);
        !          1089:          return FALSE;
        !          1090:        }
        !          1091:     }
        !          1092: 
        !          1093:   /* Prepare to send the completion string to the remote system.  If
        !          1094:      we have not yet replied to the remote send request, we leave the
        !          1095:      transfer structure on the remote queue.  Otherwise we add it to
        !          1096:      the send queue.  The psendfn field will already be set.  */
        !          1097:   qinfo->fmoved = zerr == NULL;
        !          1098:   if (qinfo->freplied)
        !          1099:     return fqueue_send (qdaemon, qtrans);
        !          1100: 
        !          1101:   return TRUE;
        !          1102: }
        !          1103: 
        !          1104: /* Send the final confirmation string to the remote system.  */
        !          1105: 
        !          1106: static boolean
        !          1107: frec_file_send_confirm (qtrans, qdaemon)
        !          1108:      struct stransfer *qtrans;
        !          1109:      struct sdaemon *qdaemon;
        !          1110: {
        !          1111:   struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo;
        !          1112:   const char *zsend;
        !          1113:   boolean fret;
        !          1114: 
        !          1115:   if (! qinfo->fmoved)
        !          1116:     zsend = "CN5";
        !          1117:   else if (! qdaemon->frequest_hangup)
        !          1118:     zsend = "CY";
        !          1119:   else
        !          1120:     {
        !          1121: #if DEBUG > 0
        !          1122:       if (qdaemon->fmaster)
        !          1123:        ulog (LOG_FATAL, "frec_file_send_confirm: Can't happen");
        !          1124: #endif
        !          1125: 
        !          1126:       DEBUG_MESSAGE0 (DEBUG_UUCP_PROTO,
        !          1127:                      "frec_send_file_confirm: Requesting remote to transfer control");
        !          1128:       zsend = "CYM";
        !          1129:     }
        !          1130: 
        !          1131:   fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, zsend,
        !          1132:                                        qtrans->ilocal, qtrans->iremote);
        !          1133: 
        !          1134:   /* Now, if that was a remote command, then when the confirmation
        !          1135:      message is acked we no longer have to remember that we received
        !          1136:      that file.  */
        !          1137:   if (! qinfo->flocal && qinfo->fmoved)
        !          1138:     usent_receive_ack (qdaemon, qtrans);
        !          1139: 
        !          1140:   urrec_free (qtrans);
        !          1141:   return fret;
        !          1142: }
        !          1143: 
        !          1144: /* Discard a temporary file if it is not useful.  A temporary file is
        !          1145:    useful if it could be used to restart a receive.  This is called if
        !          1146:    the connection is lost.  It is only called if qtrans->frecfile is
        !          1147:    TRUE.  */
        !          1148: 
        !          1149: boolean
        !          1150: frec_discard_temp (qdaemon, qtrans)
        !          1151:      struct sdaemon *qdaemon;
        !          1152:      struct stransfer *qtrans;
        !          1153: {
        !          1154:   struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo;
        !          1155: 
        !          1156:   if ((qdaemon->ifeatures & FEATURE_RESTART) == 0
        !          1157:       || qtrans->s.ztemp == NULL
        !          1158:       || qtrans->s.ztemp[0] != 'D'
        !          1159:       || strcmp (qtrans->s.ztemp, "D.0") == 0)
        !          1160:     (void) remove (qinfo->ztemp);
        !          1161:   return TRUE;
        !          1162: }

unix.superglobalmegacorp.com

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