home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / k95source / p_callbk.c < prev    next >
C/C++ Source or Header  |  2003-05-01  |  47KB  |  1,509 lines

  1. /*****************************************************************************/
  2. /*             Copyright (c) 1994 by Jyrki Salmi <jytasa@jyu.fi>             */
  3. /*        You may modify, recompile and distribute this file freely.         */
  4. /*****************************************************************************/
  5.  
  6. /*
  7.    Callback functions called by P.DLL
  8. */
  9.  
  10. #include "ckcdeb.h"
  11. #ifndef NOXFER
  12. #ifdef XYZ_INTERNAL
  13. #include "ckcker.h"
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <fcntl.h>
  19. #include <sys\types.h>
  20. #include <sys\stat.h>
  21. #include <sys\utime.h>
  22. #include <share.h>
  23. #include <time.h>
  24. #include <ctype.h>
  25. #include <errno.h>
  26.  
  27. #ifdef OS2
  28. #ifdef NT
  29. #include <windows.h>
  30. #else
  31. #define INCL_DOSPROCESS
  32. #include <os2.h>
  33. #undef COMMENT
  34. #endif
  35. #include "ckocon.h"
  36. #endif /* OS2 */
  37.  
  38. #ifdef NT
  39. #define msleep Sleep
  40. #define DosBeep Beep
  41. #define filelength _filelength
  42. #define fstat _fstat
  43. #define unlink _unlink
  44. #define stat _stat
  45. #endif /* NT */
  46.  
  47. extern int keep, moving;                /* fdc */
  48. extern char * cmarg, * cmarg2;                  /* fdc */
  49. extern char filnam[], *srvcmd;  /* jaltman */
  50. extern int nfils, fnspath, fncnv, binary, sendmode, sndsrc ;
  51. extern long sendstart ;
  52. extern char *zinptr, *zoutptr;
  53. extern int zincnt, zoutcnt, fncact;
  54. extern long ffc, filcnt, fsize, cps, oldcps ;
  55. extern int fsecs, tsecs, rejection, timeouts, crunched, retrans ;
  56. extern int savfnc, cxseen, czseen, discard ;
  57. extern int atcapr, atdati, atdato;
  58. #ifdef GFTIMER
  59. extern CKFLOAT fpfsecs, fpxfsecs;
  60. extern CKFLOAT gtv, oldgtv;
  61. #else
  62. extern int  xfsecs;
  63. extern long gtv, oldgtv;
  64. #endif /* GFTIMER */
  65. #include "p_type.h"
  66. #include "p.h"
  67. #include "p_callbk.h"
  68. #include "p_common.h"
  69. #ifdef COMMENT
  70. #include "p_brw.h"
  71. #endif
  72. #include "p_error.h"
  73. #include "p_global.h"
  74. #include "p_module.h"
  75. #include "p_omalloc.h"
  76.  
  77. #ifdef PIPESEND
  78. #undef PIPESEND
  79. #endif /* PIPESEND */
  80. #ifdef PIPESEND
  81. extern int pipesend, usepipes;
  82. #endif /* PIPESEND */
  83.  
  84. static U8  msgbuf[512] ;
  85.  
  86. U8 *z_header[] = {
  87.  
  88.   "TIMEOUT",
  89.   "ZRQINIT",
  90.   "ZRINIT",
  91.   "ZSINIT",
  92.   "ZACK",
  93.   "ZFILE",
  94.   "ZSKIP",
  95.   "ZNAK",
  96.   "ZABORT",
  97.   "ZFIN",
  98.   "ZRPOS",
  99.   "ZDATA",
  100.   "ZEOF",
  101.   "ZFERR",
  102.   "ZCRC",
  103.   "ZCHALLENGE",
  104.   "ZCOMPL",
  105.   "ZCAN",
  106.   "ZFREECNT",
  107.   "ZCOMMAND",
  108.   "ZSTDERR"
  109. };
  110.  
  111. U8 *z_frame_end[] = {
  112.  
  113.   "TIMEOUT",
  114.   "ZCRCE",
  115.   "ZCRCG",
  116.   "ZCRCQ",
  117.   "ZCRCW",
  118.   "ZERROR",
  119.   "ZCAN"
  120. };
  121.  
  122. static char errbuf[512];
  123.  
  124. U32 _System
  125. #ifdef CK_ANSIC
  126. status_func(U32 type, U32 arg0, U32 arg1, U32 arg2, U32 arg3, U32 arg4 )
  127. #else
  128. status_func(type,arg0,arg1,arg2,arg3,arg4)
  129.      U32 type; U32 arg0; U32 arg1; U32 arg2; U32 arg3; U32 arg4;
  130. #endif
  131. {
  132.     switch (type) {
  133.     case PS_ERROR:
  134.         {
  135.             sprintf(errbuf,"Module: %d, Line %d, Device: %s, Error: %d",
  136.                      arg2,
  137.                      arg3,
  138.                      arg4?(char*)arg4:"<NULL>",
  139.                      arg0);
  140.             debug(F111,"P ERROR",errbuf,arg1);
  141.  
  142.         }
  143.  
  144.         if (is_os2_error(arg0)) {
  145.             os2_error(arg0,             /* Error num */
  146.                        arg1,            /* Return code */
  147.                        arg2,            /* Module */
  148.                        arg3,            /* Line num */
  149.                        (U8 *)arg4);     /* Optional argument */
  150.         } else if (is_tcpip_error(arg0)) {
  151.             tcpip_error(arg0,           /* Error num */
  152.                          arg1,          /* Return code */
  153.                          arg2,          /* Module */
  154.                          arg3,          /* Line num */
  155.                          (U8 *)arg4); /* Optional argument */
  156.         }
  157.         break;
  158.  
  159.     case PS_CARRIER_LOST:
  160.         carrier_lost = 1;
  161.         ckscreen(SCR_ST,ST_ERR,0l,"Carrier lost");
  162.         break;
  163.  
  164.     case PS_TIMEOUT:
  165.         timeouts++ ;
  166.         sprintf(msgbuf,"Timeout (%lu secs)",arg0);
  167.         ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  168.         debug(F111,"P status_func","TIMEOUT",arg0);
  169.         break;
  170.  
  171.     case PS_TRANSFER_DONE:
  172.         /* Do not use ST_OK as that is called in clsif() */
  173.         ckscreen(SCR_ST,ST_MSG,0l, "Transfer done!");
  174.         debug(F110,"P status_func","TRANSFER DONE",0);
  175.         break;
  176.  
  177.     case PS_PROGRESS:
  178.         ffc = arg0 ;
  179.         ckscreen(SCR_PT,'D',arg0," characters so far");
  180.         break;
  181.  
  182.     case PS_CANNOT_SEND_BLOCK:
  183.         ckscreen(SCR_ST,ST_ERR,0l, "Can't send block");
  184.         break;
  185.  
  186.     case PS_CHECKING_METHOD:
  187.         if (checking_method != arg0) { /* Has the checking method */
  188.             /* changed since last displayed? */
  189.             checking_method = arg0;
  190.             switch (checking_method) {
  191.             case CHECKING_CHECKSUM:
  192.                 ckscreen(SCR_ST,ST_MSG,0l,"Checksum checking will be used");
  193.                 break;
  194.  
  195.             case CHECKING_CRC16:
  196.                 ckscreen(SCR_ST,ST_MSG,0l, "CRC-16 checking will be used");
  197.                 break;
  198.  
  199.             case CHECKING_CRC32:
  200.             default:                    /* To shut up the compiler */
  201.                 ckscreen(SCR_ST,ST_MSG,0l, "CRC-32 checking will be used");
  202.                 break;
  203.             }
  204.         }
  205.         break;
  206.  
  207.     case PS_INVALID_FILE_INFO:
  208.         crunched++ ;
  209.         ckscreen(SCR_PT,'Q',0L,"");
  210.         ckscreen(SCR_ST,ST_MSG,0l, "Got invalid file info");
  211.         break;
  212.  
  213.     case PS_NON_STD_FILE_INFO:
  214.         ckscreen(SCR_ST,ST_MSG,0l, "Got non-standard file info");
  215.         break;
  216.  
  217.     case PS_XY_FALLBACK_TO_CHECKSUM:
  218.         ckscreen(SCR_ST,ST_MSG,0l, "Falling back to checksum checking...");
  219.         break;
  220.  
  221.     case PS_CHECK_FAILED:
  222.         switch (arg0) {
  223.         case CHECKING_CHECKSUM:
  224.             crunched++ ;
  225.             ckscreen(SCR_PT,'Q',0L,"");
  226.             ckscreen(SCR_ST,ST_ERR,0l, "Checksum mismatch");
  227.             break;
  228.  
  229.         case CHECKING_CRC16:
  230.             crunched++ ;
  231.             ckscreen(SCR_PT,'Q',0L,"");
  232.             ckscreen(SCR_ST,ST_ERR,0l, "CRC-16 mismatch");
  233.             break;
  234.  
  235.         case CHECKING_CRC32:
  236.             crunched++ ;
  237.             ckscreen(SCR_PT,'Q',0L,"");
  238.             ckscreen(SCR_ST,ST_ERR,0l, "CRC-32 mismatch");
  239.             break;
  240.         }
  241.         break;
  242.  
  243.     case PS_REMOTE_ABORTED:
  244.         ckscreen(SCR_ST,ST_ERR,0l, "Remote canceled");
  245.         break;
  246.  
  247.     case PS_G_ABORTED:
  248.         ckscreen(SCR_ST,ST_ERR,0l, "Cancelling Ymodem-g transfer");
  249.         break;
  250.  
  251.     case PS_XYG_NAK:
  252.         sprintf(msgbuf,"Got NAK on byte %lu", arg0 );
  253.         ckscreen(SCR_ST,ST_ERR,0l,msgbuf);
  254.         ckscreen(SCR_PT,'N',0L,"");
  255.         break;
  256.  
  257.     case PS_XYG_BLK_NUM_MISMATCH:
  258.         ckscreen(SCR_PT,'E',0L,"");
  259.         crunched++ ;
  260.         sprintf(msgbuf, "Block numbers mismatch (%lu:%lu <> %lu:%lu)",
  261.              arg0, arg1,
  262.              arg2, arg3);
  263.         ckscreen(SCR_ST,ST_ERR,0l,msgbuf);
  264.         break;
  265.  
  266.     case PS_Z_HEADER:
  267.         if (opt_headers) {
  268.            sprintf(msgbuf,"%s %lu",
  269.                  z_header[arg0], arg1);
  270.             ckscreen(SCR_ST,ST_MSG,0l, msgbuf ) ;
  271.         }
  272.         break;
  273.  
  274.     case PS_Z_UNEXPECTED_HEADER:
  275.         ckscreen(SCR_PT,'E',0L,"");
  276.         sprintf(msgbuf,"Unexpected %s %lu",
  277.              z_header[arg0], arg1);
  278.         ckscreen(SCR_ST,ST_ERR,0l, msgbuf);
  279.         break;
  280.  
  281.     case PS_Z_FRAME_END:
  282.         if (opt_frameends)
  283.           ckscreen(SCR_ST,ST_MSG,0l, z_frame_end[arg0]);
  284.         break;
  285.  
  286.     case PS_Z_INVALID_FRAME_END:
  287.         crunched++ ;
  288.         ckscreen(SCR_PT,'E',0L,"");
  289.         sprintf( msgbuf, "Invalid frame end: %s",
  290.              z_frame_end[arg0]);
  291.         ckscreen(SCR_ST,ST_ERR,0l, msgbuf );
  292.         break;
  293.  
  294.     case PS_Z_PHONY_ZEOF:
  295.         ckscreen(SCR_PT,'E',0L,"");
  296.         ckscreen(SCR_ST,ST_ERR,0l, "Got phony ZEOF");
  297.         break;
  298.  
  299.     case PS_Z_RETRY_CNT_EXCEEDED:
  300.         ckscreen(SCR_PT,'E',0L,"");
  301.         ckscreen(SCR_ST,ST_ERR,0l, "Retry count exceeded");
  302.         break;
  303.  
  304.     case PS_Z_DATA_FROM_INVALID_POS:
  305.         crunched++ ;
  306.         ckscreen(SCR_PT,'Q',0L,"");
  307.         sprintf(msgbuf, "Got data from invalid position: %lu, expected from %lu",
  308.              arg0, arg1);
  309.         ckscreen(SCR_ST,ST_ERR,0l,msgbuf);
  310.         break;
  311.  
  312.     case PS_Z_COMMAND:
  313.        sprintf(msgbuf, "Zcommand: \"%s\"", arg0);
  314.         ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  315.         break;
  316.  
  317.     case PS_Z_CTRL_CHAR_IGNORED:
  318.        sprintf(msgbuf, "Unexpected control character ignored: %lu",
  319.              arg0);
  320.         ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  321.         break;
  322.  
  323.     case PS_Z_INVALID_ZDLE_SEQUENCE:
  324.         ckscreen(SCR_PT,'Q',0L,"");
  325.         ckscreen(SCR_ST,ST_ERR,0l, "Invalid ZDLE sequence received");
  326.         break;
  327.  
  328.     case PS_Z_CHECK_FAILED_FOR_HEADER:
  329.         switch (arg0) {
  330.         case CHECKING_CHECKSUM:
  331.             /* This never happens... Checksum checking isn't used for headers! */
  332.             break;
  333.  
  334.         case CHECKING_CRC16:
  335.             crunched++ ;
  336.             ckscreen(SCR_PT,'Q',0L,"");
  337.             ckscreen(SCR_ST,ST_ERR,0l, "CRC-16 mismatch for a header");
  338.             break;
  339.  
  340.         case CHECKING_CRC32:
  341.             crunched++ ;
  342.             ckscreen(SCR_PT,'Q',0L,"");
  343.             ckscreen(SCR_ST,ST_ERR,0l, "CRC-32 mismatch for a header");
  344.             break;
  345.         }
  346.         break;
  347.  
  348.     case PS_Z_INVALID_HEX_HEADER:
  349.         crunched++ ;
  350.         ckscreen(SCR_PT,'Q',0L,"");
  351.         ckscreen(SCR_ST,ST_ERR,0l, "Invalid zmodem hex header received");
  352.         break;
  353.  
  354.     case PS_Z_SUBPACKET_TOO_LONG:
  355.         crunched++ ;
  356.         ckscreen(SCR_PT,'Q',0L,"");
  357.         sprintf(msgbuf, "Too long zmodem subpacket received (> %lu)",
  358.              arg0);
  359.         ckscreen(SCR_ST,ST_ERR,0l,msgbuf);
  360.         break;
  361.  
  362.     case PS_Z_CRASH_RECOVERY:
  363.         sprintf(msgbuf, "Crash recovery at %lu", arg0);
  364.         ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  365.         debug(F111,"P status_func","CRASH RECOVERY",arg0);
  366.         break;
  367.  
  368.     case PS_Z_RECEIVER_FLAGS:
  369.         if (receiver_flags != arg0) {
  370.             if (receiver_flags != 0)    /* We have parsed zrinit */
  371.               /* at least once before */
  372.               ckscreen(SCR_ST,ST_MSG,0l, "Receiver has changed its parameters");
  373.             receiver_flags = arg0;
  374.  
  375.             if (receiver_flags & RZ_FLAG_CANFDX)
  376.               ckscreen(SCR_ST,ST_MSG,0l, "Receiver is capable of true full duplex");
  377.             if (receiver_flags & RZ_FLAG_CANOVIO)
  378.               ckscreen(SCR_ST,ST_MSG,0l, "Receiver can receive data during disk I/O");
  379.             if (receiver_flags & RZ_FLAG_CANBRK)
  380.               ckscreen(SCR_ST,ST_MSG,0l, "Receiver can send break signal");
  381.             if (receiver_flags & RZ_FLAG_CANCRY)
  382.               ckscreen(SCR_ST,ST_MSG,0l, "Receiver can decrypt");
  383.             if (receiver_flags & RZ_FLAG_CANLZW)
  384.               ckscreen(SCR_ST,ST_MSG,0l, "Receiver can uncompress");
  385.             if (receiver_flags & RZ_FLAG_CANFC32) {
  386.                 ckscreen(SCR_ST,ST_MSG,0l, "Receiver can use 32-bit frame checking");
  387.                 if (p_cfg.attr & CFG_ALTERNATIVE_CHECKING)
  388.                   ckscreen(SCR_ST,ST_MSG,0l, "Our parameters override, 16-bit frame checking will be used");
  389.             }
  390.             if (receiver_flags & RZ_FLAG_ESC_CTRL)
  391.               ckscreen(SCR_ST,ST_MSG,0l, "Receiver wants control characters to be escaped");
  392.             if (receiver_flags & RZ_FLAG_ESC_8TH)
  393.               ckscreen(SCR_ST,ST_MSG,0l, "Receiver wants 8th bit to be escaped");
  394.         }
  395.         break;
  396.  
  397.     case PS_Z_RECEIVER_WINDOW_SIZE:
  398.         if (receiver_window_size != arg0) {
  399.             if (receiver_window_size != -1)
  400.               ckscreen(SCR_ST,ST_MSG,0l, "Receiver has changed its window parameters");
  401.             receiver_window_size = arg0;
  402.             if (receiver_window_size == 0)
  403.               ckscreen(SCR_ST,ST_MSG,0l, "Receiver can accept full streaming");
  404.             else
  405.             {
  406.                sprintf(msgbuf, "Receiver wants a frame window of %lu bytes to be used", receiver_window_size);
  407.                ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  408.             }
  409.             if (p_cfg.blk_size &&
  410.                  p_cfg.blk_size != receiver_window_size)
  411.             {
  412.                sprintf(msgbuf,  "Our parameters override, a frame window of %lu bytes will be used", p_cfg.blk_size);
  413.                ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  414.             }
  415.         }
  416.         break;
  417.  
  418.     case PS_Z_SENDER_FLAGS:
  419.         if (arg0 & RZ_FLAG_ESC_CTRL)
  420.           ckscreen(SCR_ST,ST_MSG,0l, "Sender wants control characters to be escaped");
  421.         if (arg0 & RZ_FLAG_ESC_8TH)
  422.           ckscreen(SCR_ST,ST_MSG,0l, "Sender wants 8th bit to be escaped");
  423.         break;
  424.  
  425.     case PS_SERVER_WAITING:
  426.         if (arg0 == opt_wait) {
  427.             if (opt_wait) {
  428.                 ckscreen(SCR_PT,'T',0L,"");
  429.                 ckscreen(SCR_ST,ST_ERR,0l, "Timeout");
  430.                 DosBeep(750, 1000);
  431.             } else
  432.                 ckscreen(SCR_ST,ST_ERR,0l, "No connection, try specifying a waiting time (with -wait option)");
  433.             aborted = 1;
  434.         } else {
  435.             sprintf(msgbuf, "Waiting for connect (%lu secs)", arg0 + 1);
  436.             ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  437.             if (!opt_quiet)
  438.                 DosBeep(250, 20);
  439.             msleep(1000);
  440.         }
  441.         break;
  442.  
  443.     case PS_FILE_SKIPPED:
  444.         ckscreen(SCR_ST,ST_MSG,0l, "File skipped by receiver request");
  445.         break;
  446.  
  447.     case PS_Z_SERIAL_NUM:
  448.         if (p_cfg.attr & CFG_QUERY_SERIAL_NUM) /* Let's not show it, if not */
  449.                                            /* explicitly asked to */
  450.         {
  451.             sprintf(msgbuf, "Serial number of the receiver is %lu", arg0);
  452.             ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  453.         }
  454.         remote_serial_num = arg0;
  455.         break;
  456.  
  457.     case PS_PACKET_LENGTH:
  458.         break;
  459.  
  460.     default:
  461.         sprintf(msgbuf, "Got unknown P_STATUS: %lu", type);
  462.         ckscreen(SCR_ST,ST_ERR,0l,msgbuf);
  463.         break;
  464.     }
  465.     if (aborted) {              /* User has pressed CTRL-C */
  466.         we_aborted = 1;
  467.         aborted = 0;            /* Once is enough */
  468.         debug(F110,"P status_func","User aborted",0);
  469.         return(1);
  470.     }
  471.     return(0);
  472. }
  473.  
  474. U32
  475. #ifdef CK_ANSIC
  476. s_open_func(U8 **path, U32 *length, U32 *date, U32 *mode,
  477.                     U32 *f_left, U32 *b_left,
  478.                     U8 *zconv, U8 *zmanag, U8 *ztrans)
  479. #else
  480. s_open_func(path,length,date,mode,f_left,b_left,zconv,zmanag,ztrans)
  481.      U8 **path; U32 *length; U32 *date; U32 *mode;
  482.      U32 *f_left; U32 *b_left;
  483.      U8 *zconv; U8 *zmanag; U8 *ztrans;
  484. #endif
  485. {
  486.     APIRET rc = 0;
  487.     struct stat statbuf;
  488.     U8 convert = 0 ;
  489.     extern long rs_len ;
  490.  
  491.     debug(F100,"s_open_func","",0);
  492.  
  493.     rtimer();                       /* Reset the elapsed seconds timer. */
  494. #ifdef GFTIMER
  495.     rftimer();
  496. #endif /* GFTIMER */
  497.  
  498.     if (tl->c == NULL) {
  499.         debug(F100,"s_open_func tl->c == NULL","",0);
  500.         *path = NULL;
  501.         return(0);
  502.     }
  503.  
  504.     debug(F101,"s_open_func tl->c->convert","",tl->c->convert);
  505.     debug(F110,"s_open_func tl->c->path",tl->c->path,0);
  506.     debug(F110,"s_open_func tl->c->as_name",tl->c->as_name,0);
  507.  
  508.     p_omalloc( (void**)path, 4096, MODULE_CALLBACK, __LINE__ ) ;
  509.  
  510.     full_path = tl->c->path ;
  511.     binary = !tl->c->convert ; /* set the file transfer mode for this file */
  512.     convert = tl->c->convert ;
  513.     nzltor(tl->c->as_name ? tl->c->as_name : tl->c->path,
  514.             *path,fncnv,fnspath,4095);
  515.     tl->c = tl->c->n ; /* advance to next file */
  516.  
  517.     debug(F110,"s_open_func",full_path,0);      /* Log debugging info */
  518.     debug(F110," (*path)",(*path),0);
  519.     sndsrc = 1 ;                       /* We aren't using STDIO */
  520.     ckscreen(SCR_FN,0,0l,full_path);
  521.     if (openi(full_path) == 0) {        /* Try to open the input file */
  522.         debug(F110,"P open_func","Unable to open input file",0);
  523.         return(1);
  524.     }
  525.  
  526.     ckscreen(SCR_AN,0,0l,*path);
  527.     tlog(F110,"Sending",full_path,0);
  528.     tlog(F110," as",*path,0);
  529.     if ( binary )
  530.         tlog(F101," mode: binary","",(long) binary);
  531.     else
  532.         tlog(F110," mode: text","",0);
  533.  
  534. #ifdef CK_RESEND
  535.     if (sendmode == SM_PSEND)   /* PSENDing? */
  536.       if (sendstart > 0L)               /* Starting position */
  537.         if (zfseek(sendstart) < 0)      /* seek to it... */
  538.           return(0);
  539. #endif /* CK_RESEND */
  540.  
  541. #ifdef PIPESEND
  542.     if ( pipesend )
  543.         *length = 0;
  544.     else
  545. #endif /* PIPESEND */
  546.     *length = zchki(full_path);
  547.     fsize = *length ;
  548.     ckscreen(SCR_FS,0,*length,"");
  549.  
  550. #ifdef UNIX
  551.     stat(full_path, &statbuf);
  552.     if ( atcapr && atdato )
  553.         *date = statbuf.st_mtime;
  554.     else 
  555.         *date = -1;
  556.     *mode = statbuf.st_mode;
  557. #else
  558. #ifdef OS2
  559.     stat(full_path, &statbuf);
  560.     if ( atcapr && atdato )
  561.         *date = statbuf.st_mtime;
  562.     else
  563.         *date = -1;
  564.     *mode = statbuf.st_mode;
  565. #else
  566.     NEED TO ADD THIS CODE  ;
  567. #endif
  568. #endif
  569.     *f_left = files_left;
  570.     *b_left = bytes_left;
  571.  
  572.     if (p_cfg.protocol_type == PROTOCOL_Z) {
  573.         /**********************/
  574.         /* Conversion options */
  575.         /**********************/
  576.         *zconv = 0;
  577.         if (convert)
  578.           *zconv |= Z_CONVERSION_TEXT;
  579.         else
  580.           *zconv |= Z_CONVERSION_BINARY;
  581.  
  582.         if (opt_resume)
  583.           *zconv = Z_CONVERSION_RESUME;
  584.  
  585.         /**********************/
  586.         /* Management options */
  587.         /**********************/
  588.         *zmanag = 0;
  589.         if (opt_existing)
  590.           *zmanag |= Z_MANAGEMENT_MUST_EXIST;
  591.         *zmanag |= opt_management;
  592.  
  593.         /*********************/
  594.         /* Transport options */
  595.         /*********************/
  596.         *ztrans = 0;
  597.     }
  598.     if (opt_mileage) {
  599.         if (opt_speed)
  600.         {
  601.             sprintf(msgbuf,
  602.                      "Total of %lu files and %lu bytes (%s) left to transfer",
  603.                      files_left, bytes_left, d_time(bytes_left / (opt_speed / 10)));
  604.             ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  605.         }
  606.         else
  607.         {
  608.             sprintf(msgbuf,  "Total of %lu files and %lu bytes left to transfer",
  609.                      files_left, bytes_left);
  610.             ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  611.         }
  612.     }
  613.     if (opt_speed)
  614.     {
  615.         sprintf(msgbuf,  "Sending %s, %lu bytes, %s",
  616.                  full_path, *length, d_time(*length / (opt_speed / 10)));
  617.         ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  618.     }
  619.     else
  620.     {
  621.         sprintf( msgbuf,  "Sending %s, %lu bytes", full_path, *length);
  622.         ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  623.     }
  624.     time(&t_started);
  625.  
  626.     /* update screen counts */
  627.     ffc = 0L;                           /* Init file character counter. */
  628.     tsecs = -1 ;
  629.     cps = oldcps = 0L ; /* Init cps statistics */
  630.     rs_len = 0L;
  631.     rejection = -1;
  632.     fsecs = gtimer();                   /* Time this file started */
  633. #ifdef GFTIMER
  634.     fpfsecs = gftimer();
  635. #endif /* GFTIMER */
  636.     filcnt++ ;
  637.     intmsg(filcnt);
  638.     return(0);
  639. }
  640.  
  641. /* Finds an unique name for the file */
  642.  
  643. U32
  644. #ifdef CK_ANSIC
  645. r_open_func(U8 **path, U32 length, U32 date, U32 mode,
  646.                 U32 f_left, U32 b_left,
  647.                 U8 zconv, U8 zmanag, U8 ztrans,
  648.                 U32 *offset)
  649. #else
  650. r_open_func(path,length,date,mode,f_left,b_left,zconv,zmanag,ztrans,offset)
  651.      U8 **path; U32 length; U32 date; U32 mode;
  652.      U32 f_left; U32 b_left;
  653.      U8 zconv; U8 zmanag; U8 ztrans;
  654.      U32 *offset;
  655. #endif
  656. {
  657.     extern char * zdtstr(time_t);
  658.     extern char *rf_err;
  659.     extern char ofn1[CKMAXPATH+1];
  660.     extern int ofn1x, discard, opnerr, stdouf, fnrpath ;
  661.     extern long rs_len ;
  662.     extern char * ofn2, fspec[];
  663.     extern int  fspeclen;
  664. #ifdef DYNAMIC
  665.     extern CHAR * srvcmd;
  666. #else /* DYNAMIC */
  667.     extern CHAR srvcmd[];
  668. #endif /* DYNAMIC */
  669.     char *zs, *longname, *newlongname, *pn; /* OS/2 long name items */
  670.     int dirflg=0;
  671.     BOOLEAN path_was_null=0;
  672.     BOOLEAN path_is_as_name=0;
  673.     U32 management = 0;
  674.     U32 open_mode = 0;
  675.     APIRET rc = 0;
  676.     struct stat statbuf;
  677.     struct zattr zz ;
  678.     int len = 0;
  679.  
  680.     rtimer();                       /* Reset the elapsed seconds timer. */
  681. #ifdef GFTIMER
  682.     rftimer();
  683. #endif /* GFTIMER */
  684.  
  685.     ofn2 = NULL ;                       /* No new name (yet) */
  686.  
  687.     /* Simulate a Kermit Attribute Packet */
  688.     initattr(&zz);
  689.     zz.length = length ;
  690.     zz.date.val = zdtstr(date);
  691.     zz.date.len = strlen(zz.date.val);
  692.     zz.type.val = zconv ? "A" : "B" ;
  693.     zz.type.len = 1 ;
  694.  
  695.     if (*path == NULL) {                /* Xmodem receive? */
  696.         if ( !(tl && tl->c && tl->c->path && tl->c->path[0]) ) {
  697.             /* No as-name given, can't continue */
  698.             ckscreen(SCR_ST,ST_ERR,0l,"No file name specified.");
  699.             return(0);
  700.         }
  701.         p_omalloc( (void**)path, 4096, MODULE_CALLBACK, __LINE__ ) ;
  702.         ckstrncpy( *path, tl->c->path, 4096 ) ;
  703.         tl->c = tl->c->n ;
  704.         path_was_null = 1;
  705.     }
  706.  
  707.     ckscreen(SCR_FN,0,0l,*path);
  708.     tlog(F110,"Receiving",*path,0);
  709.     fsize = length;
  710.     /* ckscreen(SCR_FS,0,length,""); called from opena() when fsize is set */
  711.  
  712.     /* Use the AS-NAME */
  713.     if ( !path_was_null && tl && tl->c && tl->c->path && tl->c->path[0] ) {
  714.         p_ofree( (void*)path, MODULE_CALLBACK, __LINE__ );
  715.         p_omalloc( (void**)path, 4096, MODULE_CALLBACK, __LINE__ ) ;
  716.         ckstrncpy( *path, tl->c->path, 4096 ) ;
  717.         tl->c = tl->c->n ;
  718.         ckscreen(SCR_AN,0,0l,*path);
  719.         tlog(F110," as",*path,0);
  720.         path_is_as_name=1;
  721. #ifdef PIPESEND
  722.         if ( pipesend ) {
  723.             ckstrncpy(srvcmd,*path,MAXRP+4);
  724.         }
  725. #endif /* PIPESEND */
  726.     }
  727. #ifdef PIPESEND
  728.     else if ( (*path)[0] == '!' && usepipes ) {
  729.         (*path)++;
  730.         ckstrncpy(srvcmd,*path,MAXRP+4);
  731.     }
  732. #endif /* PIPESEND */
  733.     else {
  734.  
  735.         if (!opt_paths)
  736.             strip_drive_and_dir(*path);
  737.         else {
  738.             if (opt_create && create_dirs(*path)) {
  739.                 sprintf(msgbuf, "%s: %s, %s...", *path, strerror(errno),
  740.                          p_cfg.protocol_type == PROTOCOL_Z ? "skipping" : "canceling");
  741.                 ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  742.                 tlog(F110," error - can't create path",*path,0);
  743.                 p_ofree( (void*)path, MODULE_CALLBACK, __LINE__ );
  744.                 return(0);
  745.             }
  746.         }
  747.     }
  748.     if (opt_mileage) {
  749.         if (f_left || b_left) {
  750.             if (opt_speed) {
  751.                 sprintf(msgbuf,
  752.                          "Total of %lu files and %lu bytes (%s) left to transfer",
  753.                          f_left, b_left, d_time(b_left / (opt_speed / 10)));
  754.                 ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  755.             }
  756.             else
  757.             {
  758.                 sprintf(msgbuf, "Total of %lu files and %lu bytes left to transfer",
  759.                          f_left, b_left);
  760.                 ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  761.             }
  762.         }
  763.     }
  764.     if (p_cfg.protocol_type == PROTOCOL_Z && opt_options) {
  765.         switch (zconv) {
  766.         case Z_CONVERSION_UNDEFINED:
  767.             break;
  768.  
  769.         case Z_CONVERSION_BINARY:
  770.             ckscreen(SCR_ST,ST_MSG,0l,
  771.                     "Sender suggests a binary conversion to be used");
  772.             break;
  773.  
  774.         case Z_CONVERSION_TEXT:
  775.             ckscreen(SCR_ST,ST_MSG,0l,
  776.                     "Sender suggests a text conversion to be used");
  777.             break;
  778.  
  779.         case Z_CONVERSION_RESUME:
  780.             ckscreen(SCR_ST,ST_MSG,0l,
  781.                     "Sender suggests that the file transfer should be resumed");
  782.             break;
  783.  
  784.         default:
  785.             sprintf(msgbuf, "Unknown conversion option received: %lu", zconv);
  786.             ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  787.             break;
  788.         }
  789.  
  790. #ifdef COMMENT
  791.         /* Kermit's File Collision Setting always is used instead of */
  792.         /* the sender's request.  Otherwise, it would be a huge      */
  793.         /* security risk.                                            */
  794.         switch (zmanag & Z_MANAGEMENT_MASK) {
  795.         case Z_MANAGEMENT_UNDEFINED:
  796.             break;
  797.  
  798.         case Z_MANAGEMENT_UPDATE:
  799.             fncact = XYFX_U ;
  800.             ckscreen(SCR_ST,ST_MSG,0l,
  801.                     "Sender wants to update older and shorter files");
  802.             break;
  803.  
  804.         case Z_MANAGEMENT_COMPARE:
  805.             fncact = XYFX_U ;
  806.             ckscreen(SCR_ST,ST_MSG,0l,
  807.     "Sender wants to compare possibly existing files before replacing");
  808.             break;
  809.  
  810.         case Z_MANAGEMENT_APPEND:
  811.             fncact = XYFX_A ;
  812.             ckscreen(SCR_ST,ST_MSG,0l,
  813.                     "Sender wants to append to already existing files");
  814.             break;
  815.  
  816.         case Z_MANAGEMENT_REPLACE:
  817.             fncact = XYFX_X ;
  818.             ckscreen(SCR_ST,ST_MSG,0l,
  819.                     "Sender wants to replace already existing files");
  820.             break;
  821.  
  822.         case Z_MANAGEMENT_NEWER:
  823.             fncact = XYFX_U ;
  824.             ckscreen(SCR_ST,ST_MSG,0l,
  825.                     "Sender wants to update older files");
  826.             break;
  827.  
  828.         case Z_MANAGEMENT_DIFFERENT:
  829.             fncact= XYFX_U ;
  830.             ckscreen(SCR_ST,ST_MSG,0l,
  831.              "Sender wants to replace files with different dates and lengths");
  832.             break;
  833.  
  834.         case Z_MANAGEMENT_PROTECT:
  835.             fncact = XYFX_D ;
  836.             ckscreen(SCR_ST,ST_MSG,0l,
  837.                 "Sender does not want to replace already existing files");
  838.             break;
  839.  
  840.         case Z_MANAGEMENT_RENAME:
  841.             fncact = XYFX_R ;
  842.             ckscreen(SCR_ST,ST_MSG,0l,
  843.                 "Sender wants to use a new name for file if file exists");
  844.             break;
  845.  
  846.         case Z_MANAGEMENT_BACKUP:
  847.             fncact = XYFX_B ;
  848.             ckscreen(SCR_ST,ST_MSG,0l,
  849.                 "Sender wants to backup existing files");
  850.             break;
  851.  
  852.         default:
  853.               sprintf(msgbuf,
  854.                        "Unknown management option received: %lu", zmanag);
  855.               ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  856.               break;
  857.         }
  858.  
  859.         if (zmanag & Z_MANAGEMENT_MUST_EXIST)
  860.           ckscreen(SCR_ST,ST_MSG,0l,
  861.                   "Sender wants to transfer only already existing files");
  862. #endif /* COMMENT */
  863.  
  864.         switch (ztrans) {
  865.         case Z_TRANSPORT_UNDEFINED:
  866.             break;
  867.  
  868.         case Z_TRANSPORT_LZW:
  869.             ckscreen(SCR_ST,ST_MSG,0l,
  870.                     "Sender wants to use Lempel-Ziv compression");
  871.             break;
  872.  
  873.         case Z_TRANSPORT_CRYPT:
  874.             ckscreen(SCR_ST,ST_MSG,0l,
  875.                     "Sender wants to use encryption");
  876.             break;
  877.  
  878.         case Z_TRANSPORT_RLE:
  879.             ckscreen(SCR_ST,ST_MSG,0l,
  880.                     "Sender wants to use RLE compression");
  881.             break;
  882.  
  883.         default:
  884.               sprintf(msgbuf,
  885.                        "Unknown transport option received: %lu", ztrans);
  886.               ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  887.               break;
  888.         }
  889.     }
  890.     /******************************/
  891.     /* Process conversion options */
  892.     /******************************/
  893.     if (zconv == Z_CONVERSION_TEXT || opt_text) {
  894.         binary = 0 ;
  895.         tlog(F100," mode: text","",0);
  896.     }
  897.     else {
  898.         binary = 1 ;
  899.         tlog(F100," mode: binary","",0);
  900.     }
  901.  
  902. #ifdef COMMENT
  903.     /* More things that Kermit is not going to support */
  904.     /******************************/
  905.     /* Process management options */
  906.     /******************************/
  907.     if (!(zmanag & Z_MANAGEMENT_MUST_EXIST) && !opt_existing)
  908.       open_mode |= O_CREAT;
  909.     management = (zmanag & Z_MANAGEMENT_MASK);
  910.     if (opt_management)         /* If management option specified */
  911.                                         /* on the command-line */
  912.       management = opt_management;      /* Command-line overrides remote's */
  913.                                         /* options */
  914.     if (!management && zconv != Z_CONVERSION_RESUME && !opt_resume) {
  915.         /* If no management option or resume specified, we'll default to */
  916.         /* protecting existing files... */
  917.         management = Z_MANAGEMENT_PROTECT;
  918.     }
  919. #endif /* COMMENT */
  920.  
  921.  
  922.     if (length != -1) {
  923.         if (opt_speed != 0) {
  924.             sprintf(msgbuf, "Receiving %s, %lu bytes, %s",
  925.                      *path, length, d_time(length / (opt_speed / 10)));
  926.             ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  927.         }
  928.         else
  929.         {
  930.             sprintf(msgbuf, "Receiving %s, %lu bytes", *path, length);
  931.             ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  932.         }
  933.     }
  934.     else
  935.     {
  936.         sprintf(msgbuf, "Receiving %s", *path);
  937.         ckscreen(SCR_ST,ST_MSG,0l,msgbuf);
  938.     }
  939.  
  940.     if ( !path_is_as_name ) {
  941.         add_recv_dir_to_path(path);
  942.         ckscreen(SCR_AN,0,0l,*path);
  943.         tlog(F110," as",*path,0);
  944.     }
  945.  
  946.     if (fncnv)                          /* FILE NAMES CONVERTED? */
  947.       zrtol((char *)(*path),(char *)ofn1); /* Yes, convert to local form */
  948.     else
  949.       ckstrncpy(ofn1,(char *)(*path),CKMAXPATH+1); /* No, copy literally. */
  950.  
  951.     /* Now the incoming filename, possibly converted, is in ofn1[]. */
  952.  
  953. #ifdef OS2ONLY
  954.     /* Don't refuse the file just because the name is illegal. */
  955.     if (!IsFileNameValid(ofn1)) {       /* Name is OK for OS/2? */
  956. #ifdef __32BIT__
  957.         char *zs = NULL;
  958.         zstrip(ofn1, &zs);              /* Not valid, strip unconditionally */
  959.         if (zs) {
  960.             if (zz.longname.len &&
  961.                  zz.longname.val)       /* Free previous longname, if any */
  962.                 free(zz.longname.val);
  963.             zz.longname.len = strlen(zs); /* Store in attribute structure */
  964.             zz.longname.val = (char *) malloc( zz.longname.len + 1 ) ;
  965.             if (zz.longname.val)        /* Remember this (illegal) name */
  966.                 ckstrncpy( zz.longname.val, zs, zz.longname.len + 1);
  967.         }
  968. #endif /* __32BIT__ */
  969.         debug(F110,"rcvfil: invalid file name",ofn1,0);
  970.         ChangeNameForFAT(ofn1); /* Change to an acceptable name */
  971.         debug(F110,"rcvfil: FAT file name",ofn1,0);
  972.     } else {                            /* Name is OK. */
  973.         debug(F110,"rcvfil: valid file name",ofn1,0);
  974. #ifdef __32BIT__
  975.         if (zz.longname.len &&
  976.              zz.longname.val)           /* Free previous longname, if any */
  977.           free(zz.longname.val);
  978.         zz.longname.len = 0;
  979.         zz.longname.val = "";   /* This file doesn't need a longname */
  980. #endif /* __32BIT__ */
  981.     }
  982. #endif /* OS2ONLY */
  983.     debug(F110,"rcvfil as",ofn1,0);
  984.  
  985. /* Filename collision action section. */
  986.  
  987.     discard = 0 ;                       /* Reset the flag for this file */
  988.     dirflg =                            /* Is it a directory name? */
  989. #ifdef CK_TMPDIR
  990.         isdir(ofn1)
  991. #else
  992.         0
  993. #endif /* CK_TMPDIR */
  994.           ;
  995.     debug(F101,"rcvfil dirflg","",dirflg);
  996.     ofn1x = (zchki(ofn1) != -1);        /* File already exists? */
  997.     debug(F101,"rcvfil ofn1x",ofn1,ofn1x);
  998.  
  999.     if ( (
  1000. #ifdef UNIX
  1001.         strcmp(ofn1,"/dev/null") &&     /* It's not the null device? */
  1002. #else
  1003. #ifdef OSK
  1004.         strcmp(ofn1,"/nil") &&  /* It's not the null device? */
  1005. #endif /* OSK */
  1006. #endif /* UNIX */
  1007.         !stdouf ) &&                    /* Not copying to standard output? */
  1008.         ofn1x ||                        /* File of same name exists? */
  1009.         dirflg ) {                      /* Or file is a directory? */
  1010.         debug(F111,"rcvfil exists",ofn1,fncact);
  1011.         switch (fncact) {               /* Yes, do what user said. */
  1012.         case XYFX_A:                    /* Append */
  1013.             debug(F100,"rcvfil append","",0);
  1014.             if (dirflg) {
  1015.                 rf_err = "Can't append to a directory";
  1016.                 tlog(F100," error - can't append to directory","",0);
  1017.                 discard = opnerr = 1;
  1018.                 p_ofree( (void **) path, MODULE_CALLBACK, __LINE__ ) ;
  1019.                 return(0);
  1020.             }
  1021.             tlog(F110," appending to",ofn1,0);
  1022.             break;
  1023.         case XYFX_Q:                    /* Query (Ask) */
  1024.             break;                      /* not implemented */
  1025.         case XYFX_B:                    /* Backup (rename old file) */
  1026.             if (dirflg) {
  1027.                 rf_err = "Can't rename existing directory";
  1028.                 tlog(F100," error - can't rename directory","",0);
  1029.                 discard = opnerr = 1;
  1030.                 p_ofree( (void **) path, MODULE_CALLBACK, __LINE__ ) ;
  1031.                 return(0);
  1032.             }
  1033.             if ( zconv != Z_CONVERSION_RESUME ) {
  1034.                 znewn(ofn1,&ofn2);              /* Get new unique name */
  1035.                 tlog(F110," backup:",ofn2,0);
  1036.                 debug(F110,"rcvfil backup ofn1",ofn1,0);
  1037.                 debug(F110,"rcvfil backup ofn2",ofn2,0);
  1038. #ifdef OS2
  1039. #ifdef CK_LABELED
  1040. #ifdef __32BIT__
  1041. /*
  1042.   In case this is a FAT file system, we can't change only the FAT name, we
  1043.   also have to change the longname from the extended attributes block.
  1044.   Otherwise, we'll have many files with the same longname and if we copy them
  1045.   to an HPFS volume, only one will survive.
  1046. */
  1047.                 if (os2getlongname(ofn1, &longname) > -1) {
  1048.                     if (strlen(longname)) {
  1049.                         char tmp[10];
  1050.                         extern int ck_znewn;
  1051.                         sprintf(tmp,".~%d~",ck_znewn);
  1052.                         newlongname =
  1053.                             (char *) malloc(strlen(longname) + strlen(tmp) + 1 ) ;
  1054.                         if (newlongname) {
  1055.                             strcpy(newlongname, longname);
  1056.                             strcat(newlongname, tmp);
  1057.                             os2setlongname(ofn1, newlongname);
  1058.                             free(newlongname);
  1059.                             newlongname = NULL;
  1060.                         }
  1061.                     }
  1062.                 }
  1063.                 else
  1064.                     debug(F100,"rcvfil os2getlongname failed","",0);
  1065. #endif /* __32BIT__ */
  1066. #endif /* CK_LABELED */
  1067. #endif /* OS2 */
  1068.  
  1069. #ifdef COMMENT
  1070.                 /* Do this later, in opena()... */
  1071.                 if (zrename(ofn1,ofn2) < 0) {
  1072.                     rf_err = "Can't transform filename";
  1073.                     debug(F110,"rcvfil rename fails",ofn1,0);
  1074.                     discard = opnerr = 1;
  1075.                     p_ofree( (void **) path, MODULE_CALLBACK, __LINE__ ) ;
  1076.                     return(0);
  1077.                 }
  1078. #endif /* COMMENT */
  1079.             }
  1080.             break;
  1081.  
  1082.         case XYFX_D:                    /* Discard (refuse new file) */
  1083.             if ( zconv != Z_CONVERSION_RESUME ) {
  1084.                 discard = 1;
  1085.                 rejection = 1;          /* Horrible hack: reason = name */
  1086.                 debug(F101,"rcvfil discard","",discard);
  1087.                 tlog(F100," refused: name","",0);
  1088.                 p_ofree( (void **) path, MODULE_CALLBACK, __LINE__ ) ;
  1089.                 return(0);
  1090.             }
  1091.             break;
  1092.  
  1093.         case XYFX_R:                    /* Rename incoming file */
  1094.             if ( zconv != Z_CONVERSION_RESUME ) {
  1095.             znewn(ofn1,&ofn2);          /* Make new name for it */
  1096. #ifdef OS2
  1097. #ifdef __32BIT__
  1098.             if (zz.longname.len) {
  1099.                 char tmp[10];
  1100.                 extern int ck_znewn;
  1101.                 sprintf(tmp,".~%d~",ck_znewn);
  1102.                 newlongname =
  1103.                     (char *) malloc(zz.longname.len + strlen(tmp) + 1);
  1104.                 if (newlongname) {
  1105.                     strcpy( newlongname, zz.longname.val);
  1106.                     strcat( newlongname, tmp);
  1107.                     debug(F110,
  1108.                            "Rename Incoming: newlongname",newlongname,0);
  1109.                     if (zz.longname.len &&
  1110.                          zz.longname.val)
  1111.                         free(zz.longname.val);
  1112.                     zz.longname.len = strlen(newlongname);
  1113.                     zz.longname.val = newlongname ;
  1114.                 }
  1115.             }
  1116. #endif /* __32BIT__ */
  1117. #endif /* OS2 */
  1118.             }
  1119.             break;
  1120.         case XYFX_X:                    /* Replace old file */
  1121.             debug(F100,"rcvfil overwrite","",0);
  1122.             if (dirflg) {
  1123.                 rf_err = "Can't overwrite existing directory";
  1124.                 tlog(F100," error - can't overwrite directory","",0);
  1125.                 discard = opnerr = 1;
  1126.                 p_ofree( (void **) path, MODULE_CALLBACK, __LINE__ ) ;
  1127.                 return(0);
  1128.             }
  1129.             if ( zconv != Z_CONVERSION_RESUME )
  1130.                 tlog(F110,"overwriting",ofn1,0);
  1131.             break;
  1132.  
  1133.         case XYFX_U:                    /* Refuse if older */
  1134.             debug(F100,"rcvfil update","",0);
  1135.             if (dirflg) {
  1136.                 rf_err = "File has same name as existing directory";
  1137.                 tlog(F110," error - directory exists:",ofn1,0);
  1138.                 discard = opnerr = 1;
  1139.                 p_ofree( (void **) path, MODULE_CALLBACK, __LINE__ ) ;
  1140.                 return(0);
  1141.             }
  1142.             if ( zconv != Z_CONVERSION_RESUME && zstime(*path,&zz,1) > 0 ) {
  1143.                 tlog(F100," refused: date","",0);
  1144.                 ckscreen(SCR_ST,ST_REFU,0l,"date");
  1145.                 p_ofree( (void **) path, MODULE_CALLBACK, __LINE__ ) ;
  1146.                 return(0);
  1147.             }
  1148.             break;                      /* Not here, we don't have */
  1149.                                         /* the attribute packet yet. */
  1150.         default:
  1151.             debug(F101,"rcvfil bad collision action","",fncact);
  1152.             break;
  1153.         }
  1154.     }
  1155.  
  1156.     debug(F110,"rcvfil ofn1",ofn1,0);
  1157.     debug(F110,"rcvfil ofn2",ofn2,0);
  1158.     if (zconv != Z_CONVERSION_RESUME &&
  1159.          fncact == XYFX_R && ofn1x && ofn2) { /* Renaming incoming file? */
  1160.         ckscreen(SCR_AN,0,0l,ofn2);     /* Display renamed name */
  1161.         p_ofree( (void*)path, MODULE_CALLBACK, __LINE__ );
  1162.         p_omalloc( (void**)path, 4096, MODULE_CALLBACK, __LINE__ ) ;
  1163.         ckstrncpy((*path), ofn2, 4096);          /* Return it */
  1164.     } else {                            /* No */
  1165.         ckscreen(SCR_AN,0,0l,ofn1);     /* Display regular name */
  1166.         p_ofree( (void*)path, MODULE_CALLBACK, __LINE__ );
  1167.         p_omalloc( (void**)path, 4096, MODULE_CALLBACK, __LINE__ ) ;
  1168.         ckstrncpy((*path), ofn1, 4096);          /* and return it. */
  1169.     }
  1170.  
  1171. #ifdef CK_MKDIR
  1172. /*  Create directory(s) if necessary.  */
  1173.     if (!discard && !fnrpath) {         /* RECEIVE PATHAMES ON? */
  1174.         debug(F110,"rcvfil calling zmkdir",ofn1,0); /* Yes */
  1175.         if (zmkdir(ofn1) < 0) {
  1176.             debug(F100,"zmkdir fails","",0);
  1177.             tlog(F110," error - directory creation failure:",ofn1,0);
  1178.             rf_err = "Directory creation failure.";
  1179.             discard = 1;
  1180.             return(0);
  1181.         }
  1182.     }
  1183. #else
  1184.     debug(F110,"sfile CK_MKDIR not defined",ofn1,0);
  1185. #endif /* CK_MKDIR */
  1186.  
  1187. #ifndef NOICP
  1188. /* #ifndef MAC */
  1189. /* Why not Mac? */
  1190.     ckstrncpy(fspec,ofn1,fspeclen);        /* Here too for \v(filespec) */
  1191. /* #endif */
  1192. #endif /* NOICP */
  1193.     debug(F110,"rcvfil: (*path)",(*path),0);
  1194.  
  1195.     len = zchki(*path);          /* if returns < 0, file does not exist */
  1196.     if ( p_cfg.protocol_type == PROTOCOL_Z &&
  1197.          /* Are we crash-recovering? */
  1198.          (zconv == Z_CONVERSION_RESUME || opt_resume) && (len >= 0) ) {
  1199.         if ( len != length ) {
  1200.             zz.disp.val = "R" ; /* Treat as a RESEND */
  1201.             zz.disp.len = 1 ;
  1202.             fncact = XYFX_A ;
  1203.         }
  1204.         else {
  1205.             tlog(F100," refused: file complete","",0);
  1206.             ckscreen(SCR_ST,ST_REFU,0l,"file complete");
  1207.             p_ofree( (void **) path, MODULE_CALLBACK, __LINE__ ) ;
  1208.             return(0);
  1209.         }
  1210.     }
  1211.  
  1212.     if ( discard || opena(*path,&zz) == 0 )
  1213.     {
  1214.         p_ofree( (void **) path, MODULE_CALLBACK, __LINE__ ) ;
  1215.         return(0);
  1216.     }
  1217.  
  1218.     if (p_cfg.protocol_type == PROTOCOL_Z && (len >= 0) &&
  1219.          /* Are we crash-recovering? */
  1220.          (zconv == Z_CONVERSION_RESUME || opt_resume)) {
  1221.         if (len != length)
  1222.         {
  1223.             sprintf( msgbuf,  "Crash recovery at %lu", len);
  1224.             ckscreen(SCR_ST,ST_MSG,0l, msgbuf ) ;
  1225.             tlog(F101," resume at","",len);
  1226.         }
  1227.         else {
  1228.             ckscreen(SCR_ST,ST_MSG,0l,
  1229.                     "We have the whole file already, skipping...");
  1230.             tlog(F100," skipping - file match detected","",0);
  1231.             clsof(0);   /* don't discard the file */
  1232.             p_ofree( (void **) path, MODULE_CALLBACK, __LINE__ ) ;
  1233.             return(0);
  1234.         }
  1235.         if (offset != NULL)     /* If not null, we're using Zmodem */
  1236.                       /* Tell the remote to start sending from the */
  1237.           *offset = len;        /* existing file length */
  1238.     }
  1239.     else {              /* Not resuming => appending */
  1240.         if ( len >= 0 ) {
  1241.             sprintf( msgbuf,  "Appending at %lu", len);
  1242.             ckscreen(SCR_ST,ST_MSG,0l,msgbuf ) ;
  1243.             tlog(F101," appending at","",len);
  1244.         }
  1245.         if (offset != NULL)     /* If not null, we're using Zmodem */
  1246.           /* Tell the remote to start sending from the */
  1247.           *offset = 0;  /* beginning of the file */
  1248.     }
  1249.     time(&t_started);
  1250.  
  1251.     /* update screen counts */
  1252.     ffc = 0L;                           /* Init per-file counters */
  1253.     cps = oldcps = 0L ;
  1254.     rs_len = 0L;
  1255.     rejection = -1;
  1256. #ifdef GFTIMER
  1257.     fpfsecs = gftimer();
  1258. #else
  1259.     fsecs = gtimer();                   /* Time this file started */
  1260. #endif /* GFTIMER */
  1261. #ifdef GFTIMER
  1262.     gtv = -1.0;
  1263.     oldgtv = -1.0;
  1264. #else
  1265.     gtv = -1L;
  1266.     oldgtv = -1L;
  1267. #endif /* GFTIMER */
  1268.     filcnt++;
  1269.     intmsg(filcnt);
  1270.  
  1271.     return(0);
  1272. }
  1273.  
  1274. U32
  1275. #ifdef CK_ANSIC
  1276. close_func(U8 **path,
  1277.                U32 length,
  1278.                U32 date,
  1279.                U32 retransmits,
  1280.                BOOLEAN successful,
  1281.                U32 offset)
  1282. #else
  1283. close_func(path,length,date,retransmits,successful,offset)
  1284.      U8 **path;
  1285.      U32 length;
  1286.      U32 date;
  1287.      U32 retransmits;
  1288.      BOOLEAN successful;
  1289.      U32 offset;
  1290. #endif
  1291. {
  1292.     U8 id=0;
  1293.     S32 rw_ret;
  1294.     time_t t_now;
  1295.     U32 cps;
  1296.     U32 ret_val = 0;
  1297. #ifdef NT
  1298.     struct _utimbuf times;
  1299. #else
  1300.     struct utimbuf times;
  1301. #endif
  1302.     APIRET rc = 0;
  1303.  
  1304.     time(&t_now);
  1305.     if ( p_cfg.transfer_direction == DIR_SEND ) {
  1306.         if ( successful ) {
  1307.             cxseen = 0 ;
  1308.             czseen = 0 ;
  1309.             discard = 0 ;
  1310.         if (ffc < fsize)        /* don't let clsif() print interrupted msg */
  1311.             ffc=fsize;
  1312.         }
  1313.         else if ( aborted ) {
  1314.             cxseen = 0 ;
  1315.             czseen = 1 ;
  1316.             discard = 0 ;
  1317.         }
  1318.         else {
  1319.             cxseen = 0 ;
  1320.             czseen = 0 ;
  1321.             discard = 1 ;
  1322.         }
  1323.         clsif() ;
  1324.     }
  1325.     else if ( p_cfg.transfer_direction == DIR_RECV ) {
  1326.         if ( successful ) {
  1327.             cxseen = 0 ;
  1328.             czseen = 0 ;
  1329.             discard = 0 ;
  1330.         }
  1331.         else if ( aborted ) {
  1332.             cxseen = 0 ;
  1333.             czseen = 1 ;
  1334.             discard = 0 ;
  1335.         }
  1336.         else {
  1337.             cxseen = 0 ;
  1338.             czseen = 0 ;
  1339.             discard = 0 ;
  1340.         }
  1341.         clsof( !successful ) ;
  1342.     }
  1343.  
  1344.     if (p_cfg.transfer_direction == DIR_RECV) {
  1345.         /* Set the file date */
  1346.         time(×.actime);
  1347.         if (!atcapr || !atdati || date == -1)
  1348.             times.modtime = times.actime;
  1349.         else 
  1350.             times.modtime = date;
  1351.         _utime(*path, ×);
  1352.     }
  1353.  
  1354.     if (p_cfg.transfer_direction == DIR_SEND) {
  1355.         files_left--;
  1356.         bytes_left -= length;
  1357.     }
  1358.     if (offset) {
  1359.         cps = (t_now == t_started ?
  1360.                 offset : offset / (t_now - t_started));
  1361.         sprintf( msgbuf, "%lu bytes, %s, %lu CPS%s",
  1362.                  offset, d_time(t_now - t_started), cps,
  1363.                  !successful ? ", Transfer incomplete" : "");
  1364.         ckscreen(SCR_ST,ST_MSG,0l, msgbuf ) ;
  1365.     }
  1366.     if (p_cfg.transfer_direction == DIR_RECV &&
  1367.          (opt_clean || !keep) &&                /* fdc */
  1368.          !successful)
  1369.     {
  1370.         sprintf( msgbuf,   "Deleting: %s", *path);
  1371.         ckscreen(SCR_ST,ST_MSG,0l,msgbuf ) ;
  1372.         tlog(F110," deleting",*path,0);
  1373.         unlink(*path);
  1374.     } else if (p_cfg.transfer_direction == DIR_SEND && /* fdc */
  1375.                 moving &&                               /* fdc */
  1376.                 successful)
  1377.     {                   /* fdc */
  1378.         sprintf( msgbuf, "Deleting: %s", *path);
  1379.         ckscreen(SCR_ST,ST_MSG,0l, msgbuf);     /* fdc */
  1380.         tlog(F110," deleting",*path,0);
  1381.         unlink(*path);                  /* fdc */
  1382.     }
  1383.     p_ofree( (void **) path, MODULE_CALLBACK, __LINE__ );
  1384.  
  1385.     fncact = savfnc ;
  1386.     return(ret_val);
  1387. }
  1388.  
  1389. U32
  1390. #ifdef CK_ANSIC
  1391. seek_func(U32 pos)
  1392. #else
  1393. seek_func(pos) U32 pos;
  1394. #endif
  1395. {
  1396.   if (zfseek(pos) == -1) {
  1397.       sprintf(msgbuf, "\rFailed to seek in file, %s\n", strerror(errno));
  1398.       ckscreen(SCR_ST,ST_MSG,0l, msgbuf);     /* fdc */
  1399.       debug(F111,"P seek_func","Failed to seek in file",errno);
  1400.       return(1);
  1401.   }
  1402.   else
  1403.       return(0);
  1404. }
  1405.  
  1406. U32
  1407. #ifdef CK_ANSIC
  1408. read_func(U8 *buf, U32 bytes_wanted, U32 *bytes_got)
  1409. #else
  1410. read_func(buf,bytes_wanted,bytes_got)
  1411.      U8 *buf; U32 bytes_wanted; U32 *bytes_got;
  1412. #endif
  1413. {
  1414.     int c ;
  1415.     static int oldc = -1;
  1416.  
  1417.     *bytes_got = 0 ;
  1418.  
  1419.     if ( oldc >= 0 )
  1420.     {
  1421.         *buf = (U8) oldc ;
  1422.         buf++ ;
  1423.         (*bytes_got)++ ;
  1424.         bytes_wanted-- ;
  1425.         oldc = -1 ;
  1426.     }
  1427.  
  1428.     for ( ; bytes_wanted ; bytes_wanted-- )
  1429.     {
  1430.        if ((c = zminchar()) < 0)
  1431.        {
  1432.            if ( bytes_got == 0 )
  1433.            {
  1434.                fprintf(stderr, "\rFailed to read from file, %s\n", strerror(errno));
  1435.                debug(F111,"P read_func","Failed to read from file",errno);
  1436.                return(1);
  1437.            }
  1438.            else
  1439.              return(0);
  1440.        }
  1441.        else
  1442.        {
  1443.            /* Text files are converted by the sender in XMODEM and YMODEM   */
  1444.            /* and by the receiver in ZMODEM.  So for ZMODEM we must convert */
  1445.            /* CR-LF to NL before transmitting.                              */
  1446.            if ( p_cfg.protocol_type != PROTOCOL_Z || binary || c != 13 )
  1447.            {
  1448.                *buf = (U8) c ;
  1449.                buf++ ;
  1450.                (*bytes_got)++ ;
  1451.            }
  1452.            else
  1453.            {
  1454.                *buf = (U8) c ;
  1455.                if ((c = zminchar()) < 0)
  1456.                  return(0) ;
  1457.                if ( c == 10 )
  1458.                {
  1459.                    *buf = (U8) c ;
  1460.                    buf++ ;
  1461.                    (*bytes_got)++ ;
  1462.                }
  1463.                else
  1464.                {
  1465.                    buf++ ;
  1466.                    (*bytes_got)++ ;
  1467.  
  1468.                    if ( bytes_wanted > 1 )
  1469.                    {
  1470.                        *buf = (U8) c ;
  1471.                        buf++ ;
  1472.                        (*bytes_got)++ ;
  1473.                        bytes_wanted-- ;
  1474.                    }
  1475.                    else
  1476.                    {
  1477.                        oldc = c ;
  1478.                    }
  1479.                }
  1480.            }
  1481.        }
  1482.     }
  1483.  
  1484.  
  1485.     return(0);
  1486.  
  1487. }
  1488.  
  1489. U32
  1490. #ifdef CK_ANSIC
  1491. write_func(U8 *buf, U32 bytes)
  1492. #else
  1493. write_func(buf,bytes) U8 *buf; U32 bytes ;
  1494. #endif
  1495. {
  1496.     char str[80];
  1497.  
  1498.     if (zsoutx(ZOFILE,buf,bytes)<0)
  1499.     {
  1500.         sprintf(str,"Failed to write to file, %s", strerror(errno));
  1501.         ckscreen(SCR_ST,ST_ERR,0l,str);
  1502.         debug(F111,"P write_func","Failed to write to file",errno);
  1503.         return(1);
  1504.     }
  1505.     return (0);
  1506. }
  1507.  
  1508. #endif /* XYZ_INTERNAL */
  1509. #endif /* NOXFER */