00001 00002 /* 00003 * THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE 00004 * CHECKED IT OUT USING THE COMMAND CHECKOUT. 00005 * 00006 * $Id: remote__copy_8c-source.html 2161 2006-05-19 16:55:03Z paulf $ 00007 * 00008 * Revision history: 00009 * $Log$ 00009 * Revision 1.1 2006/05/19 16:55:02 paulf 00009 * first inclusion 00009 * 00010 * Revision 1.1 2000/02/14 18:53:30 lucky 00011 * Initial revision 00012 * 00013 * 00014 */ 00015 00016 /*************************************************************************** 00017 * remote_copy.c * 00018 * Windows NT version * 00019 * * 00020 * Copies a file from local machine to a remote machine using rcp. * 00021 * * 00022 * NOTE: This has been modified from the library version of copyfile !!! * 00023 * The destination path is constructed externally and the file is * 00024 * copied with a name change following the copy. The file names * 00025 * are all given with directory paths to provide greater * 00026 * versatility. This routine is used primarily to copy GIF and html * 00027 * files to webservers. * 00028 *************************************************************************** 00029 * For this function to work, make sure that the following files are * 00030 * set up properly on the remote machine: * 00031 * /etc/hosts must contain address and localhostname * 00032 * /etc/hosts.equiv must contain local_hostname * 00033 * .rhosts in <userid>'s home directory must contain a * 00034 * line: local_hostname local_username * 00035 * describing who is running this program. * 00036 * * 00037 * * 00038 * fullname full name of file to copy. /dir/filename * 00039 * tname temporary name of file to copy. /dir/filename * 00040 * fname final name of file to copy. /dir/filename * 00041 * host remote machine to copy file to * 00042 * userid use this user name on remote machine * 00043 * passwd userid's password on remote machine (not needed by NT) * 00044 * * 00045 * errtxt string to return error message in * 00046 * mypid external process id to preserve re-entrancy * 00047 * mystat external status variable to preserve re-entrancy * 00048 * * 00049 * Also make sure that entries for the remote host are in the * 00050 * local machine's \winnt\system32\drivers\etc\hosts file. * 00051 * * 00052 * Returns 0 if all is ok * 00053 * 1 if error creating the child process * 00054 * 2 if error waiting for the child process to complete * 00055 * 3 if the child process ended abnormally * 00056 ***************************************************************************/ 00057 00058 #include <stdio.h> 00059 #include <string.h> 00060 #include <windows.h> 00061 #include <earthworm.h> 00062 00063 00064 int remote_copy( char *fullname, /* Name of /dir/file to copy */ 00065 char *tname, /* Temporary remote file name */ 00066 char *fname, /* Final remote file name */ 00067 char *host, /* Remote machine to copy file to */ 00068 char *dir, /* Directory on remote machine */ 00069 char *userid, /* Use this user name on remote machine */ 00070 char *passwd, /* Userid's password on remote machine */ 00071 char *errtxt, /* String to return error message in */ 00072 pid_t *mypid, /* ext. process id to preserve re-entrancy */ 00073 int *mystat ) /* ext. status variable for re-entrancy */ 00074 00075 00076 { 00077 char rcpPath[175]; /* Copy the file to this path */ 00078 char tmpName[100]; /* Temporary file name */ 00079 char finalName[100]; /* Final name for the copied file */ 00080 char commandLine[100]; /* Command that invokes the child proc */ 00081 DWORD display; 00082 BOOL success; 00083 DWORD priorityClass; 00084 DWORD rc; 00085 DWORD exitCode; 00086 00087 STARTUPINFO startUpInfo; 00088 PROCESS_INFORMATION procInfo; 00089 00090 /* Build temporary and final path names on the target system 00091 *********************************************************/ 00092 sprintf( rcpPath, "%s.%s:%s%s", host, userid, dir, tname ); 00093 sprintf( tmpName, "%s%s", dir, tname ); 00094 sprintf( finalName, "%s%s", dir, fname ); 00095 00096 /* Retrieve the STARTUPINFOR structure for the current process. 00097 Use this structure for the child processes. 00098 ***********************************************************/ 00099 GetStartupInfo( &startUpInfo ); 00100 00101 /* Copy the file using rcp 00102 ***********************/ 00103 display = 0; /* Do not create a new console window */ 00104 00105 priorityClass = GetPriorityClass( GetCurrentProcess() ); 00106 00107 sprintf( commandLine, "rcp %s %s", fullname, rcpPath ); 00108 00109 success = CreateProcess( 0, 00110 commandLine, /* Command line to invoke child */ 00111 0, 0, /* No security attributes */ 00112 FALSE, /* No inherited handles */ 00113 display | /* Child does not get a window */ 00114 priorityClass, /* Same as priority of parent */ 00115 0, /* Not passing environmental vars */ 00116 0, /* Current dir same as parent */ 00117 &startUpInfo, /* Attributes of process window */ 00118 &procInfo ); /* Attributes of child process */ 00119 if ( !success ) { 00120 sprintf( errtxt, "Error starting the rcp command: %d", GetLastError() ); 00121 return 1; 00122 } 00123 00124 /* Wait 2 minutes for the remote copy to complete. 00125 Check the process exit code for abnormal termination. 00126 ****************************************************/ 00127 rc = WaitForSingleObject( procInfo.hProcess, 120000 ); 00128 00129 if ( rc == WAIT_FAILED ) { 00130 sprintf( errtxt, "rcp WaitForSingleObject() failed with error: %d", GetLastError() ); 00131 return 2; 00132 } 00133 if ( rc == WAIT_TIMEOUT ) { 00134 sprintf( errtxt, "Error. Remote copy not completed within 2 minutes." ); 00135 return 2; 00136 } 00137 success = GetExitCodeProcess( procInfo.hProcess, &exitCode ); 00138 if ( !success ) { 00139 sprintf( errtxt, "Error getting the rcp exit code: %d", GetLastError() ); 00140 return 3; 00141 } 00142 if ( exitCode != 0 ) { 00143 strcpy( errtxt, "Remote copy failed." ); 00144 return 3; 00145 } 00146 00147 /* Close the process and thread handles for rcp 00148 ********************************************/ 00149 success = CloseHandle( procInfo.hProcess ); 00150 if ( !success ) { 00151 sprintf( errtxt, "Error closing the rcp process handle: %d", GetLastError() ); 00152 return 3; 00153 } 00154 success = CloseHandle( procInfo.hThread ); 00155 if ( !success ) { 00156 sprintf( errtxt, "Error closing the rcp thread handle: %d", GetLastError() ); 00157 return 3; 00158 } 00159 00160 /* Rename the remote file using rsh 00161 ********************************/ 00162 sprintf( commandLine, "rsh %s -l %s /usr/bin/mv %s %s", 00163 host, userid, tmpName, finalName ); 00164 00165 success = CreateProcess( 0, 00166 commandLine, /* Command line to invoke child */ 00167 0, 0, /* No security attributes */ 00168 FALSE, /* No inherited handles */ 00169 display | /* Child does not get a window */ 00170 priorityClass, /* Same as priority of parent */ 00171 0, /* Not passing environmental vars */ 00172 0, /* Current dir same as parent */ 00173 &startUpInfo, /* Attributes of process window */ 00174 &procInfo ); /* Attributes of child process */ 00175 if ( !success ) { 00176 sprintf( errtxt, "Error starting the rsh command: %d", GetLastError() ); 00177 return 1; 00178 } 00179 00180 /* Wait 2 minutes for the remote move command to complete. 00181 Check the process exit code for abnormal termination. 00182 ******************************************************/ 00183 rc = WaitForSingleObject( procInfo.hProcess, 120000 ); 00184 00185 if ( rc == WAIT_FAILED ) { 00186 sprintf( errtxt, "rsh WaitForSingleObject() failed with error: %d", GetLastError() ); 00187 return 2; 00188 } 00189 if ( rc == WAIT_TIMEOUT ) { 00190 sprintf( errtxt, "Error. Remote mv command not completed within 2 minutes." ); 00191 return 2; 00192 } 00193 success = GetExitCodeProcess( procInfo.hProcess, &exitCode ); 00194 if ( !success ) { 00195 sprintf( errtxt, "Error getting the rsh exit code: %d", GetLastError() ); 00196 return 3; 00197 } 00198 if ( exitCode != 0 ) { 00199 strcpy( errtxt, "Remote mv command failed." ); 00200 return 3; 00201 } 00202 00203 /* Close the process and thread handles for rsh 00204 ********************************************/ 00205 success = CloseHandle( procInfo.hProcess ); 00206 if ( !success ) { 00207 sprintf( errtxt, "Error closing the rsh process handle: %d", GetLastError() ); 00208 return 3; 00209 } 00210 success = CloseHandle( procInfo.hThread ); 00211 if ( !success ) { 00212 sprintf( errtxt, "Error closing the rsh thread handle: %d", GetLastError() ); 00213 return 3; 00214 } 00215 00216 /* Everything went smoothly 00217 ************************/ 00218 return 0; 00219 }