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

📄 syncupload.c

📁 同步软件源码,作者 Jeroen C. Kessels Internet Engineer
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
   syncupload  --  Send files to a slave.


   AUTHOR

        Jeroen C. Kessels
        Internet Engineer
        http://www.kessels.com/

   Copyright:   Jeroen C. Kessels
   Date:        19 august 2005
   Version:     4.*

*/




#include "version.h"

#include <stdio.h>
#include <time.h>                                                /* ctime(). */
#include <sys/timeb.h>                                          /* _ftime(). */
#include <sys/stat.h>                                             /* stat(). */
#include <io.h>
#include <winsock.h>

#include "md5.h"
#include "common.h"




#define USAGE   "usage:  syncupload [-c] [-d] [-h] [filename(s)]\n\
  -c           Do not copy and/or delete, just compare the files.\n\
  -d           Debug mode, show all network traffic.\n\
  -h           Show this usage text.\n\
  filename(s)  Process workfile(s) 'filename.WRK'.\n"

#define WS_VERSION_REQD 0x0101     /* The minimum winsock version required. */

#define NONE        0
#define READ        1
#define WRITE       2
#define APPEND      3
#define CHANGE      4

struct FileStruct {
  char *Path;
  char *LocalMask;
  char *RemoteMask;
  char Date[15];                                           /* YYYYMMDDHHMMSS */
  unsigned long Size;
  int CopyFlag;
  struct FileStruct *Previous;
  struct FileStruct *Smaller;
  struct FileStruct *Bigger;
  };

struct ExcludeStruct {
  char *Mask;
  struct ExcludeStruct *Next;
  };

int Debug = 0;





void MaskTranslate(char *InputMask, char *OutputMask, char *Path) {
  char s1[BUFSIZ];
  char *p1;
  char *p2;
  char *p3;
  char *p4;
  char *p5;
  int i;

  p1 = InputMask;
  p2 = OutputMask;
  p3 = Path;
  p4 = s1;

  while (*p1 != '\0') {

    /* Compare the InputMask and the Path until a wildcard, they
       must be exactly the same. */
    while ((*p1 != '\0') && (*p1 != '*') && (*p1 != '?')) {
      if (*p1 != *p3) {
        fprintf(stdout,"Error: the path does not match the inputmask.\n");
        fprintf(stdout,"  InputMask: %s\n",InputMask);
        fprintf(stdout,"  OutputMask: %s\n",OutputMask);
        fprintf(stdout,"  Path: %s\n",Path);
        exit(1);
        }
      p1++;
      p3++;
      }

    /* Copy from the OutputMask to the Path until a wildcard. */
    while ((*p2 != '\0') && (*p2 != '*') && (*p2 != '?')) *p4++ = *p2++;

    if (*p1 != *p2) {
      fprintf(stdout,"Error: the inputmask and outputmask do not match.\n");
      fprintf(stdout,"  InputMask: %s\n",InputMask);
      fprintf(stdout,"  OutputMask: %s\n",OutputMask);
      fprintf(stdout,"  Path: %s\n",Path);
      exit(1);
      }

    /* If the wildcard is '?' then copy a single character. */
    if (*p1 == '?') {
      p1++;
      p2++;
      *p4++ = *p3++;
      continue;
      }

    if (*p1 != '\0') *p1++;
    if (*p2 != '\0') *p2++;
    p5 = p1;
    i = 0;
    while ((*p5 != '\0') && (*p5 != '*') && (*p5 != '?')) {
      p5++;
      i++;
      }
    while (*p3 != '\0') {
      if ((i > 0) && (strncmp(p1,p3,i) == 0)) break;
      *p4++ = *p3++;
      }
    if ((i > 0) && (*p3 == '\0')) {
      fprintf(stdout,"Error: the inputmask and path do not match.\n");
      fprintf(stdout,"  InputMask: %s\n",InputMask);
      fprintf(stdout,"  OutputMask: %s\n",OutputMask);
      fprintf(stdout,"  Path: %s\n",Path);
      exit(1);
      }
    }

  *p4 = '\0';
/*
fprintf(stdout,"Path translated:\n");
fprintf(stdout,"  Input path: %s\n",Path);
fprintf(stdout,"  Output path: %s\n",s1);
fprintf(stdout,"  InputMask: %s\n",InputMask);
fprintf(stdout,"  OutputMask: %s\n",OutputMask);
*/
  strcpy(Path,s1);
  }





