📄 dcpxfer.c
字号:
}
lName = spool ? tName : spolName; // choose name to log
return XFER_RECVDATA; /* Switch to data state */
} /*rrfile*/
/*--------------------------------------------------------------------*/
/* r s f i l e */
/* */
/* Receive File Header for a file remote has requested us to */
/* send */
/*--------------------------------------------------------------------*/
XFER_STATE rsfile( void )
{
char fileName[FILENAME_MAX];
struct stat statbuf;
size_t subscript;
expand_path( strcpy(fileName, fName ) ,
securep->pubdir ,
securep->pubdir ,
NULL );
/*--------------------------------------------------------------------*/
/* Let host munge filename as appropriate */
/*--------------------------------------------------------------------*/
strcpy( spolName, fileName ); // Assume remote can type ...
// don't munge the file they want
// sent
/*--------------------------------------------------------------------*/
/* Check if the name is a directory name (end with a '/') */
/*--------------------------------------------------------------------*/
subscript = strlen( fileName ) - 1;
if ((fileName[subscript] == '/') ||
((stat(spolName , &statbuf) == 0) && (statbuf.st_mode & S_IFDIR)))
{
printmsg(3, "rsfile: source is directory \"%s\", rejecting",
spolName);
if (!pktsendstr("RN2")) /* Report cannot send file */
return XFER_LOST; /* School is out, die */
else
return XFER_FILEDONE; /* Tell them to send next file */
} /* if */
/*--------------------------------------------------------------------*/
/* Check the access to the file desired */
/*--------------------------------------------------------------------*/
if ( !ValidateFile( spolName , ALLOW_READ ))
{
if (!pktsendstr("RN2")) /* Report access denied to requestor */
return XFER_LOST;
else
return XFER_FILEDONE; /* Look for next file from master */
} /* if */
/*--------------------------------------------------------------------*/
/* The filename is transformed, try to open it */
/*--------------------------------------------------------------------*/
xfer_stream = FOPEN( spolName, "r" , BINARY_MODE);
/* Open stream to transmit */
if (xfer_stream == NULL)
{
printmsg(0, "rsfile: Cannot open file %s (%s).", fName, spolName);
printerr(spolName);
if (!pktsendstr("RN2")) /* Report cannot send file */
return XFER_LOST; /* School is out, die */
else
return XFER_FILEDONE; /* Tell them to send next file */
} /* if */
#ifndef _Windows // Leave file buffered under Windows
if (setvbuf( xfer_stream, NULL, _IONBF, 0))
{
printmsg(0, "rsfile: Cannot unbuffer file %s (%s).", fName, spolName);
pktsendstr("RN2"); /* Tell them we cannot handle it */
printerr(spolName);
fclose(xfer_stream);
xfer_stream = NULL;
return XFER_ABORT;
} /* if */
#endif
/*--------------------------------------------------------------------*/
/* We have the file open, announce it to the log and to the remote */
/*--------------------------------------------------------------------*/
if (!pktsendstr("RY"))
{
fclose(xfer_stream);
xfer_stream = NULL;
return XFER_LOST;
}
printmsg(0, "Sending \"%s\" (%s) as \"%s\"", fName, spolName, tName);
lName = spolName; // Remember name of file to log
return XFER_SENDDATA; /* Switch to send data state */
} /*rsfile*/
/*--------------------------------------------------------------------*/
/* r d a t a */
/* */
/* Receive Data */
/*--------------------------------------------------------------------*/
XFER_STATE rdata( void )
{
short len;
int used = 0;
do {
if ((*getpkt)((char *) (databuf + used), &len) != DCP_OK)
{
fclose(xfer_stream);
xfer_stream = NULL;
return XFER_LOST;
}
else
used += len;
} while (((int) (used + r_pktsize) <= (int) xferBufSize) && len);
/*--------------------------------------------------------------------*/
/* Write incoming data to the file */
/*--------------------------------------------------------------------*/
if (used && (bufwrite((char *) databuf, used) < (int) used))
{ /* ahd */
printmsg(0, "rdata: Error writing data to file.");
fclose(xfer_stream);
xfer_stream = NULL;
return XFER_ABORT;
}
/*--------------------------------------------------------------------*/
/* Handle end of file */
/*--------------------------------------------------------------------*/
if (len == 0)
return XFER_RECVEOF;
else
return XFER_RECVDATA; /* Remain in data state */
} /*rdata*/
/*--------------------------------------------------------------------*/
/* r e o f */
/* */
/* Process EOF for a received file */
/*--------------------------------------------------------------------*/
XFER_STATE reof( void )
{
struct tm *tmx;
struct timeb now;
long ticks;
char *cy = "CY";
char *cn = "CN";
char *response = cy;
char *rName = spool ? tempName : spolName;
// Name to delete if we have a problem
/*--------------------------------------------------------------------*/
/* Close out the file, checking for I/O errors */
/*--------------------------------------------------------------------*/
fclose(xfer_stream);
if (ferror (xfer_stream ))
{
response = cn; /* Report we had a problem */
printerr( rName );
}
xfer_stream = NULL; /* To make sure! */
/*--------------------------------------------------------------------*/
/* If it was a spool file, rename it to its permanent location */
/*--------------------------------------------------------------------*/
if (spool && equal(response,cy))
{
unlink( spolName ); /* Should be safe, since we only do it
for spool files */
if ( RENAME(tempName, spolName ))
{
printmsg(0,"reof: Unable to rename %s to %s",
tempName, spolName);
response = cn;
printerr(spolName);
} /* if ( RENAME(tempName, spolName )) */
spool = FALSE;
} /* if (equal(response,cy) && spool) */
if (!pktsendstr(response)) /* Announce we accepted the file */
return XFER_LOST; /* No ACK? Return, if so */
if ( !equal(response, cy) ) /* If we had an error, delete file */
{
printmsg(0,"reof: Deleting corrupted file %s", rName );
unlink(rName );
return XFER_ABORT;
} /* if ( !equal(response, cy) ) */
/*--------------------------------------------------------------------*/
/* The file is delivered; compute stats for it */
/*--------------------------------------------------------------------*/
remote_stats.freceived++;
remote_stats.breceived += bytes;
if (bflag[F_SYSLOG] || (debuglevel > 2 ))
{
ftime(&now);
ticks = (now.time - startTime.time) * 1000 +
((long) now.millitm - (long) startTime.millitm);
printmsg(2, "Transfer completed, %ld chars/sec",
(long) ((bytes * 1000) / (ticks ? ticks : 1) ));
if (bflag[F_SYSLOG])
{
tmx = localtime(&now.time);
if ( bflag[F_MULTITASK] )
syslog = FOPEN(SYSLOG, "a",TEXT_MODE);
if ( syslog == NULL )
printerr(SYSLOG);
#ifndef _Windows
else if ((bflag[F_MULTITASK] && setvbuf( syslog, NULL, _IONBF, 0)))
printerr(SYSLOG);
#endif
else {
fprintf( syslog,
"%s!%s %c %s (%d/%d-%02d:%02d:%02d) <- %ld"
" / %ld.%02d secs\n",
hostp->via,
userid,
type,
lName,
(tmx->tm_mon+1), tmx->tm_mday,
tmx->tm_hour, tmx->tm_min, tmx->tm_sec, bytes,
ticks / 1000 , (int) ((ticks % 1000) / 10) );
if ( bflag[F_MULTITASK] )
{
fclose( syslog );
syslog = NULL;
}
}
} /* if (bflag[F_SYSLOG]) */
} /* if (bflag[F_SYSLOG] || (debuglevel > 2 )) */
/*--------------------------------------------------------------------*/
/* Return success to caller */
/*--------------------------------------------------------------------*/
return XFER_FILEDONE; /* go get the next file to process */
} /* reof */
/*--------------------------------------------------------------------*/
/* MISC ROUTINES */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* p k t s e n d s t r */
/* */
/* Transmit a control packet */
/*--------------------------------------------------------------------*/
static boolean pktsendstr( char *s )
{
printmsg(2, ">>> %s", s);
/*--------------------------------------------------------------------*/
/* We flush here because we know we're in control and not */
/* waiting for remote data we could miss. */
/*--------------------------------------------------------------------*/
if ( (! bflag[ F_MULTITASK ]) || (debuglevel > 2) )
fflush( logfile ); /* Known safe place to flush log */
if((*wrmsg)(s) != DCP_OK )
return FALSE;
remote_stats.bsent += strlen(s)+1;
return TRUE;
} /* pktsendstr */
/*--------------------------------------------------------------------*/
/* p k t g e t s t r */
/* */
/* Receive a control packet */
/*--------------------------------------------------------------------*/
static boolean pktgetstr( char *s)
{
if ((*rdmsg)(s) != DCP_OK )
return FALSE;
remote_stats.breceived += strlen( s ) + 1;
printmsg(2, "<<< %s", s);
return TRUE;
} /* pktgetstr */
/*--------------------------------------------------------------------*/
/* b u f _ i n i t */
/* */
/* Alocate buffers for file transfer */
/*--------------------------------------------------------------------*/
static void buf_init( void )
{
xferBufSize = max( s_pktsize, r_pktsize ) * 4;
if ( xferBufSize < BUFSIZ )
xferBufSize = BUFSIZ;
if ( xferBufSize < M_xfer_bufsize )
xferBufSize = M_xfer_bufsize;
#if defined(__OS2__) || defined(WIN32)
if ( xferBufSize < (16 * 1024) )
xferBufSize = 16 * 1024;
#endif
if (databuf == NULL)
databuf = malloc( xferBufSize );
else
databuf = realloc( databuf, xferBufSize );
checkref( databuf );
} /* buf_init */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -