1 /***************************************************************************
2  *
3  * $Header: /usr/local/cvsroot/utils/ytree/copy.c,v 1.22 2011/01/09 12:28:01 werner Exp $
4  *
5  * Kopieren von Dateien / Verzeichnissen
6  *
7  ***************************************************************************/
8 
9 
10 #include "ytree.h"
11 
12 
13 
14 static int Copy(char *to_path, char *from_path);
15 static int CopyArchiveFile(char *to_path, char *from_path);
16 
17 
18 
CopyFile(Statistic * statistic_ptr,FileEntry * fe_ptr,unsigned char confirm,char * to_file,DirEntry * dest_dir_entry,char * to_dir_path,BOOL path_copy)19 int CopyFile(Statistic *statistic_ptr,
20              FileEntry *fe_ptr,
21              unsigned char confirm,
22              char *to_file,
23              DirEntry *dest_dir_entry,
24              char *to_dir_path,       /* absoluter Pfad */
25              BOOL path_copy
26 	    )
27 {
28   LONGLONG    file_size;
29   char        from_path[PATH_LENGTH+1];
30   char        from_dir[PATH_LENGTH+1];
31   char        to_path[PATH_LENGTH+1];
32   char        abs_path[PATH_LENGTH+1];
33   char        buffer[20];
34   FileEntry   *dest_file_entry;
35   FileEntry   *fen_ptr;
36   struct stat stat_struct;
37   int         term;
38   int         result;
39   DIR         *tmpdir = NULL;
40   int	      refresh_dirwindow = FALSE;
41 
42 
43   result = -1;
44 
45   (void) GetRealFileNamePath( fe_ptr, from_path );
46   (void) GetPath(fe_ptr->dir_entry, from_dir);
47 
48   *to_path = '\0';
49   if( strcmp( to_dir_path, FILE_SEPARATOR_STRING ) )
50   {
51     /* not ROOT */
52     /*----------*/
53 
54     (void) strcat( to_path, to_dir_path );
55   }
56   if( path_copy )
57   {
58     (void) GetPath( fe_ptr->dir_entry, &to_path[strlen(to_path)] );
59 
60     /* Create destination folder (if neccessary) */
61     /*-------------------------------------------*/
62     strcat(to_path, FILE_SEPARATOR_STRING );
63 
64     if(*to_path != FILE_SEPARATOR_CHAR) {
65          strcpy(abs_path, from_dir);
66 	 strcat(abs_path, FILE_SEPARATOR_STRING);
67 	 strcat(abs_path, to_path);
68 	 strcpy(to_path, abs_path);
69     }
70 
71     if( MakePath( statistic_ptr->tree, to_path, &dest_dir_entry ) )
72     {
73      	 (void) sprintf( message,
74                          "Can't create path*\"%s\"*%s",
75                          to_path,
76                          strerror(errno)
77                          );
78          MESSAGE( message );
79          return( result );
80     }
81   }
82   (void) strcat( to_path, FILE_SEPARATOR_STRING );
83   if ((tmpdir = opendir(to_path)) == NULL)
84     if (errno == ENOENT) {
85      if ( (term =InputChoise( "Directory does not exist; create (y/N) ? ", "YN\033" ))== 'Y')
86      {
87         if(*to_path != FILE_SEPARATOR_CHAR) {
88           strcpy(abs_path, from_dir);
89 	  strcat(abs_path, FILE_SEPARATOR_STRING);
90 	  strcat(abs_path, to_path);
91 	  strcpy(to_path, abs_path);
92         }
93         if (MakePath(statistic_ptr->tree, to_path, &dest_dir_entry ) )
94         {
95                 closedir(tmpdir);
96                 (void) sprintf( message,
97                                 "Can't create path*\"%s\"*%s",
98                                 to_path,
99                                 strerror(errno)
100                                 );
101                 MESSAGE( message );
102                 return( result );
103         }
104 	else
105 	{
106 		refresh_dirwindow = TRUE;
107 	}
108      }
109      else
110      {
111         if( tmpdir)
112 	  closedir(tmpdir);
113 
114         return ( result );
115      }
116   }
117   (void) strcat( to_path, to_file );
118 
119 
120 #ifdef DEBUG
121   fprintf( stderr, "Copy: \"%s\" --> \"%s\"\n", from_path, to_path );
122 #endif /* DEBUG */
123 
124   if( !strcmp( to_path, from_path ) )
125   {
126     MESSAGE( "Can't copy file into itself" );
127     return( result );
128   }
129 
130 
131   if( dest_dir_entry )
132   {
133     /* Ziel befindet sich im Sub-Tree */
134     /*--------------------------------*/
135 
136     (void) GetFileEntry( dest_dir_entry, to_file, &dest_file_entry );
137 
138     if( dest_file_entry )
139     {
140       /* Datei existiert */
141       /*-----------------*/
142 
143       if( confirm )
144       {
145 	term = InputChoise( "file exist; overwrite (Y/N) ? ", "YN\033" );
146 
147         if( term != 'Y' )
148         {
149 	  result = (term == 'N' ) ? 0 : -1;  /* Abort on escape */
150           ESCAPE;
151         }
152       }
153 
154       (void) DeleteFile( dest_file_entry );
155     }
156   }
157   else
158   {
159     /* access benutzen */
160     /*-----------------*/
161 
162     if( !access( to_path, F_OK ) )
163     {
164       /* Datei existiert */
165       /*-----------------*/
166 
167       if( confirm )
168       {
169 	term = InputChoise( "file exist; overwrite (Y/N) ? ", "YN\033" );
170 
171         if( term != 'Y' )
172         {
173 	  result = (term == 'N' ) ? 0 : -1;  /* Abort on escape */
174           ESCAPE;
175         }
176       }
177     }
178   }
179 
180 
181   if( !Copy( to_path, from_path ) )
182   {
183     /* File wurde kopiert */
184     /*--------------------*/
185 
186     if( chmod( to_path, fe_ptr->stat_struct.st_mode ) == -1 )
187     {
188       sprintf( message, "Can't chmod file*\"%s\"*to mode %s*IGNORED",
189                to_path, GetAttributes(fe_ptr->stat_struct.st_mode, buffer) );
190       WARNING( message );
191     }
192 
193     if( dest_dir_entry )
194     {
195       if( STAT_( to_path, &stat_struct ) )
196       {
197         ERROR_MSG( "Stat Failed*ABORT" );
198         exit( 1 );
199       }
200 
201       file_size = stat_struct.st_size;
202 
203       dest_dir_entry->total_bytes += file_size;
204       dest_dir_entry->total_files++;
205       statistic_ptr->disk_total_bytes += file_size;
206       statistic_ptr->disk_total_files++;
207       dest_dir_entry->matching_bytes += file_size;
208       dest_dir_entry->matching_files++;
209       statistic_ptr->disk_matching_bytes += file_size;
210       statistic_ptr->disk_matching_files++;
211 
212       /* File eintragen */
213       /*----------------*/
214 
215       if( ( fen_ptr = (FileEntry *) malloc( sizeof( FileEntry ) + strlen( to_file ) ) ) == NULL )
216       {
217         ERROR_MSG( "Malloc Failed*ABORT" );
218         exit( 1 );
219       }
220 
221       (void) strcpy( fen_ptr->name, to_file );
222 
223       (void) memcpy( &fen_ptr->stat_struct,
224 		     &stat_struct,
225 		     sizeof( stat_struct )
226 		   );
227 
228       fen_ptr->dir_entry   = dest_dir_entry;
229       fen_ptr->tagged      = FALSE;
230       fen_ptr->matching    = Match( fen_ptr->name );
231       fen_ptr->next        = dest_dir_entry->file;
232       fen_ptr->prev        = NULL;
233       if( dest_dir_entry->file ) dest_dir_entry->file->prev = fen_ptr;
234       dest_dir_entry->file = fen_ptr;
235     }
236 
237     (void) GetAvailBytes( &statistic_ptr->disk_space );
238 
239     result = 0;
240   }
241 
242   if( refresh_dirwindow)
243   {
244   	RefreshDirWindow();
245   }
246 
247 FNC_XIT:
248 
249   move( LINES - 3, 1 ); clrtoeol();
250   move( LINES - 2, 1 ); clrtoeol();
251   move( LINES - 1, 1 ); clrtoeol();
252 
253   return( result );
254 }
255 
256 
257 
258 
259 
GetCopyParameter(char * from_file,BOOL path_copy,char * to_file,char * to_dir)260 int GetCopyParameter(char *from_file, BOOL path_copy, char *to_file, char *to_dir)
261 {
262   char buffer[PATH_LENGTH + 1];
263 
264   if( from_file == NULL )
265   {
266     from_file = "TAGGED FILES";
267     (void) strcpy( to_file, "*" );
268   }
269   else
270   {
271     (void) strcpy( to_file, from_file );
272   }
273 
274   if( path_copy )
275   {
276     (void) sprintf( buffer, "PATHCOPY %s", from_file );
277   }
278   else
279   {
280     (void) sprintf( buffer, "COPY %s", from_file );
281   }
282 
283   ClearHelp();
284 
285   MvAddStr( LINES - 3, 1, buffer );
286   MvAddStr( LINES - 2, 1, "AS   ");
287 
288   if( InputString(to_file, LINES - 2, 6, 0, COLS - 6, "\r\033" ) == CR){
289     MvAddStr( LINES - 1, 1, "TO   " );
290     if( InputString( to_dir, LINES - 1, 6, 0, COLS - 6, "\r\033" ) == CR )
291     return( 0 );
292   }
293   ClearHelp();
294   return( -1 );
295 }
296 
297 
298 
299 
300 
Copy(char * to_path,char * from_path)301 static int Copy(char *to_path, char *from_path)
302 {
303   int         i, o, n;
304   char        buffer[2048];
305 
306   if( mode != DISK_MODE && mode != USER_MODE )
307   {
308     return( CopyArchiveFile( to_path, from_path ) );
309   }
310 
311 #ifdef DEBUG
312   fprintf( stderr, "Copy: \"%s\" --> \"%s\"\n", from_path, to_path );
313 #endif /* DEBUG */
314 
315   if( !strcmp( to_path, from_path ) )
316   {
317     MESSAGE( "Can't copy file into itself" );
318     return( -1 );
319   }
320 
321   if( ( i = open( from_path, O_RDONLY ) ) == -1 )
322   {
323     (void) sprintf( message, "Can't open file*\"%s\"*%s", from_path, strerror(errno) );
324     MESSAGE( message );
325     return( -1 );
326   }
327 
328   if( ( o = open( to_path,
329 		  O_CREAT | O_TRUNC | O_WRONLY,
330                   S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
331       ) ) == -1 )
332   {
333     (void) sprintf( message,
334 		    "Can't open file*\"%s\"*%s",
335 		    to_path,
336 		    strerror(errno)
337 		  );
338     MESSAGE( message );
339     (void) close( i );
340     return( -1 );
341   }
342 
343   while( ( n = read( i, buffer, sizeof( buffer ) ) ) > 0 )
344   {
345     if( write( o, buffer, n ) != n )
346     {
347       (void) sprintf( message, "Write-Error!*%s", strerror(errno) );
348       MESSAGE( message );
349       (void) close( i ); (void) close( o );
350       (void) unlink( to_path );
351       return( -1 );
352     }
353   }
354 
355   (void) close( i ); (void) close( o );
356 
357   return( 0 );
358 }
359 
360 
361 
362 
363 
364 
CopyTaggedFiles(FileEntry * fe_ptr,WalkingPackage * walking_package)365 int CopyTaggedFiles(FileEntry *fe_ptr, WalkingPackage *walking_package)
366 {
367   char new_name[PATH_LENGTH+1];
368   int  result = -1;
369 
370   walking_package->new_fe_ptr = fe_ptr;  /* unchanged */
371 
372   if( BuildFilename( fe_ptr->name,
373 		     walking_package->function_data.copy.to_file,
374 		     new_name
375 		   ) == 0 )
376   {
377     if( *new_name == '\0' )
378     {
379       MESSAGE( "Can't copy file to*empty name" );
380     }
381 
382     result = CopyFile( walking_package->function_data.copy.statistic_ptr,
383 		       fe_ptr,
384 		       walking_package->function_data.copy.confirm,
385 		       new_name,
386 		       walking_package->function_data.copy.dest_dir_entry,
387 		       walking_package->function_data.copy.to_path,
388 		       walking_package->function_data.copy.path_copy
389 		     );
390   }
391 
392   return( result );
393 }
394 
395 
396 
397 
398 
CopyArchiveFile(char * to_path,char * from_path)399 static int CopyArchiveFile(char *to_path, char *from_path)
400 {
401   char *command_line;
402   char buffer[PATH_LENGTH + 3];
403   char from_p_aux[PATH_LENGTH + 1];
404   char to_p_aux[PATH_LENGTH + 1];
405   char *archive;
406   int result = -1;
407 
408   if( ( command_line = (char *)malloc( COMMAND_LINE_LENGTH + 1 ) ) == NULL )
409   {
410     ERROR_MSG( "Malloc failed*ABORT" );
411     exit( 1 );
412   }
413 
414   (void) StrCp( to_p_aux, to_path );
415   (void) sprintf( buffer, "> %s", to_p_aux );
416 
417   archive = (mode == TAPE_MODE) ? statistic.tape_name : statistic.login_path;
418 
419   (void) StrCp( from_p_aux, from_path);
420   MakeExtractCommandLine( command_line,
421 			  archive,
422                           from_p_aux,
423 			  buffer
424 			);
425 
426   result = SilentSystemCall( command_line );
427 
428   free( command_line );
429 
430   if( result )
431   {
432     (void) sprintf( message, "can't copy file*%s*to file*%s", from_p_aux, to_p_aux );
433     WARNING( message );
434   }
435   return( result );
436 }
437 
438 
439