/* Add a file to the linked list in memory. The list is sorted by filename. */
void AddFile(
    char *Path,
    char *LocalMask,
    char *RemoteMask,
    long Size,
    char *Date,
    int CopyFlag,
    struct FileStruct **Top) {
  struct FileStruct *Here;
  struct FileStruct *Ins;
  struct FileStruct *New;
  int Found;

  /* Search this file in the linked list. */
  Here = *Top;
  Ins = NULL;
  Found = 1;
  while ((Here != NULL) && ((Found = strcmp(Here->Path,Path)) != 0)) {
    Ins = Here;
    if (Found > 0)
      Here = Here->Smaller;
      else Here = Here->Bigger;
    }

  /* If the file is already in the list, then ignore. */
  if (Found == 0) return;

  /* Allocate a new record. */
  New = (struct FileStruct *) malloc (sizeof(struct FileStruct));
  if (New == NULL) {
    fprintf(stdout,"  Error: malloc() returned NULL.\n");
    exit(0);
    }
  New->Path = (char *) malloc (strlen(Path) + 1);
  if (New->Path == NULL) {
    fprintf(stdout,"  Error: malloc() returned NULL.\n");
    exit(0);
    }
  New->LocalMask = (char *) malloc (strlen(LocalMask) + 1);
  if (New->LocalMask == NULL) {
    fprintf(stdout,"  Error: malloc() returned NULL.\n");
    exit(0);
    }
  New->RemoteMask = (char *) malloc (strlen(RemoteMask) + 1);
  if (New->RemoteMask == NULL) {
    fprintf(stdout,"  Error: malloc() returned NULL.\n");
    exit(0);
    }

  /* Fill the new record. */
  strcpy(New->Path,Path);
  strcpy(New->LocalMask,LocalMask);
  strcpy(New->RemoteMask,RemoteMask);
  New->Size = Size;
  New->CopyFlag = CopyFlag;
  strcpy(New->Date,Date);

  /* Add to the linked list. */
  New->Previous = Ins;
  New->Bigger = New->Smaller = NULL;
  if (Ins == NULL) {
      *Top = New;
    } else {
      if (Found > 0) {
          Ins->Smaller = New;
        } else {
          Ins->Bigger = New;
          }
      }

  return;
  }





/* Return the smallest item in the list. */
struct FileStruct *FileSmallest(struct FileStruct *Top) {
  struct FileStruct *Here;

  Here = Top;
  if (Here != NULL)
    while (Here->Smaller != NULL)
      Here = Here->Smaller;
  return(Here);
  }





/* Goto the next bigger item in the list. */
struct FileStruct *FileBigger(struct FileStruct *Here) {
  struct FileStruct *Temp;

  if (Here == NULL) return(Here);
  if (Here->Bigger != NULL) {
      Here = Here->Bigger;
      while (Here->Smaller != NULL) Here = Here->Smaller;
    } else {
      do {
        Temp = Here;
        Here = Here->Previous;
        } while ((Here != NULL) && (Here->Bigger == Temp));
      }
  return(Here);
  }





/* Discard an entire linked list from memory. The subroutine iterates. */
void DropFiles(struct FileStruct *Here) {

  if (Here == NULL) return;
  DropFiles(Here->Smaller);
  DropFiles(Here->Bigger);
  if (Here->Path != NULL) free(Here->Path);
  if (Here->LocalMask != NULL) free(Here->LocalMask);
  if (Here->RemoteMask != NULL) free(Here->RemoteMask);
  free(Here);
  }





/* Return YES if the path matches a mask in the Exclude list. */
int FindExclude(struct ExcludeStruct *Excludes, char *Path) {
  struct ExcludeStruct *Here;

  Here = Excludes;
  while (Here != NULL) {
    if (MatchMask(Path,Here->Mask) == YES) return(YES);
    Here = Here->Next;
    }
  return(NO);
  }




