Pol  Revision:cb584c9
dirfunc.cpp
Go to the documentation of this file.
1 
8 #include <assert.h>
9 #include <ctype.h>
10 #include <errno.h>
11 #include <fcntl.h>
12 #include <io.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <sys\stat.h>
17 
18 #pragma hdrstop
19 
20 #include "clib.h"
21 
22 #include "dirfunc.h"
23 namespace Pol
24 {
25 namespace Clib
26 {
27 // temp stuff for fnsplit/ fnmerge
28 char temp_path[MAXPATH];
29 char temp_drive[MAXDRIVE];
30 char temp_dir[MAXDIR];
31 char temp_fname[MAXFILE];
32 char temp_ext[MAXEXT];
33 
34 int fullsplit( const char* path )
35 {
36 #ifdef _WIN32
37 // FIXME: 2008 Upgrades needed here?
38 #if defined( _MSC_VER ) && ( _MSC_VER <= 1310 ) // up to VS2003
39  _splitpath( path, temp_drive, temp_dir, temp_fname, temp_ext );
40 #else // VS2005 using MS STL, boooooo
41  _splitpath_s( path, temp_drive, MAXDRIVE, temp_dir, MAXDIR, temp_fname, MAXFILE, temp_ext,
42  MAXEXT );
43 #endif
44  return 0;
45 #else
46  return fnsplit( path, temp_drive, temp_dir, temp_fname, temp_ext );
47 #endif
48 }
49 
50 char* fullmerge( char* path )
51 {
52 #ifdef _WIN32
53 // FIXME: 2008 Upgrades needed here?
54 #if defined( _MSC_VER ) && ( _MSC_VER <= 1310 ) // up to VS2003
55  _makepath( path, temp_drive, temp_dir, temp_fname, temp_ext );
56 #else // VS2005 using MS STL, booooo
57  _makepath_s( path, MAXPATH, temp_drive, temp_dir, temp_fname, temp_ext );
58 #endif
59 #else
60  fnmerge( path, temp_drive, temp_dir, temp_fname, temp_ext );
61 #endif
62  return path;
63 }
64 
65 char* mergeFnExt( char* fname )
66 {
67  strzcpy( fname, temp_fname, MAXFILE );
68  strncat( fname, temp_ext, MAXEXT - 1 );
69  return fname;
70 }
71 
72 
74 
75 #ifndef _WIN32
76 int chddir( const char* dir )
77 {
78  // assume: drive is full pathname.
79  int ch = toupper( dir[0] );
80  if ( isalpha( ch ) )
81  setdisk( ch - 'A' );
82  return chdir( dir );
83 }
84 #endif
85 /*
86  the build directory functions:
87  params: directory, filename, node
88  directory: should not include trailing backslash
89 
90  */
91 namespace
92 {
93 const char* use_dir;
94 const char* use_fname;
95 const char* use_template;
96 
97 void find_usefns( const char* dir, const char* fname )
98 {
99  /* first, the directory. */
100  if ( dir && dir[0] ) /* this is not null */
101  use_dir = dir;
102  else
103  use_dir = "."; // current directory.
104 
105  if ( fname && fname[0] )
106  use_fname = fname;
107  else
108  use_fname = ".";
109 
110  // now, if dir has a trailing backslash, we use %s%s
111  // else, we use %s\\%s
112  const char* s = strrchr( use_dir, '\\' );
113  if ( s == NULL )
114  s = strrchr( use_dir, '/' );
115 
116  if ( s != NULL && ( s[1] == '\0' ) ) // is trailing
117  use_template = "%s%s";
118  else
119  use_template = "%s\\%s";
120 }
121 } // namespace
122 
123 char* nodefile( const char* directory, const char* filename, int node )
124 {
125  char buf[20];
126  find_usefns( directory, filename );
127  sprintf( buf, "%s.%%d", use_template );
128  sprintf( workspace2, buf, directory, filename, node );
129  _fullpath( fullpath2, workspace2, sizeof fullpath2 );
130 
131  return fullpath2;
132 }
133 
134 char* buildfn( const char* directory, const char* filename )
135 {
136  // oughta, first, strip off the traling backslash.
137  find_usefns( directory, filename );
138  sprintf( workspace2, use_template, use_dir, use_fname );
139  _fullpath( fullpath2, workspace2, sizeof fullpath2 );
140 
141  return fullpath2;
142 }
143 
144 char* buildfnext( const char* directory, const char* filename, const char* extension )
145 {
146  find_usefns( directory, filename );
147  sprintf( workspace2, use_template, directory, filename );
148  strcat( workspace2, "." );
149  strncat( workspace2, extension, 3 );
150  _fullpath( fullpath2, workspace2, sizeof fullpath2 );
151 
152  return fullpath2;
153 }
154 
155 
156 /*
157  normalize_dir: strip a trailin backslash from a directory.
158  */
159 void normalize_dir( char* dir )
160 {
161  char* s = strrchr( dir, '\\' );
162  if ( s == NULL )
163  return;
164  if ( *( s + 1 ) == '\0' )
165  *s = '\0';
166 }
167 
168 
170 
171 #ifndef _WIN32
172 static int inner_copy( const char* src, const char* dst, int replaceOk )
173 {
174  int in = -1, out = -1; // file handles
175  int result = -1; // default to error
176 
177  int bufsize = 0;
178  void* buf = NULL;
179 
180  for ( bufsize = 0x4000; buf == NULL && bufsize >= 128; bufsize /= 2 )
181  buf = malloc( bufsize );
182  if ( buf == NULL )
183  { /* no errors allowed here! */
184  static char dummy[4];
185  buf = dummy;
186  bufsize = 4;
187  }
188 
189 
190  in = open( src, O_RDONLY | O_BINARY );
191  if ( in >= 0 )
192  {
193  out = open( dst, O_BINARY | O_CREAT | O_RDWR | ( replaceOk ? O_TRUNC : O_EXCL ),
194  S_IREAD | S_IWRITE );
195  if ( out >= 0 )
196  {
197  int lastwrite, nbytes;
198  while ( ( nbytes = read( in, buf, bufsize ) ) > 0 )
199  {
200  lastwrite = write( out, buf, nbytes );
201  if ( lastwrite == -1 )
202  break;
203  }
204  if ( lastwrite >= 0 )
205  {
206 #ifdef _WIN32
207  struct _timeb ftime;
208 #else
209  struct ftime ftime;
210 #endif
211  getftime( in, &ftime );
212  setftime( out, &ftime );
213  result = 0;
214  }
215  else
216  mydir_errno = WRITE_ERROR;
217 
218  close( out );
219  // put this here so if fail 'cause of existence,
220  // we don't remove the unreplaced file!
221  // also, the file must be closed to remove
222  if ( result )
223  remove( dst );
224  }
225  else
226  {
227  mydir_errno = DST_OPEN_ERROR;
228  switch ( errno )
229  {
230  case EEXIST:
231  mydir_errno = DST_ALREADY_EXIST;
232  break;
233  }
234  }
235  close( in );
236  }
237  else
238  {
239  mydir_errno = SRC_OPEN_ERROR;
240  switch ( errno )
241  {
242  case ENOENT:
243  mydir_errno = SRC_NO_EXIST;
244  break;
245  }
246  }
247 
248  assert( buf );
249  if ( bufsize != 4 )
250  free( buf );
251 
252  return result;
253 }
254 
255 int copyFile( const char* src, const char* dst )
256 {
257  int replaceOk = 1;
258  return inner_copy( src, dst, replaceOk );
259 }
260 
261 int copyFileNoRep( const char* src, const char* dst )
262 {
263  int replaceOk = 0;
264  return inner_copy( src, dst, replaceOk );
265 }
266 
267 static int inner_move( const char* src, const char* dst, int replaceOk )
268 {
269  if ( replaceOk && access( dst, 0 ) == 0 )
270  remove( dst ); // let rename work
271  if ( rename( src, dst ) == 0 )
272  return 0; // same drive, no replace.
273  else if ( inner_copy( src, dst, replaceOk ) == 0 )
274  {
275  remove( src );
276  return 0;
277  }
278  else
279  return -1;
280 }
281 
282 int moveFile( const char* src, const char* dst )
283 {
284  int replaceOk = 1;
285  return inner_move( src, dst, replaceOk );
286 }
287 int moveFileNoRep( const char* src, const char* dst )
288 {
289  int replaceOk = 0;
290  return inner_move( src, dst, replaceOk );
291 }
292 #endif
293 }
294 }
static Pathname workspace2
Definition: dirfunc.cpp:73
int moveFileNoRep(const char *src, const char *dst)
Definition: dirfunc.cpp:287
int copyFileNoRep(const char *src, const char *dst)
Definition: dirfunc.cpp:261
char temp_ext[MAXEXT]
Definition: dirfunc.cpp:32
char * buildfnext(const char *directory, const char *filename, const char *extension)
Definition: dirfunc.cpp:144
char * buildfn(const char *directory, const char *filename)
Definition: dirfunc.cpp:134
char temp_dir[MAXDIR]
Definition: dirfunc.cpp:30
int moveFile(const char *src, const char *dst)
Definition: dirfunc.cpp:282
char temp_drive[MAXDRIVE]
Definition: dirfunc.cpp:29
int mydir_errno
Definition: dirfunc.cpp:169
static int inner_move(const char *src, const char *dst, int replaceOk)
Definition: dirfunc.cpp:267
void normalize_dir(char *dir)
Definition: dirfunc.cpp:159
int copyFile(const char *src, const char *dst)
Definition: dirfunc.cpp:255
void dummy()
Definition: testmisc.cpp:23
char temp_path[MAXPATH]
Definition: dirfunc.cpp:28
int chddir(const char *dir)
Definition: dirfunc.cpp:76
char * nodefile(const char *directory, const char *filename, int node)
Definition: dirfunc.cpp:123
static int inner_copy(const char *src, const char *dst, int replaceOk)
Definition: dirfunc.cpp:172
char * fullmerge(char *path)
Definition: dirfunc.cpp:50
char temp_fname[MAXFILE]
Definition: dirfunc.cpp:31
int fullsplit(const char *path)
Definition: dirfunc.cpp:34
static Pathname fullpath2
Definition: dirfunc.cpp:73
#define strzcpy
Definition: clib.h:154
char * mergeFnExt(char *fname)
Definition: dirfunc.cpp:65
char Pathname[MAXPATH]
Definition: dirfunc.h:22
Definition: berror.cpp:12