⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syncupload.c

📁 同步软件源码,作者 Jeroen C. Kessels Internet Engineer
💻 C
📖 第 1 页 / 共 2 页
字号:
        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 + -