/* Include files. Walk through all files in the root directory, and add all
   the files to the linked list at "Top". Iterate for subdirectories. */
long DoInclude(
    char *InPath,
    char *LocalMask,
    char *RemoteMask,
    struct FileStruct **Top,
    struct ExcludeStruct *Excludes) {
  char Path[BUFSIZ];
  char SearchPath[BUFSIZ];
  char FilePath[BUFSIZ];
  long dirp;
  struct _finddata_t dp;
  char Date[BUFSIZ];
  struct tm *DateTm;
  long Counter;
  char *p1;

  Counter = 0;

  /* Fixup the input path. We need a searchpath with a trailing '*'
     and a path that ends in '/'. */
  strcpy(Path,InPath);
  p1 = strchr(Path,'*');
  if (p1 != NULL) {
      strcpy(SearchPath,Path);
      *p1 = '\0';
    } else {
      sprintf(SearchPath,"%s*",Path);
      p1 = strchr(Path,'\0');
      }
  while ((p1 != Path) && ((*p1 == '\0') || (strchr(DIRSEP,*p1) == NULL))) p1--;
  if (strchr(DIRSEP,*p1) != NULL) p1++;
  *p1 = '\0';

  if (Debug > 0) fprintf(stdout,"  %s\n",SearchPath);

  dirp = _findfirst(SearchPath,&dp);
  if (dirp == -1L) return(Counter);
  do {
    if (strcmp(dp.name,".") == 0) continue;
    if (strcmp(dp.name,"..") == 0) continue;

    /* If this is a file, then list it and continue. */
    if ((dp.attrib & _A_SUBDIR) != _A_SUBDIR) {
      sprintf(FilePath,"%s%s",Path,dp.name);
      if (FindExclude(Excludes,FilePath) == YES) continue;
      DateTm = localtime(&dp.time_write);
      sprintf(Date,"%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);
      AddFile(FilePath,LocalMask,RemoteMask,dp.size,Date,1,Top);
      Counter = Counter + 1;
      continue;
      }

    /* Recurse into the directory by calling myself, except if the
       directory matches an Exclude mask. */
    sprintf(FilePath,"%s%s%c*",Path,dp.name,*DIRSEP);
    if (FindExclude(Excludes,FilePath) == YES) continue;
    Counter = Counter + DoInclude(FilePath,LocalMask,RemoteMask,Top,Excludes);

    } while (_findnext(dirp,&dp) == 0);
  _findclose(dirp);

  return(Counter);
  }





/* Return a string with the error message for GetLastError(). */
void SystemErrorStr(DWORD ErrorCode, char *Out) {
  char s1[BUFSIZ];

  FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
    NULL,ErrorCode,0,s1,BUFSIZ,NULL);
  sprintf(Out,"error %lu: %s",ErrorCode,s1);
  }




