1 #include "copyfile.h"
2 #include "envdeps.h"
3 #include "log.h"
4
5 #if defined(__OS2__)
6 #define INCL_DOSFILEMGR
7 #define INCL_DOSERRORS
8 #include <os2.h>
9 #elif defined(__NT__)
10 #include <windows.h>
11 #endif
12
13 #ifdef INCS_NEED_DOT_H
14 #include <errno.h>
15 #include <stdio.h> // remove
16 #include <fstream.h>
17 #else
18 #include <errno>
19 #include <stdio> // remove
20 #include <fstream>
21 #endif
22 #include "findfile.h"
23
24 /* copyfile is expected to ...
25 - return COPY_NOTEXIST if the source path exists, but the specified
26 file cannot be found in this path
27 - return COPY_OTHER if any other error occurs, including
28 non-existance of source or destination path, or others
29 - return COPY_NOERR otherwise.
30 */
31
32 static int api_copyfile(const char*, const char*);
33 int copyfile_no_api = 0;
34
copyfile(const char * cpDest,const char * cpSource)35 int copyfile(const char *cpDest, const char *cpSource)
36 {
37 #if defined(__OS2__) || defined(__NT__)
38 if (!copyfile_no_api)
39 {
40 return api_copyfile(cpDest, cpSource);
41 }
42 #endif
43
44 static unsigned char *cpBuf=new unsigned char[BUFLEN];
45 int retval=COPY_NOERR;
46
47 logmsg(LOGDBG, "copyfile: using built-in copy routine");
48 logmsg(LOGDBG, "copyfile: copy %s -> %s", cpSource, cpDest);
49
50 ofstream fo(cpDest,ios::bin|ios::out);
51 if (!fo)
52 {
53 logmsg(LOGDBG, "copyfile: failed to create output stream: %s",
54 strerror(errno));
55 return COPY_OTHER;
56 }
57
58 ifstream fi(cpSource,ios::bin|ios::in);
59 if (!fi)
60 {
61 logmsg(LOGDBG, "copyfile: failed to open input stream: %s",
62 strerror(errno));
63
64 fo.close();
65 remove(cpDest);
66
67 // determine if the path exists or not
68 CArray<CString> *pTemp = findfile(cpSource);
69
70 if (pTemp!=NULL)
71 {
72 if (pTemp->Size() == 0)
73 {
74 delete pTemp;
75 logmsg(LOGDBG, "copyfile: source file did not exist or had zero length");
76 return COPY_NOTEXIST;
77 }
78 delete pTemp;
79 }
80 return COPY_OTHER;
81 }
82
83 logmsg(LOGDBG, "copyfile: successfully opened input and output stream.");
84
85 while (fi)
86 {
87 int gc;
88
89 fi.read(cpBuf,BUFLEN);
90 if ((gc=fi.gcount())!=0)
91 fo.write(cpBuf,gc);
92 if (!fo)
93 {
94 logmsg(LOGDBG, "copyfile: problem when writing output: %s",
95 strerror(errno));
96 retval=COPY_OTHER;
97 break;
98 }
99 }
100
101 fi.close();
102 fo.close();
103 if (retval != COPY_NOERR) // failure
104 {
105 logmsg(LOGDBG, "copyfile: some sort of problem, removing destination");
106 remove(cpDest);
107 }
108 return retval;
109 }
110
111
112 /* Routine for copying via OS2 or Win32 API. This is a lot faster, so
113 copyfile will call it if possible.
114 */
115
api_copyfile(const char * cpDest,const char * cpSource)116 static int api_copyfile(const char *cpDest, const char *cpSource)
117 {
118 #if defined(__OS2__)
119 APIRET rc;
120 HDIR FindHandle;
121 FILEFINDBUF3 FindBuffer;
122 ULONG FindCount;
123
124 logmsg(LOGDBG, "copyfile: using OS/2 API routines");
125
126 FindHandle = HDIR_CREATE; FindCount = 1;
127 logmsg(LOGDBG, "copyfile: DosFindFirst(%s, ...)", cpSource);
128 rc = DosFindFirst((PSZ)cpSource, &FindHandle,
129 FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN |
130 FILE_READONLY,
131 (PVOID)&FindBuffer,
132 sizeof(FindBuffer),
133 &FindCount,
134 FIL_STANDARD);
135 DosFindClose(FindHandle);
136
137 logmsg(LOGDBG, "copyfile: DosFindFirst return code is %d", (int)rc);
138
139 switch(rc)
140 {
141 case ERROR_NO_MORE_FILES:
142 logmsg(LOGDBG, "copyfile: source file does not exist.");
143 return COPY_NOTEXIST;
144 case NO_ERROR: break;
145 default: return COPY_OTHER;
146 }
147
148 logmsg(LOGDBG, "copyfile: DosCopy(%s,%s,%lx)",
149 (PSZ)cpSource,(PSZ)cpDest,DCPY_EXISTING);
150
151 rc = DosCopy((PSZ)cpSource,(PSZ)cpDest,DCPY_EXISTING);
152
153 logmsg(LOGDBG, "copyfile: DosCopy return code is %d", (int)rc);
154
155 switch (rc)
156 {
157 case NO_ERROR: return COPY_NOERR;
158 case ERROR_FILE_NOT_FOUND: return COPY_NOTEXIST;
159 default: return COPY_OTHER;
160 }
161
162 #elif defined(__NT__)
163
164 DWORD rv;
165
166 logmsg(LOGDBG, "copyfile: using Win32 API routines");
167 logmsg(LOGDBG, "copyfile: CopyFile(%s, %s, %d)", (char *) cpSource,
168 (char *)cpDest, (int)FALSE);
169
170 if (CopyFile((LPCTSTR)cpSource,(LPCTSTR)cpDest,FALSE)==TRUE)
171 {
172 logmsg(LOGDBG, "copyfile: CopyFile succeeded");
173 return COPY_NOERR;
174 }
175 else
176 {
177 rv = GetLastError();
178 logmsg(LOGDBG, "copyfile: CopyFile last error is %d", (int) rv);
179 if (rv == ERROR_FILE_NOT_FOUND)
180 {
181 logmsg(LOGDBG, "copyfile: source file does not exist");
182 return COPY_NOTEXIST;
183 }
184 else
185 return COPY_OTHER;
186 }
187
188 #else
189
190 /* suppress warnings about unused parameters and functions*/
191 ((void)(cpDest)); ((void)(cpSource)); ((void)(api_copyfile));
192
193 logmsg(LOGERR, "copyfile: FATAL: don't have a copy API on this platform");
194 return COPY_OTHER;
195
196 #endif
197 }
198
199