_WCRTLINK int __F_NAME(chmod,_wchmod)( const CHAR_TYPE *pathname, int pmode ) /***************************************************************************/ { #ifdef __WIDECHAR__ char mbPath[MB_CUR_MAX * _MAX_PATH]; if( wcstombs( mbPath, pathname, sizeof( mbPath ) ) == -1 ) { mbPath[0] = '\0'; } return( chmod( mbPath, pmode ) ); #else unsigned attr; if( _dos_getfileattr( __F_NAME(pathname,mbPath), &attr ) ) { return( -1 ); } attr &= ~_A_RDONLY; if( !( pmode & S_IWRITE ) ) { attr |= _A_RDONLY; } if( _dos_setfileattr( __F_NAME(pathname,mbPath), attr ) ) { return( -1 ); } return( 0 ); #endif }
HB_BOOL hb_fsDirExists( const char * pszDirName ) { HB_BOOL fExist = HB_FALSE; HB_TRACE( HB_TR_DEBUG, ( "hb_fsDirExists(%p)", pszDirName ) ); if( pszDirName != NULL ) { #if defined( HB_OS_WIN ) LPTSTR lpFree; LPCTSTR lpDirName = HB_FSNAMECONV( pszDirName, &lpFree ); DWORD dwAttr; dwAttr = GetFileAttributes( lpDirName ); fExist = ( dwAttr != INVALID_FILE_ATTRIBUTES ) && ( dwAttr & FILE_ATTRIBUTE_DIRECTORY ); if( lpFree ) hb_xfree( lpFree ); #elif defined( HB_OS_OS2 ) HB_FATTR nAttr; fExist = hb_fsOS2QueryPathInfo( pszDirName, NULL, &nAttr, NULL, NULL ) && ( nAttr & HB_FA_DIRECTORY ) != 0; #else char * pszFree = NULL; pszDirName = hb_fsNameConv( pszDirName, &pszFree ); { # if defined( HB_OS_DOS ) # if defined( __DJGPP__ ) || defined( __BORLANDC__ ) int iAttr = _chmod( pszDirName, 0, 0 ); fExist = iAttr != -1 && ( iAttr & 0x10 ) != 0; # else unsigned int iAttr = 0; fExist = _dos_getfileattr( pszDirName, &iAttr ) == 0 && ( iAttr & 0x10 ) != 0; # endif # elif defined( HB_OS_UNIX ) # if defined( HB_USE_LARGEFILE64 ) struct stat64 statbuf; fExist = stat64( pszDirName, &statbuf ) == 0 && S_ISDIR( statbuf.st_mode ); # else struct stat statbuf; fExist = stat( pszDirName, &statbuf ) == 0 && S_ISDIR( statbuf.st_mode ); # endif # else int iTODO; /* To force warning */ # endif } if( pszFree ) hb_xfree( pszFree ); #endif } return fExist; }
HB_BOOL hb_fsFileExists( const char * pszFileName ) { HB_BOOL fExist = HB_FALSE; HB_TRACE( HB_TR_DEBUG, ( "hb_fsFileExists(%p)", pszFileName ) ); if( pszFileName != NULL ) { #if defined( HB_OS_WIN ) LPTSTR lpFree; LPCTSTR lpFileName = HB_FSNAMECONV( pszFileName, &lpFree ); DWORD dwAttr; dwAttr = GetFileAttributes( lpFileName ); fExist = ( dwAttr != INVALID_FILE_ATTRIBUTES ) && ( dwAttr & ( FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE ) ) == 0; if( lpFree ) hb_xfree( lpFree ); #else char * pszFree = NULL; pszFileName = hb_fsNameConv( pszFileName, &pszFree ); { # if defined( HB_OS_DOS ) # if defined( __DJGPP__ ) || defined( __BORLANDC__ ) int iAttr = _chmod( pszFileName, 0, 0 ); fExist = iAttr != -1 && ( iAttr & 0x10 ) == 0; # else unsigned int iAttr = 0; fExist = _dos_getfileattr( pszFileName, &iAttr ) == 0 && ( iAttr & 0x10 ) == 0; # endif # elif defined( HB_OS_OS2 ) FILESTATUS3 fs3; fExist = DosQueryPathInfo( ( PCSZ ) pszFileName, FIL_STANDARD, &fs3, sizeof( fs3 ) ) == NO_ERROR && ( fs3.attrFile & FILE_DIRECTORY ) == 0; # elif defined( HB_OS_UNIX ) struct stat statbuf; fExist = stat( pszFileName, &statbuf ) == 0 && S_ISREG( statbuf.st_mode ); # else int iTODO; /* To force warning */ # endif } if( pszFree ) hb_xfree( pszFree ); #endif } return fExist; }
HB_BOOL hb_fsNameExists( const char * pszFileName ) { HB_BOOL fExist = HB_FALSE; HB_TRACE( HB_TR_DEBUG, ( "hb_fsNameExists(%p)", pszFileName ) ); if( pszFileName != NULL ) { #if defined( HB_OS_WIN ) LPTSTR lpFree; LPCTSTR lpFileName = HB_FSNAMECONV( pszFileName, &lpFree ); fExist = ( GetFileAttributes( lpFileName ) != INVALID_FILE_ATTRIBUTES ); if( lpFree ) hb_xfree( lpFree ); #else char * pszFree = NULL; pszFileName = hb_fsNameConv( pszFileName, &pszFree ); { # if defined( HB_OS_DOS ) # if defined( __DJGPP__ ) || defined( __BORLANDC__ ) fExist = _chmod( pszFileName, 0, 0 ) != -1; # else unsigned int iAttr = 0; fExist = _dos_getfileattr( pszFileName, &iAttr ) == 0; # endif # elif defined( HB_OS_OS2 ) FILESTATUS3 fs3; fExist = DosQueryPathInfo( ( PCSZ ) pszFileName, FIL_STANDARD, &fs3, sizeof( fs3 ) ) == NO_ERROR; # elif defined( HB_OS_UNIX ) # if defined( HB_USE_LARGEFILE64 ) struct stat64 statbuf; fExist = stat64( pszFileName, &statbuf ) == 0; # else struct stat statbuf; fExist = stat( pszFileName, &statbuf ) == 0; # endif # else int iTODO; /* To force warning */ # endif } if( pszFree ) hb_xfree( pszFree ); #endif } return fExist; }
char * _FARFUNC tempnam(char *dir, char *prefix) { char *dirs[4]; int tries; /* Make sure the prefix is 5 characters or less and has no '.' in it. */ if (strlen(prefix) > 5 || strchr(prefix, '.') != NULL) return (NULL); /* Set up the four directories we'll try searching. */ dirs[0] = getenv("TMP"); /* TMP enviroment variable */ dirs[1] = dir; /* dir parameter */ dirs[2] = P_tmpdir; /* stdio.h temp dir */ dirs[3] = ""; /* current directory */ /* Search the four directories. */ for (tries = 0; tries < 4; tries++) { char *dir, *p, *buf; unsigned err, attr, num; /* Allocate a buffer big enough for the complete filename. /* Put the directory name in the buffer, then repeatedly use * __mkname to append a weird name until we get one that * gives a filename that doesn't exist. */ if ((dir = dirs[tries]) == NULL) continue; /* skip NULL directory */ if ((buf = malloc(strlen(dir)+strlen(prefix)+8)) == NULL) continue; /* can't allocate space for dir\preXXXXXX */ p = _stpcpy(buf,dir); if (p != buf && *(p-1) != '/' && *(p-1) != '\\' && *(p-1) != ':') *p++ = '\\'; /* add trailing slash */ for (num = 0; num != TMP_MAX; num++) { __mkname(p, prefix, num); if ((err = _dos_getfileattr(buf, &attr)) != 0) { if (err == 2) /* file not found? */ return (buf); /* return unique name */ else /* some other error */ break; /* give up on this directory */ } } free(buf); /* try next directory */ } return (NULL); /* all four directories failed */ }
// Return whether a file/directory is normally hidden from a directory listing bool OSD::IsHidden (const char* pcszPath_) { #if defined(ALLEGRO_DOS) // Hide entries with the hidden or system attribute bits set UINT uAttrs = 0; return !_dos_getfileattr(pcszPath_, &uAttrs) && (uAttrs & (_A_HIDDEN|_A_SYSTEM)); #elif defined(ALLEGRO_WINDOWS) // Hide entries with the hidden or system attribute bits set DWORD dwAttrs = GetFileAttributes(pcszPath_); return (dwAttrs != 0xffffffff) && (dwAttrs & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)); #else // Hide entries beginning with a dot pcszPath_ = strrchr(pcszPath_, PATH_SEPARATOR); return pcszPath_ && pcszPath_[1] == '.'; #endif }
void ResetArchives( copy_entry *list ) { copy_entry *next; #ifndef __UNIX__ unsigned attr; #endif while( list != NULL ) { next = list->next; #ifndef __UNIX__ if( _dos_getfileattr( list->src, &attr ) == 0 ) { _dos_setfileattr( list->src, attr & ~_A_ARCH ); } #endif free( list ); list = next; } }
/* DoRMdir - perform RM on a specified directory */ void DoRMdir( const char *dir ) { unsigned attribute; int rc; if( ( rc = rmdir( dir ) ) == -1 ) { _dos_getfileattr( dir, &attribute ); if( attribute & _A_RDONLY ) { if( fflag ) { _dos_setfileattr( dir, _A_NORMAL ); rc = rmdir( dir ); } else { PrintALineThenDrop( "Directory %s is read-only, use -f", dir ); error_occured = 1; } } } if( rc == -1 ) { PrintALineThenDrop( "Unable to delete directory %s", dir ); error_occured = 1; } else if( !sflag ) PrintALine( "Deleting directory %s", dir ); }
/* * CopyOneFile - copy one file to another */ void CopyOneFile( char *dest, char *src ) { struct stat stat_s,stat_d; int i; unsigned srcattr; /* * first, check if source exists */ if( stat( src,&stat_s ) == - 1 ) { DropPrintALine("file \"%s\" not found.",src ); return; } _dos_getfileattr( src, &srcattr ); /* * check if the archive bit is set; if not, go back */ if( aflag ) { if( !(srcattr & _A_ARCH) ) { return; } } /* * if destination exists, make sure we can overwrite it */ if( stat( dest,&stat_d ) != -1 ) { #if !( defined( __OS2__ ) && defined( __386__ ) ) if( sameFile( dest, &stat_d, src, &stat_s ) ) { DropPrintALine( "%s and %s the same file, copy failed",src,dest ); return; } #endif if( !(stat_d.st_mode & S_IWRITE) ) { if( !fflag ) { DropPrintALine( "destination file %s is read only - use cp -f", dest); return; } else { chmod( dest, S_IWRITE | S_IREAD ); } } if( iflag ) { PrintALine( "overwrite %s (y\\n)", dest ); i = 0; while( i != 'y' && i != 'n' ) { i=getch(); } DropALine(); if( i=='n' ) { return; } } } /* * copy the file, and if it works, reset archive flag * of source (if needed) */ if( !GrabFile( src, &stat_s, dest, srcattr ) ) { return; } if( aflag ) { _dos_setfileattr( src, srcattr & (~_A_ARCH) ); } } /* CopyOneFile */
static int mkdir_nested( const char *path ) /*****************************************/ { #ifdef __UNIX__ struct stat sb; #else unsigned attr; #endif char pathname[ FILENAME_MAX ]; char *p; char *end; p = pathname; strncpy( pathname, path, FILENAME_MAX ); end = pathname + strlen( pathname ); #ifndef __UNIX__ /* special case for drive letters */ if( p[0] != '\0' && p[1] == ':' ) { p += 2; } #endif /* skip initial path separator if present */ if( (p[0] == '/') || (p[0] == '\\') ) ++p; /* find the next path component */ while( p < end ) { while( (p < end) && (*p != '/') && (*p != '\\') ) ++p; *p = '\0'; /* check if pathname exists */ #ifdef __UNIX__ if( stat( pathname, &sb ) != 0 ) { #else if( _dos_getfileattr( pathname, &attr ) != 0 ) { #endif int rc; #ifdef __UNIX__ rc = mkdir( pathname, S_IRWXU | S_IRWXG | S_IRWXO ); #else rc = mkdir( pathname ); #endif if( rc != 0 ) { Log( false, "Can not create directory '%s': %s\n", pathname, strerror( errno ) ); return( -1 ); } } else { /* make sure it really is a directory */ #ifdef __UNIX__ if( !S_ISDIR( sb.st_mode ) ) { #else if( (attr & _A_SUBDIR) == 0 ) { #endif Log( false, "Can not create directory '%s': file with the same name already exists\n", pathname ); return( -1 ); } } /* put back the path separator - forward slash always works */ *p++ = '/'; } return( 0 ); } static int ProcOneCopy( const char *src, char *dst, bool cond_copy, char *copy_buff ) { FILE *sp; FILE *dp; size_t len; size_t out; struct stat srcbuf; struct utimbuf dstbuf; sp = fopen( src, "rb" ); if( sp == NULL ) { if( cond_copy ) { return( 0 ); // Quietly ignore missing source } else { Log( false, "Can not open '%s' for reading: %s\n", src, strerror( errno ) ); return( 1 ); } } dp = fopen( dst, "wb" ); if( dp == NULL ) { len = strlen( dst ); while( len-- > 0 ) { char c = dst[len]; if( c == '/' || c == '\\' ) { dst[len] = '\0'; mkdir_nested( dst ); dst[len] = c; dp = fopen( dst, "wb" ); break; } } if( dp == NULL ) { Log( false, "Can not open '%s' for writing: %s\n", dst, strerror( errno ) ); fclose( sp ); return( 1 ); } } Log( Quiet, "Copying '%s' to '%s'...\n", src, dst ); while( (len = fread( copy_buff, 1, COPY_BUFF_SIZE, sp )) != 0 ) { if( ferror( sp ) ) { Log( false, "Error reading '%s': %s\n", src, strerror( errno ) ); fclose( sp ); fclose( dp ); return( 1 ); } out = fwrite( copy_buff, 1, len, dp ); if( ferror( dp ) ) { Log( false, "Error writing '%s': %s\n", dst, strerror( errno ) ); fclose( sp ); fclose( dp ); return( 1 ); } if( out != len ) { Log( false, "Error writing '%s': Disk full\n", dst ); fclose( sp ); fclose( dp ); return( 1 ); } } fclose( sp ); fclose( dp ); /* make real copy, set the date back */ stat( src, &srcbuf ); dstbuf.actime = srcbuf.st_atime; dstbuf.modtime = srcbuf.st_mtime; utime( dst, &dstbuf ); #ifdef __UNIX__ /* copy permissions: mostly necessary for the "x" bit */ // some files is copied from the source tree with the read-only permission // for next run we need the write permission for the current user as minimum chmod( dst, srcbuf.st_mode | S_IWUSR ); #endif return( 0 ); } static int ProcCopy( char *cmd, bool test_abit, bool cond_copy, bool ignore_errors ) { char *dst; copy_entry *list; copy_entry *next; int res; for( dst = cmd; *dst != '\0'; ++dst ) { if( IS_BLANK( *dst ) ) { *dst++ = '\0'; dst = SkipBlanks( dst ); break; } } if( *dst == '\0' ) { Log( false, "Missing parameter\n" ); return( 1 ); } res = BuildList( cmd, dst, test_abit, cond_copy, &list ); if( res == 0 && list != NULL ) { char *copy_buff = Alloc( COPY_BUFF_SIZE ); for( ; list != NULL; list = next ) { next = list->next; if( res == 0 || ignore_errors ) { int rc; rc = ProcOneCopy( list->src, list->dst, cond_copy, copy_buff ); if( rc != 0 ) { res = rc; #ifndef __UNIX__ } else if( test_abit ) { list->next = IncludeStk->reset_abit; IncludeStk->reset_abit = list; continue; #endif } } free( list ); } free( copy_buff ); } return( res ); }
cpm_word redir_find(int n, cpm_byte *fcb, cpm_byte *dma) { DIR *hostdir; int drv, attrib; long recs; struct stat st; struct dirent *de; cpm_word rights; drv = (fcb[0] & 0x7F); if (!drv || drv == '?') drv = redir_cpmdrive; else drv--; if (find_xfcb) /* Return another extent */ { memcpy(dma, lastdma, 0x80); dma[0] |= 0x10; /* XFCB */ dma[0x0c] = dma[0x69]; /* Password mode */ dma[0x0d] = 0x0A; /* Password decode byte */ memset(dma + 0x10, '*', 7); dma[0x17] = ' '; /* Encoded password */ memcpy(lastdma, dma, 0x80); find_xfcb = 0; return 0; } if (find_ext) /* Return another extent */ { memcpy(dma, lastdma, 0x80); dma[0x0c]++; if (dma[0x0c] == 0x20) { dma[0x0c] = 0; dma[0x0e]++; } lastsize -= 0x4000; recs = (lastsize + 127) / 128; dma[0x0f] = (recs > 127) ? 0x80 : (recs & 0x7F); if (lastsize <= 0x4000) find_ext = 0; memcpy(lastdma, dma, 0x80); return 0; } memset(dma, 0, 128); /* Zap the buffer */ /* If returning all entries, return a volume label. */ if ((fcb[0] & 0x7F) == '?') { if (!n) { volume_label(drv, dma); return 0; } else --n; } /* Note: This implies that opendir() works on a filename with a trailing slash. It does under Linux, but that's the only assurance I can give. */ entryno = -1; hostdir = opendir(redir_drive_prefix[drv]); if (!hostdir) { redir_Msg("opendir() fails on '%s'\n", redir_drive_prefix[drv]); return 0xFF; } /* We have a handle to the directory. */ while (n >= 0) { de = next_entry(hostdir, fcb, dma + 1, &st); if (!de) { closedir(hostdir); return 0xFF; } --n; } /* Valid entry found & statted. dma+1 holds filename. */ dma[0] = redir_cpmuser; /* Uid always matches */ dma[0x0c] = 0; /* Extent counter, low */ dma[0x0d] = st.st_size & 0x7F; /* Last record byte count */ dma[0x0e] = 0; /* Extent counter, high */ #ifdef __MSDOS__ _dos_getfileattr(target_name, (unsigned int *)&attrib); rights = redir_drdos_get_rights(target_name); if (rights && ((fcb[0] & 0x7F) == '?')) find_xfcb = 1; #else attrib = 0; rights = 0; #endif if (attrib & 1) dma[9] |= 0x80; if (attrib & 4) dma[10] |= 0x80; if (!(attrib & 0x20)) dma[11] |= 0x80; /* TODO: Under Unix, work out correct RO setting */ recs = (st.st_size + 127) / 128; dma[0x0f] = (recs > 127) ? 0x80 : (recs & 0x7F); dma[0x10] = 0x80; if (S_ISDIR(st.st_mode)) dma[0x10] |= 0x40; if (attrib & 2) dma[0x10] |= 0x20; dma[0x10] |= ((entryno & 0x1FFF) >> 8); dma[0x11] = dma[0x10]; dma[0x12] = entryno & 0xFF; redir_wr32(dma + 0x16, st.st_mtime); /* Modification time. */ /* TODO: It should be in DOS */ /* format */ /* TODO: At 0x1A, 1st cluster */ redir_wr32(dma + 0x1C, st.st_size); /* True size */ if (rights) /* Store password mode. Don't return an XFCB. */ { dma[0x69] = redir_cpm_pwmode(rights); memcpy(lastdma, dma, 0x80); } dma[0x60] = 0x21; /* XFCB */ redir_wr32(dma + 0x61, redir_cpmtime(st.st_atime)); redir_wr32(dma + 0x65, redir_cpmtime(st.st_mtime)); closedir(hostdir); if (st.st_size > 0x4000 && (fcb[0x0C] == '?')) /* All extents? */ { lastsize = st.st_size; find_ext = 1; memcpy(lastdma, dma, 0x80); } return 0; }
static int mkdir_nested( char *path ) /***********************************/ { #ifdef __UNIX__ struct stat sb; #else unsigned attr; #endif char pathname[ FILENAME_MAX ]; char *p; char *end; p = pathname; strncpy( pathname, path, FILENAME_MAX ); end = pathname + strlen( pathname ); #ifndef __UNIX__ /* special case for drive letters */ if( p[0] && p[1] == ':' ) { p += 2; } #endif /* skip initial path separator if present */ if( (p[0] == '/') || (p[0] == '\\') ) ++p; /* find the next path component */ while( p < end ) { while( (p < end) && (*p != '/') && (*p != '\\') ) ++p; *p = '\0'; /* check if pathname exists */ #ifdef __UNIX__ if( stat( pathname, &sb ) == -1 ) { #else if( _dos_getfileattr( pathname, &attr ) != 0 ) { #endif int rc; #ifdef __UNIX__ rc = mkdir( pathname, S_IRWXU | S_IRWXG | S_IRWXO ); #else rc = mkdir( pathname ); #endif if( rc != 0 ) { Log( FALSE, "Can not create directory '%s': %s\n", pathname, strerror( errno ) ); return( -1 ); } } else { /* make sure it really is a directory */ #ifdef __UNIX__ if( !S_ISDIR( sb.st_mode ) ) { #else if( (attr & _A_SUBDIR) == 0 ) { #endif Log( FALSE, "Can not create directory '%s': file with the same name already exists\n", pathname ); return( -1 ); } } /* put back the path separator - forward slash always works */ *p++ = '/'; } return( 0 ); } static unsigned ProcOneCopy( char *src, char *dst, bool cond_copy ) { FILE *sp; FILE *dp; unsigned len; unsigned out; struct stat srcbuf; struct utimbuf dstbuf; static char buff[32 * 1024]; sp = fopen( src, "rb" ); if( sp == NULL ) { if( cond_copy ) { return( 0 ); // Quietly ignore missing source } else { Log( FALSE, "Can not open '%s' for reading: %s\n", src, strerror( errno ) ); return( 1 ); } } dp = fopen( dst, "wb" ); if( dp == NULL ) { char *end1, *end2, *end; strcpy( buff, dst ); end1 = strrchr( buff, '/' ); end2 = strrchr( buff, '\\' ); if( end1 && end2 ) { if( end1 > end2 ) end = end1; else end = end2; } else if( end1 ) { end = end1; } else { end = end2; } if( end ) { end[0] = 0; mkdir_nested( buff ); dp = fopen( dst, "wb" ); } if( !dp ) { Log( FALSE, "Can not open '%s' for writing: %s\n", dst, strerror( errno ) ); fclose( sp ); return( 1 ); } } Log( FALSE, "Copying '%s' to '%s'...\n", src, dst ); for( ;; ) { len = fread( buff, 1, sizeof( buff ), sp ); if( len == 0 ) break; if( ferror( sp ) ) { Log( FALSE, "Error reading '%s': %s\n", src, strerror( errno ) ); fclose( sp ); fclose( dp ); return( 1 ); } out = fwrite( buff, 1, len, dp ); if( ferror( dp ) ) { Log( FALSE, "Error writing '%s': %s\n", dst, strerror( errno ) ); fclose( sp ); fclose( dp ); return( 1 ); } if( out != len ) { Log( FALSE, "Error writing '%s': Disk full\n", dst ); fclose( sp ); fclose( dp ); return( 1 ); } } fclose( sp ); fclose( dp ); /* make real copy, set the date back */ stat( src, &srcbuf ); dstbuf.actime = srcbuf.st_atime; dstbuf.modtime = srcbuf.st_mtime; utime( dst, &dstbuf ); #ifdef __UNIX__ /* copy permissions: mostly necessary for the "x" bit */ // some files is copied from the source tree with the read-only permission // for next run we need the write permission for the current user as minimum chmod( dst, srcbuf.st_mode | S_IWUSR ); #endif return( 0 ); } static unsigned ProcCopy( char *cmd, bool test_abit, bool cond_copy ) { char *src; char *dst; copy_entry *list; copy_entry *next; unsigned res; src = cmd; dst = strchr( src, ' ' ); if( dst == NULL ) { dst = strchr( src, '\t' ); if( dst == NULL ) { Log( FALSE, "Missing destination parameter\n" ); return( 1 ); } } *dst = '\0'; dst = SkipBlanks( dst + 1 ); if( *dst == '\0' ) { Log( FALSE, "Missing destination parameter\n" ); return( 1 ); } list = BuildList( src, dst, test_abit ); for( ;; ) { if( list == NULL ) break; res = ProcOneCopy( list->src, list->dst, cond_copy ); if( res != 0 ) { while( list != NULL ) { next = list->next; free( list ); list = next; } return( res ); } next = list->next; if( test_abit ) { list->next = IncludeStk->reset_abit; IncludeStk->reset_abit = list; } else { free( list ); } list = next; } return( 0 ); }
static copy_entry *BuildList( char *src, char *dst, bool test_abit ) { copy_entry *head; copy_entry *curr; copy_entry **owner; char *end; char buff[_MAX_PATH2]; char full[_MAX_PATH]; char srcdir[_MAX_PATH]; char *drive; char *dir; char *fn; char *ext; DIR *directory; struct dirent *dent; #ifndef __UNIX__ FILE *fp; unsigned attr; #else struct stat statsrc, statdst; int dstrc, srcrc; char pattern[_MAX_PATH]; #endif strcpy( srcdir, src ); end = &dst[strlen( dst ) - 1]; while( end[0] == ' ' || end[0] == '\t' ) { --end; } end[1] = '\0'; if( strchr( srcdir, '*' ) == NULL && strchr( srcdir, '?' ) == NULL ) { /* no wild cards */ head = Alloc( sizeof( *head ) ); head->next = NULL; _fullpath( head->src, srcdir, sizeof( head->src ) ); switch( *end ) { case '\\': case '/': /* need to append source file name */ _splitpath2( srcdir, buff, &drive, &dir, &fn, &ext ); _makepath( full, NULL, dst, fn, ext ); _fullpath( head->dst, full, sizeof( head->dst ) ); break; default: _fullpath( head->dst, dst, sizeof( head->dst ) ); break; } if( test_abit ) { #ifndef __UNIX__ fp = fopen( head->dst, "rb" ); if( fp != NULL ) fclose( fp ); _dos_getfileattr( head->src, &attr ); if( !( attr & _A_ARCH ) && fp != NULL ) { /* file hasn't changed */ free( head ); head = NULL; } #else /* Linux has (strangely) no 'archive' attribute, compare modification times */ dstrc = stat( head->dst, &statdst ); srcrc = stat( head->src, &statsrc ); if( (dstrc != -1) && (srcrc != -1) && (statdst.st_mtime == statsrc.st_mtime) ) { free( head ); head = NULL; } #endif } return( head ); } #ifdef __UNIX__ _splitpath2( srcdir, buff, &drive, &dir, &fn, &ext ); _makepath( srcdir, drive, dir, NULL, NULL ); _makepath( pattern, NULL, NULL, fn, ext ); #endif directory = opendir( srcdir ); if( directory == NULL ) { Log( FALSE, "Can not open source directory '%s': %s\n", srcdir, strerror( errno ) ); return( NULL ); } head = NULL; owner = &head; for( ;; ) { dent = readdir( directory ); if( dent == NULL ) break; #ifdef __UNIX__ { struct stat buf; size_t len = strlen( srcdir ); if( __fnmatch( pattern, dent->d_name ) == 0 ) continue; strcat( srcdir, dent->d_name ); stat( srcdir, &buf ); srcdir[len] = '\0'; if( S_ISDIR( buf.st_mode ) ) continue; } #else if( dent->d_attr & ( _A_SUBDIR | _A_VOLID ) ) continue; #endif curr = Alloc( sizeof( *curr ) ); curr->next = NULL; _splitpath2( srcdir, buff, &drive, &dir, &fn, &ext ); _makepath( full, drive, dir, dent->d_name, NULL ); _fullpath( curr->src, full, sizeof( curr->src ) ); strcpy( full, dst ); switch( *end ) { case '\\': case '/': strcat( full, dent->d_name ); break; } _fullpath( curr->dst, full, sizeof( curr->dst ) ); if( test_abit ) { #ifndef __UNIX__ fp = fopen( curr->dst, "rb" ); if( fp != NULL ) fclose( fp ); if( !(dent->d_attr & _A_ARCH) && fp != NULL ) { /* file hasn't changed */ free( curr ); continue; } #else /* Linux has (strangely) no 'archive' attribute, compare modification times */ dstrc = stat( curr->dst, &statdst ); srcrc = stat( curr->src, &statsrc ); if( (dstrc != -1) && (srcrc != -1) && (statdst.st_mtime == statsrc.st_mtime) ) { free( curr ); continue; } #endif } *owner = curr; owner = &curr->next; } return( head ); }
int SendFile (char *FileName) { WaitLoop (DelayToTransmit); int hFile; if ((hFile = open (FileName, O_BINARY | O_RDONLY, FILE_ACCESS)) == -1) { printf ("-Send file %s not found!\n", FileName); return hFile; } dword FileSize = lseek (hFile, 0, SEEK_END), FileOffset = 0; lseek (hFile, 0, SEEK_SET); byte *ClusterBuffer = new byte [SizeOrigCluster]; if (!ClusterBuffer) return (int)ClusterBuffer; LockMemory (ClusterBuffer, SizeOrigCluster, LOCK_MEMORY); // Make file header FileHdr *filehdr = (FileHdr*)ClusterBuffer; filehdr->FileID = get_time () + FileSize; // Is static parametr dword FileHeaderLen = strlen (FileName) + 1 + sizeof (FileAttr); dword FileBlockIndex = 0; // Insert empty frames vint Semaphore = SizeOrigCluster / SizeDataFrame; SendAFrames ((word*)ClusterBuffer, &Semaphore, ID_FRAME, NULL); while (Semaphore > 4) {} while (FileSize && !StopByUser) { CheckOnFreeComBuffer (); BlockHdr *pBH = (BlockHdr*) ((int)ClusterBuffer + sizeof (FileHdr)); dword BlockIndex = FileBlockIndex, BlockInCluster = 0; dword LastBytes = SizeOrigCluster - sizeof (FileHdr); // Divide cluster on blocks while (LastBytes) { if (LastBytes <= sizeof (BlockHdr)) break; BlockInCluster++; LastBytes -= sizeof (BlockHdr); if (BlockIndex) { if (LastBytes >= BLOCK_LEN) pBH->Len = BLOCK_LEN; else pBH->Len = LastBytes; LastBytes -= pBH->Len; } else if (FileHeaderLen <= LastBytes) { pBH->Len = FileHeaderLen; LastBytes -= pBH->Len; } else { BlockInCluster--; LastBytes = 0; break; } BlockIndex++; pBH++; } // Dinamyc part of file header modify filehdr->NumBlock = BlockInCluster; filehdr->HdrLen = sizeof (FileHdr) + BlockInCluster * sizeof (BlockHdr); byte *pClusterData = (byte*)((int)ClusterBuffer + filehdr->HdrLen); pBH = (BlockHdr *) ((int)ClusterBuffer + sizeof (FileHdr)); dword OffsetToData = filehdr->HdrLen; BlockIndex = 0; // Skeleton of cluster data fill while (BlockInCluster && FileSize) { BlockIndex++; if (!FileBlockIndex) { FileAttr *pFA = (FileAttr *)pClusterData; pFA->Size = FileSize; _dos_getfileattr (FileName, &pFA->Attr); #ifdef __GNUC__ _dos_getftime (hFile, &pFA->Date, &pFA->Time); #else _dos_getftime (hFile, (word*)&pFA->Date, (word*)&pFA->Time); #endif strcpy ((char*) ((int)pClusterData + sizeof (FileAttr)), FileName); } else { read (hFile, pClusterData, pBH->Len); pBH->FileOffset = FileOffset; FileOffset += pBH->Len; if (FileSize >= pBH->Len) FileSize -= pBH->Len; else { pBH->Len = FileSize; // truncate block FileSize = 0; // Correct file header filehdr->NumBlock = BlockIndex; filehdr->HdrLen = sizeof (FileHdr) + BlockIndex * sizeof (BlockHdr); } } pBH->Number = FileBlockIndex++; pBH->CRC = GetBlockCRC (pClusterData, pBH->Len); pBH->ClusterOffset = OffsetToData; OffsetToData += pBH->Len; pClusterData += pBH->Len; BlockInCluster--; pBH++; } printf ("BlockInCluster %d\n", BlockIndex); dword CountCluster; while ((CountCluster = SendACluster (1, ClusterBuffer, filehdr->FileID + FileBlockIndex)) != 1) {} } // end while FileSize delete ClusterBuffer; LockMemory (ClusterBuffer, SizeOrigCluster, UNLOCK_MEMORY); close (hFile); while ((SComFlag || RComFlag || StartFlag) && !StopByUser) CheckOnFreeComBuffer (); return 1; }