📄 syncupload.c
字号:
fprintf(stdout,">>> %s\n",Message);
}
}
if (send(Socket,Message,strlen(Message),0) <= 0) return(NO);
sprintf(s1,"\r\n");
if (send(Socket,s1,strlen(s1),0) <= 0) return(NO);
return(YES);
}
int HandleSlave(
SOCKET Socket,
char *Password,
char *WorkPath,
struct FileStruct **Top,
struct ExcludeStruct *Excludes,
int CompareOnly) {
char Challenge[BUFSIZ];
char EncodedPassword[BUFSIZ];
FILE *Fin;
size_t BytesRead;
size_t BytesSent;
char Line[BUFSIZ];
char LocalMask[BUFSIZ];
char RemoteMask[BUFSIZ];
struct FileStruct *Here;
char Date[BUFSIZ];
unsigned long Size;
char Path[BUFSIZ];
int Found;
int Status;
long Counter;
long ByteCount;
unsigned char Buf[100000];
md5_byte_t Digest[16];
md5_state_t Context;
struct stat StatBuf;
struct tm *DateTm;
struct _timeb StartTime;
struct _timeb EndTime;
unsigned long TimePassed;
char s1[BUFSIZ];
char s2[BUFSIZ];
char *p1;
int i;
/* Send the SYNCHRONIZE command to the remote, asking for the
Challenge. */
if (SendMsg(Socket,"synchronize") != YES) return(NO);
if (ReceiveRawLine(Socket,Line,BUFSIZ) != YES) return(NO);
p1 = AcceptWord(Line,s1,BUFSIZ);
p1 = AcceptWord(p1,Challenge,BUFSIZ);
if (stricmp(s1,"challenge") != 0) {
fprintf(stdout,"Error: unexpected reply from slave, expected 'CHALLENGE' but got: %s",Line);
return(YES);
}
PasswordEncode(Challenge,Password,s1);
Base64encode(s1,strlen(s1),EncodedPassword,BUFSIZ);
/* Process all the includes from the configuration file and send
a LIST command for every one of them to the remote, asking for
a current list of files on disk. */
fprintf(stdout,"Comparing files...\n");
fflush(stdout);
Fin = fopen(WorkPath,"r");
Status = YES;
while (fgets(Line,BUFSIZ,Fin) != NULL) {
if (*Line == '#') continue;
p1 = AcceptWord(Line,s1,BUFSIZ);
if (stricmp(s1,"include") != 0) continue;
p1 = AcceptWord(p1,s1,BUFSIZ);
striptw(LocalMask,s1);
FixupPath(LocalMask);
p1 = AcceptWord(p1,s1,BUFSIZ);
striptw(RemoteMask,s1);
FixupPath(RemoteMask);
if (strlen(RemoteMask) == 0) strcpy(RemoteMask,LocalMask);
if (Debug > 0) fprintf(stdout," %s\n",LocalMask);
sprintf(s1,"LIST %s %s",EncodedPassword,RemoteMask);
if (Status == YES) Status = SendMsg(Socket,s1);
if (Status == YES) Status = ReceiveRawLine(Socket,Line,BUFSIZ);
if ((Status == YES) && (strnicmp(Line,"ok",2) != 0)) {
fprintf(stdout,"Slave says: %s",Line);
if (strnicmp(Line,"error",5) != 0) Status = NO;
}
/* Compare the list from the remote with the list in memory and
determine wether a file needs to be copied or deleted. */
while (Status == YES) {
Status = ReceiveRawLine(Socket,Line,BUFSIZ);
if (Status != YES) {
SocketErrorStr(WSAGetLastError(),s1);
fprintf(stdout,"Error: %s\n",s1);
break;
}
if (*Line == '.') break;
p1 = AcceptWord(Line,Date,BUFSIZ);
p1 = AcceptWord(p1,s1,BUFSIZ);
Size = atol(s1);
striptw(Path,p1);
FixupPath(Path);
/* Translate the remote filename into it's local equivalent. */
MaskTranslate(RemoteMask,LocalMask,Path);
/* The remote may have listed more files than we want, since it does
not have our Excludes list. They must be filtered out or the files
will be deleted! */
if (FindExclude(Excludes,Path) == YES) continue;
Here = *Top;
Found = 1;
while ((Here != NULL) && ((Found = strcmp(Here->Path,Path)) != 0)) {
if (Found > 0)
Here = Here->Smaller;
else Here = Here->Bigger;
}
if (Found != 0) { /* Not found: deleted. */
AddFile(Path,LocalMask,RemoteMask,Size,Date,2,Top);
continue;
}
if ((Here->Size == Size) && (strcmp(Here->Date,Date) == 0)) {
Here->CopyFlag = 0; /* File not changed. */
}
}
}
fclose(Fin);
/* Send the files that are different. */
if (Status == YES) {
Counter = 0;
ByteCount = 0;
if (CompareOnly == NO) {
fprintf(stdout,"Copying files...\n");
} else {
fprintf(stdout,"List of different files:\n");
}
fflush(stdout);
_ftime(&StartTime);
Here = FileSmallest(*Top);
while ((Here != NULL) && (Status == YES)) {
if (Here->CopyFlag == 1) {
fprintf(stdout," %-12lu %s\n",Here->Size,Here->Path);
fflush(stdout);
if (CompareOnly == NO) {
strcpy(s2,Here->Path);
MaskTranslate(Here->LocalMask,Here->RemoteMask,s2);
sprintf(s1,"UPDATE %s %s %lu %s",EncodedPassword,Here->Date,
Here->Size,s2);
if (Status == YES) Status = SendMsg(Socket,s1);
if (Status == YES) Status = ReceiveRawLine(Socket,Line,BUFSIZ);
if ((Status == YES) && (strnicmp(Line,"ok",2) != 0)) {
fprintf(stdout,"Slave says: %s\n",Line);
if (strnicmp(Line,"error",5) != 0) Status = NO;
}
md5_init(&Context);
BytesSent = 0;
if (Status == YES) {
Fin = fopen(Here->Path,"rb");
while (Status == YES) {
BytesRead = fread(Buf,1,100000,Fin);
if (BytesRead <= 0) break;
if (BytesSent + BytesRead <= Here->Size) {
if (send(Socket,Buf,BytesRead,0) <= 0) Status = NO;
BytesSent = BytesSent + BytesRead;
} else {
if (Here->Size > BytesSent) {
if (send(Socket,Buf,Here->Size - BytesSent,0) <= 0) Status = NO;
}
BytesSent = Here->Size;
}
md5_append(&Context,Buf,BytesRead);
}
fclose(Fin);
}
md5_finish(&Context,Digest);
if (Status == YES) {
if (BytesSent == Here->Size) {
for (i = 0; i < 16; i++) sprintf(Line+2*i,"%02x",Digest[i]);
sprintf(s1,"CHECKSUM %s",Line);
} else {
while ((Status == YES) && (BytesSent < Here->Size)) {
if (BytesSent + 100000 <= Here->Size) {
if (send(Socket,Buf,100000,0) <= 0) Status = NO;
BytesSent = BytesSent + 100000;
} else {
if (send(Socket,Buf,Here->Size - BytesSent,0) <= 0) Status = NO;
BytesSent = Here->Size;
}
}
sprintf(s1,"IGNORE");
}
/* Make sure the file hasn't changed while we were sending it by
comparing it's date/time and size with what we had before we
started sending. */
if (MyStat(Here->Path,&StatBuf) != 0) {
sprintf(s1,"IGNORE");
} else {
DateTm = localtime(&StatBuf.st_mtime);
sprintf(s2,"%04u%02u%02u%02u%02u%02u",DateTm->tm_year + 1900,
DateTm->tm_mon + 1, DateTm->tm_mday, DateTm->tm_hour, DateTm->tm_min,
DateTm->tm_sec);
if ((strcmp(s2,Here->Date) != 0) ||
((unsigned long)StatBuf.st_size != Here->Size)) {
sprintf(s1,"IGNORE");
}
}
Status = SendMsg(Socket,s1);
}
if (Status == YES) Status = ReceiveRawLine(Socket,Line,BUFSIZ);
if ((Status == YES) && (strnicmp(Line,"ok",2) != 0)) {
fprintf(stdout,"Slave says: %s\n",Line);
if (strnicmp(Line,"error",5) != 0) Status = NO;
}
if (Status == YES) ByteCount = ByteCount + Here->Size;
}
Counter = Counter + 1;
}
Here = FileBigger(Here);
}
if (Counter == 0) {
fprintf(stdout," Nothing copied.\n");
} else {
_ftime(&EndTime);
TimePassed = 0;
if (StartTime.time != 0) {
TimePassed = EndTime.time - StartTime.time;
TimePassed = TimePassed * 1000 + EndTime.millitm - StartTime.millitm;
}
fprintf(stdout," %lu files updated, %lu bytes sent, %lu bytes per second.\n",
Counter,ByteCount,ByteCount * 1000 / TimePassed);
}
fflush(stdout);
}
/* Send commands to delete old files. */
if (Status == YES) {
Counter = 0;
if (CompareOnly == NO) {
fprintf(stdout,"Deleting files...\n");
} else {
fprintf(stdout,"List of old files:\n");
}
fflush(stdout);
Here = FileSmallest(*Top);
while (Here != NULL) {
if (Here->CopyFlag == 2) {
fprintf(stdout," %s\n",Here->Path);
fflush(stdout);
if (CompareOnly == NO) {
strcpy(s2,Here->Path);
MaskTranslate(Here->LocalMask,Here->RemoteMask,s2);
sprintf(s1,"DELETE %s %s",EncodedPassword,s2);
if (Status == YES) Status = SendMsg(Socket,s1);
if (Status == YES) Status = ReceiveRawLine(Socket,Line,BUFSIZ);
if ((Status == YES) && (strnicmp(Line,"ok",2) != 0)) {
fprintf(stdout,"Slave says: %s",Line);
if (strnicmp(Line,"error",5) != 0) Status = NO;
}
}
Counter = Counter + 1;
}
Here = FileBigger(Here);
}
if (Counter == 0) {
fprintf(stdout," Nothing deleted.\n");
} else {
fprintf(stdout," %lu files deleted.\n",Counter);
}
fflush(stdout);
}
/* Disconnect from remote. */
Status = SendMsg(Socket,"QUIT");
if (Status == YES) Status = ReceiveRawLine(Socket,Line,BUFSIZ);
if ((Status == YES) && (strnicmp(Line,"ok",2) != 0)) {
fprintf(stdout,"Slave says: %s",Line);
if (strnicmp(Line,"error",5) != 0) Status = NO;
}
/* Cleanup and exit. */
return(YES);
}
void DoSlave(
char *Slave,
char *Password,
char *WorkPath,
int CompareOnly) {
FILE *Fin;
struct FileStruct *Top;
struct ExcludeStruct *Excludes;
struct ExcludeStruct *Exclude;
struct ExcludeStruct *NewExclude;
char Line[BUFSIZ];
char Keyword[BUFSIZ];
char LocalMask[BUFSIZ];
char RemoteMask[BUFSIZ];
WSADATA stWSAData;
SOCKET Socket;
struct hostent *HostEntBuf;
SOCKADDR_IN SocketControl;
unsigned long IpAddress;
int Status;
long Counter;
char s1[BUFSIZ];
char *p1;
/* Collect all the excludes from the configuration file into a linked
list in memory. */
Fin = fopen(WorkPath,"r");
Excludes = NULL;
while (fgets(Line,BUFSIZ,Fin) != NULL) {
if (*Line == '#') continue;
p1 = AcceptWord(Line,Keyword,BUFSIZ);
if (stricmp(Keyword,"exclude") != 0) continue;
p1 = AcceptWord(p1,s1,BUFSIZ);
striptw(LocalMask,s1);
FixupPath(LocalMask);
NewExclude = (struct ExcludeStruct *)malloc(sizeof(struct ExcludeStruct));
if (NewExclude == NULL) {
fprintf(stdout," Error: malloc() returned NULL.\n");
return;
}
NewExclude->Mask = (char *)malloc(strlen(LocalMask) + 1);
if (NewExclude->Mask == NULL) {
fprintf(stdout," Error: malloc() returned NULL.\n");
return;
}
strcpy(NewExclude->Mask,LocalMask);
NewExclude->Next = Excludes;
Excludes = NewExclude;
}
fclose(Fin);
/* Process all the includes from the configuration file. The
specified directories will be scanned and a linked list of all
the files created in memory. */
fprintf(stdout,"Scanning includes...\n");
fflush(stdout);
Top = NULL;
Fin = fopen(WorkPath,"r");
Counter = 0;
while (fgets(Line,BUFSIZ,Fin) != NULL) {
if (*Line == '#') continue;
p1 = AcceptWord(Line,Keyword,BUFSIZ);
if (stricmp(Keyword,"include") != 0) continue;
p1 = AcceptWord(p1,s1,BUFSIZ);
striptw(LocalMask,s1);
FixupPath(LocalMask);
p1 = AcceptWord(p1,s1,BUFSIZ);
striptw(RemoteMask,s1);
FixupPath(RemoteMask);
Counter = Counter + DoInclude(LocalMask,LocalMask,RemoteMask,&Top,Excludes);
}
fclose(Fin);
fprintf(stdout," %lu files found.\n",Counter);
/* Initialize winsock. */
fprintf(stdout,"Contacting slave '%s'...\n",Slave);
fflush(stdout);
Status = YES;
if (WSAStartup(WS_VERSION_REQD,&stWSAData) != 0) Status = NO;
if (Status == YES) {
IpAddress = inet_addr(Slave);
if (IpAddress == INADDR_NONE) {
HostEntBuf = gethostbyname(Slave);
if (HostEntBuf == NULL) {
Status = NO;
} else {
IpAddress = *((u_long FAR *) (HostEntBuf->h_addr));
}
}
}
if (Status == YES) {
Socket = socket(AF_INET,SOCK_STREAM,0);
if (Socket == INVALID_SOCKET) Status = NO;
}
if (Status == YES) {
memcpy(&SocketControl.sin_addr,&IpAddress,sizeof(IpAddress));
SocketControl.sin_port = htons((unsigned short)9577);
SocketControl.sin_family = AF_INET;
if (connect(Socket,(LPSOCKADDR) & SocketControl,sizeof(SocketControl)) != 0) Status = NO;
}
if (Status == YES) {
Status = HandleSlave(Socket,Password,WorkPath,&Top,Excludes,CompareOnly);
}
if (Status != YES) {
SocketErrorStr(WSAGetLastError(),s1);
fprintf(stdout,"Error: %s\n",s1);
}
/* Cleanup and exit. */
fprintf(stdout,"Disconnecting from slave...\n");
fflush(stdout);
shutdown(Socket,2);
closesocket(Socket);
WSACleanup();
DropFiles(Top);
Exclude = Excludes;
while (Exclude != NULL) {
NewExclude = Exclude;
Exclude = Exclude->Next;
free(NewExclude->Mask);
free(NewExclude);
}
}
void DoSlaves(char *InPath, int CompareOnly) {
FILE *Fin;
char WorkPath[BUFSIZ];
char Line[BUFSIZ];
char Keyword[BUFSIZ];
char Slave[BUFSIZ];
char Password[BUFSIZ];
char *p1;
/* Open the configuration file. */
sprintf(WorkPath,"%s.wrk",InPath);
Fin = fopen(WorkPath,"r");
if (Fin == NULL) {
strcpy(WorkPath,InPath);
p1 = strrchr(WorkPath,'.');
if (p1 != NULL) {
strcpy(p1,".wrk");
Fin = fopen(WorkPath,"r");
}
}
if (Fin == NULL) {
fprintf(stdout," Error: could not open config file: %s\n",WorkPath);
return;
}
/* Process all the slaves from the configuration file. */
Fin = fopen(WorkPath,"r");
while (fgets(Line,BUFSIZ,Fin) != NULL) {
if (*Line == '#') continue;
p1 = AcceptWord(Line,Keyword,BUFSIZ);
if ((stricmp(Keyword,"slave") != 0) && (stricmp(Keyword,"server") != 0)) continue;
p1 = AcceptWord(p1,Slave,BUFSIZ);
p1 = AcceptWord(p1,Password,BUFSIZ);
DoSlave(Slave,Password,WorkPath,CompareOnly);
}
fclose(Fin);
}
int main(int argc, char **argv) {
int WorkDone = NO;
int CompareOnly = NO;
int i;
umask(0);
/* Accept arguments from the command line. */
if (argc > 1) {
for (i = 1; i < argc; i++) {
if (strcmp(argv[i],"-c") == 0) {
CompareOnly = YES;
continue;
}
if (strcmp(argv[i],"-d") == 0) {
Debug = 1;
continue;
}
if (strcmp(argv[i],"-h") == 0) {
fprintf(stdout,USAGE);
continue;
}
if (WorkDone == NO) {
fflush(stdout);
fprintf(stdout,"SyncUpload v4.%s, (c) 2005 J.C. Kessels\n",BUILD);
fflush(stdout);
}
DoSlaves(argv[i],CompareOnly);
WorkDone = YES;
}
}
fprintf(stdout,"Finished.\n");
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -