File: copy.cpp

package info (click to toggle)
xstow 1.0.2-1
  • links: PTS
  • area: main
  • in suites: bullseye, buster, sid, stretch
  • size: 1,064 kB
  • ctags: 1,073
  • sloc: cpp: 7,264; sh: 1,216; makefile: 196; awk: 26
file content (114 lines) | stat: -rw-r--r-- 2,590 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
 * $Log: copy.cpp,v $
 * Revision 1.2  2005/07/04 21:59:42  martin
 * added logging to all files
 *
 */
#include "tree.h"
#include <cstdio>
#include "debug.h"

extern "C" {
#include <sys/stat.h>
#include <sys/types.h>
}

// logically this is still the tree module
#define OUT(level) DEBUG_OUT(level, MODULE::TREE)

/*
  On some systems ferror() and feof() are not in the namespace std.  
  But since I do not "like" the 'using' directive, but I wanted to 
  limit the damn #ifdefs too, I putted the stuff into one cpp file.

  Do not wonder that I still write std::string here... that's just my coding style.

  On 32 Bit systems this code has a 2GB file size limit. But who the hell has 
  a > 2GB 'dir', or configuration file to copy?
*/
using namespace std;

bool file_copy( std::string origin, std::string target )
{
    FILE *o,*t;       

    DEBUG( OUT( 3 )( "file_copy: %s => %s\n", origin, target ) );

    if( ( o = fopen( origin.c_str(), "rb" ) ) == NULL )
	return false;
    
    DEBUG( OUT( 3 ) << "opening origin succeeded\n"  );

    if( ( t = fopen( target.c_str(), "w+b" ) ) == NULL )
	return false;

    DEBUG( OUT( 3 ) << "opening target succeeded\n"  );

    const int SIZE = 1024*1024;
    char buffer[SIZE];

    if( ferror( o ) || ferror( t ) )
	return false;

    DEBUG( OUT( 3 ) << "no ferror\n"  );

    do
    {
	size_t rsize = fread( buffer, 1, SIZE, o );
	fwrite( buffer, 1, rsize, t );

	DEBUG( OUT(3)( "wrote %d: bytes error: %d\n", rsize, ferror( o ) ) );


    } while( !feof( o ) && !ferror( o ) && !ferror( t ) );

    fclose( o );
    fclose( t );

    return true;
}

bool dir_copy( std::string origin, std::string target )
{
    CppDir::Directory dir( target );
    
    if( !dir )
    {
	// directory does not exist, create it
	if( mkdir( target.c_str(), 0777 ) != 0 )
	    return false;

	dir = CppDir::Directory( target );
    }

    CppDir::Directory odir( origin );    

    CppDir::Directory::file_list fl = odir.get_files();

    for( CppDir::Directory::file_list_it it = fl.begin(); it != fl.end(); ++it )
    {
	if( it->get_name() == "." ||
	    it->get_name() == ".." )
	    continue;

	std::string no = CppDir::concat_dir( origin, it->get_name() );
	std::string nt = CppDir::concat_dir( target, it->get_name() );

	if( it->get_type() == CppDir::EFILE::DIR )
	{
	    if( !dir_copy( CppDir::concat_dir( origin, it->get_name() ),
			   CppDir::concat_dir( target, it->get_name() ) ) )
		return false;

	} else {

	    OUT(1)( "COPY: %s => %s\n", no, nt );
	
	    if( !file_copy(  no, nt  ) )
		return false;

	}
    }
   
    return true;
}