/* Return a string with the error message for WSAGetLastError(). */
void SocketErrorStr(int ErrorCode, char *Out) {
  struct {
    int  ErrorCode;
    char *ErrorText;
    } ErrorArray[] = {
      {WSAEINTR,          "Interrupted system call"},
      {WSAEBADF,          "Bad file number"},
      {WSAEACCES,         "Permission denied"},
      {WSAEFAULT,         "Bad address"},
      {WSAEINVAL,         "Invalid argument"},
      {WSAEMFILE,         "Too many open files"},
      {WSAEWOULDBLOCK,    "Operation would block"},
      {WSAEINPROGRESS,    "Operation now in progress"},
      {WSAEALREADY,       "Operation already in progress"},
      {WSAENOTSOCK,       "Socket operation on non-socket"},
      {WSAEDESTADDRREQ,   "Destination address required"},
      {WSAEMSGSIZE,       "Message too long"},
      {WSAEPROTOTYPE,     "Protocol wrong type for socket"},
      {WSAENOPROTOOPT,    "Bad protocol option"},
      {WSAEPROTONOSUPPORT,"Protocol not supported"},
      {WSAESOCKTNOSUPPORT,"Socket type not supported"},
      {WSAEOPNOTSUPP,     "Operation not supported on socket"},
      {WSAEPFNOSUPPORT,   "Protocol family not supported"},
      {WSAEAFNOSUPPORT,   "Address family not supported by protocol family"},
      {WSAEADDRINUSE,     "Address already in use"},
      {WSAEADDRNOTAVAIL,  "Can't assign requested address"},
      {WSAENETDOWN,       "Network is down"},
      {WSAENETUNREACH,    "Network is unreachable"},
      {WSAENETRESET,      "Net dropped connection or reset"},
      {WSAECONNABORTED,   "Software caused connection abort"},
      {WSAECONNRESET,     "Connection reset by peer"},
      {WSAENOBUFS,        "No buffer space available"},
      {WSAEISCONN,        "Socket is already connected"},
      {WSAENOTCONN,       "Socket is not connected"},
      {WSAESHUTDOWN,      "Can't send after socket shutdown"},
      {WSAETOOMANYREFS,   "Too many references, can't splice"},
      {WSAETIMEDOUT,      "Connection timed out"},
      {WSAECONNREFUSED,   "Connection refused"},
      {WSAELOOP,          "Too many levels of symbolic links"},
      {WSAENAMETOOLONG,   "File name too long"},
      {WSAEHOSTDOWN,      "Host is down"},
      {WSAEHOSTUNREACH,   "No Route to Host"},
      {WSAENOTEMPTY,      "Directory not empty"},
      {WSAEPROCLIM,       "Too many processes"},
      {WSAEUSERS,         "Too many users"},
      {WSAEDQUOT,         "Disc Quota Exceeded"},
      {WSAESTALE,         "Stale NFS file handle"},
      {WSAEREMOTE,        "Too many levels of remote in path"},
      {WSASYSNOTREADY,    "Network SubSystem is unavailable"},
      {WSAVERNOTSUPPORTED,"WINSOCK DLL Version out of range"},
      {WSANOTINITIALISED, "Successful WSASTARTUP not yet performed"},
      {WSAHOST_NOT_FOUND, "Host not found"},
      {WSATRY_AGAIN,      "Non-Authoritative Host not found"},
      {WSANO_RECOVERY,    "Non-Recoverable errors: FORMERR, REFUSED, NOTIMP"},
      {WSANO_DATA,        "Valid name, no data record of requested"},
      {WSABASEERR,        ""}
      };
  int i;

  i = 0;
  while ((ErrorArray[i].ErrorCode != ErrorCode) &&
         (*ErrorArray[i].ErrorText != '\0')) i++;
  sprintf(Out,"error %lu: %s",ErrorCode,ErrorArray[i].ErrorText);
  }





/* Receive a single line from the remote. If the incoming data is
   more than the size of the buffer then data is ignored. Return:
   NO:  Error, see WSAGetLastError().
   YES: OK, end of line reached.
   */
int ReceiveRawLine(SOCKET Socket, char *Line, int Width) {
  int Here;
  int Status;
  char c1;

  Here = 0;
  while (1) {
    Status = recv(Socket,&c1,1,0);           /* Receive 1 character. */
    if (Status == 0) break;                /* Leave if no more data. */
    if (Status == SOCKET_ERROR) break;            /* Leave if error. */
    if (c1 == '\r') continue;                          /* Ignore CR. */
    if (c1 == '\0') continue;                        /* Ignore Null. */
    if (c1 == '\n') break;                        /* Leave after LF. */
    if (Here < Width - 1) Line[Here++] = c1;        /* Save in Line. */
    }
  Line[Here] = '\0';
  if (Debug > 0) fprintf(stdout,"<<< %s\n",Line);
  if (Status != 1) return(NO);
  return(YES);
  }




/* Send a message to the remote. */
int SendMsg(SOCKET Socket, char *Message) {
  char s1[BUFSIZ];

  if (Debug > 0) {
    if (strlen(Message) > 500) {
        StringCopyBuf(Message,s1,60);
        fprintf(stdout,">>> %s....\n",s1);
      } else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -