📄 syncput.c
字号:
ext = strrchr(fname, '.'); if (ext == NULL) return (kTypeBinary); ext++; STRNCPY(extbuf, ext); for (i=0, len=(int) strlen(extbuf); i<len; i++) if (isupper((int) extbuf[i])) extbuf[i] = (char) tolower(extbuf[i]); STRNCPY(buf, gTextExts); for (i=0, len=(int) strlen(buf); i<len; i++) if (isupper((int) buf[i])) buf[i] = (char) tolower(buf[i]); delims = ".;, \t\r\n"; for (tok = strtok(buf, delims); tok != NULL; tok = strtok(NULL, delims)) { if (strcmp(tok, ext) == 0) return (kTypeAscii); } return (kTypeBinary);} /* GetFileTypeBasedOffOfExtension */static intCopyFiles(void){ FTPFileInfoPtr fip; int i, n; int result; int xtype; char *cp, relDir[256], curRelDir[256]; STRNCPY(curRelDir, ""); n = gFiles.nFileInfos; if (n < 1) return (0); for (i=0; i<n; i++) { fip = gFiles.vec[i];#if 0 printf("\n\n%c %-10lu size=%-10d %s\n", fip->type, fip->mdtm, (int) fip->size, fip->lname );#endif STRNCPY(relDir, fip->relname); cp = StrRFindLocalPathDelim(relDir); if (cp != NULL) *cp = '\0'; else relDir[0] = '\0'; if (strcmp(relDir, curRelDir) != 0) { /* This file was in a different * directory than the one before. * * We now need to change back to * our starting directory, and then * change to each sub-node in the * new relative directory. */ result = FTPChdir(&gConn, gRDirActual); if (result != 0) { (void) fprintf(stderr, "NcFTPSyncPut: chdir back to %s failed: %s.\n", gRDirActual, FTPStrError(result)); return (-1); } STRNCPY(curRelDir, relDir); if (curRelDir[0] != '\0') result = FTPChdir3(&gConn, curRelDir, NULL, 0, (kChdirOneSubdirAtATime|kChdirAndMkdir)); if (result != 0) { (void) fprintf(stderr, "NcFTPSyncPut: chdir to %s failed: %s.\n", curRelDir, FTPStrError(result)); return (-1); } } if (fip->type == 'l') { if ((fip->rlinkto != NULL) && (fip->relname != NULL)) { cp = StrRFindLocalPathDelim(fip->relname); if (cp == NULL) cp = fip->relname; else cp++; (void) FTPSymlink(&gConn, fip->rlinkto, cp); } } else { xtype = GetFileTypeBasedOffOfExtension(fip->lname); result = FTPPutFiles3(&gConn, fip->lname, ".", kRecursiveNo, kGlobNo, xtype, kAppendNo, NULL, ".tmp", kResumeNo, kDeleteNo, kNoFTPConfirmResumeUploadProc, 0); if (result != 0) { (void) fprintf(stderr, "NcFTPSyncPut: file send error for %s: %s.\n", fip->lname, FTPStrError(result)); return (result); } } } n = gFilesToDelete.nFileInfos; if ((n < 1) || (gDeleteRemoteFiles == 0)) return (0); if (gConn.startingWorkingDirectory == NULL) { (void) fprintf(stderr, "NcFTPSyncPut: could not change back to starting directory.\n"); (void) fprintf(stderr, "This is required to synchronize remote deletions.\n"); /* Don't reupload everything everytime... */ return (0); } return 0;} /* CopyFiles */static intDeleteFiles(void){ FTPFileInfoPtr fip; int i, n; int result; char *cp, *fname, relDir[256], curRelDir[256]; STRNCPY(curRelDir, ""); n = gFilesToDelete.nFileInfos; if (n < 1) return (0); for (i=0; i<n; i++) { fip = gFilesToDelete.vec[i];#if 0 printf("\n\n%c %-10lu size=%-10d %s\n", fip->type, fip->mdtm, (int) fip->size, fip->lname );#endif relDir[0] = '\0'; cp = StrFindLocalPathDelim(fip->relname); if (cp != NULL) { STRNCPY(relDir, fip->relname); relDir[(int) (cp - fip->relname)] = '\0'; fname = cp + 1; } else { fname = fip->relname; } if (strcmp(relDir, curRelDir) != 0) { /* This file was in a different * directory than the one before. * * We now need to change back to * our starting directory, and then * change to each sub-node in the * new relative directory. */ result = FTPChdir(&gConn, gRDirActual); if (result != 0) { (void) fprintf(stderr, "NcFTPSyncPut: chdir back to %s failed: %s.\n", gRDirActual, FTPStrError(result)); return (-1); } STRNCPY(curRelDir, relDir); if (curRelDir[0] != '\0') result = FTPChdir3(&gConn, curRelDir, NULL, 0, (kChdirOneSubdirAtATime)); if (result != 0) { /* Assume parent directory (and the file) have been deleted. */ continue; } } if (fip->type == 'd') continue; /* We only handle 'l' and '-' (links, files) */ result = FTPDelete(&gConn, fname, kRecursiveNo, kGlobNo); if (result != 0) { (void) fprintf(stderr, "NcFTPSyncPut: remote delete of %s failed: %s.\n", fip->lname, FTPStrError(result)); continue; } } return 0;} /* DeleteFiles */static int StrToBool(const char *const s){ int c; int result; c = *s; if (isupper(c)) c = tolower(c); result = 0; switch (c) { case 'f': /* false */ case 'n': /* no */ break; case 'o': /* test for "off" and "on" */ c = (int) s[1]; if (isupper(c)) c = tolower(c); if (c == 'f') break; result = 1; break; case 't': /* true */ case 'y': /* yes */ result = 1; break; default: /* 1, 0, -1, other number? */ if (atoi(s) != 0) result = 1; } return result;} /* StrToBool */static voidSetDebugLog(const char *const fn){ if ((gConn.debugLog != NULL) && (gConn.debugLog != stderr) && (gConn.debugLog != stdout)) { (void) fclose(gConn.debugLog); } if (strcmp(fn, "stdout") == 0) gConn.debugLog = stdout; else if (fn[0] == '-') gConn.debugLog = stdout; else if (strcmp(fn, "stderr") == 0) gConn.debugLog = stderr; else gConn.debugLog = fopen( fn,#ifdef WIN32 "wt"#else "w"#endif );} /* SetDebugLog */static voidReadSyncputConfigFile(const char *fn, FTPCIPtr cip){ FILE *fp; char line[128]; char *cp, *tokstart;#ifndef WIN32 (void) chmod(fn, 0600);#endif cp = StrRFindLocalPathDelim(fn); STRNCPY(gConfigFileNameOnly, cp ? (cp + 1) : fn); fp = fopen(fn,#ifdef WIN32 "rt"#else "r"#endif ); if (fp == NULL) { perror(fn); exit(kExitBadConfigFile); } line[sizeof(line) - 1] = '\0'; while (fgets(line, sizeof(line) - 1, fp) != NULL) { cp = line; while (*cp && isspace((int) *cp)) cp++; if ((cp[0] == '#') || (cp[0] == '[') || (cp[0] == ';') || (isspace((int) cp[0]))) continue; tokstart = cp; cp = line + strlen(line) - 1; if (*cp == '\n') { *cp-- = '\0'; if (*cp == '\r') *cp-- = '\0'; } if (strncmp(tokstart, "user", 4) == 0) { (void) STRNCPY(cip->user, tokstart + 5); } else if (strncmp(tokstart, "password", 8) == 0) { (void) STRNCPY(cip->pass, tokstart + 9); } else if ((strncmp(tokstart, "pass", 4) == 0) && ((isspace((int) tokstart[4])) || (tokstart[4] == '='))) { (void) STRNCPY(cip->pass, tokstart + 5); } else if (strncmp(tokstart, "host", 4) == 0) { (void) STRNCPY(cip->host, tokstart + 5); } else if (strncmp(tokstart, "port", 4) == 0) { cip->port = atoi(tokstart + 5); } else if ((strncmp(tokstart, "acct", 4) == 0) && ((isspace((int) tokstart[4])) || (tokstart[4] == '='))) { (void) STRNCPY(cip->acct, tokstart + 5); } else if (strncmp(tokstart, "account", 7) == 0) { (void) STRNCPY(cip->acct, tokstart + 8); } else if (strncmp(tokstart, "ldir", 4) == 0) { (void) STRNCPY(gLDir, tokstart + 5); } else if (strncmp(tokstart, "rdir", 4) == 0) { (void) STRNCPY(gRDir, tokstart + 5); } else if (strncmp(tokstart, "catalog-file", 12) == 0) { (void) STRNCPY(gCatalogFile, tokstart + 13); cp = StrRFindLocalPathDelim(gCatalogFile); if (cp == NULL) gCatalogFileNameOnly = gCatalogFile; else gCatalogFileNameOnly = cp + 1; } else if (strncmp(tokstart, "cur-catalog-file", 16) == 0) { (void) STRNCPY(gDebugCurCatalogFile, tokstart + 17); } else if (strncmp(tokstart, "textexts", 8) == 0) { (void) STRNCPY(gTextExts, tokstart + 9); } else if (strncmp(tokstart, "umask", 5) == 0) { (void) STRNCPY(gUmaskStr, tokstart + 6); } else if (strncmp(tokstart, "sync-deletes", 12) == 0) { gDeleteRemoteFiles = StrToBool(tokstart + 13);#ifdef WIN32 } else if (strncmp(tokstart, "pathnames-to-lowercase", 22) == 0) { gRPathsToLowercase = StrToBool(tokstart + 23);#endif } else if (strncmp(tokstart, "passive", 7) == 0) { if (StrToBool(tokstart + 8)) cip->dataPortMode = kPassiveMode; else cip->dataPortMode = kSendPortMode; } else if (strncmp(tokstart, "debug-log", 9) == 0) { SetDebugLog(tokstart + 10); } } (void) fclose(fp);} /* ReadSyncputConfigFile */main_void_return_tmain(int argc, char **argv){ int result, c; ExitStatus es; int progmeters; int tryUtime = 1; int showListOnly = 0; int updateListOnly = 0; GetoptInfo opt; InitWinsock(); result = FTPInitLibrary(&gLib); if (result < 0) { (void) fprintf(stderr, "NcFTPSyncPut: init library error %d (%s).\n", result, FTPStrError(result)); DisposeWinsock(); exit(kExitInitLibraryFailed); } result = FTPInitConnectionInfo(&gLib, &gConn, kDefaultFTPBufSize); if (result < 0) { (void) fprintf(stderr, "NcFTPSyncPut: init connection info error %d (%s).\n", result, FTPStrError(result)); DisposeWinsock(); exit(kExitInitConnInfoFailed); } memset(gCatalogFile, 0, sizeof(gCatalogFile)); memset(gDebugCurCatalogFile, 0, sizeof(gDebugCurCatalogFile)); memset(gLDir, 0, sizeof(gLDir)); memset(gRDir, 0, sizeof(gRDir)); memset(gUmaskStr, 0, sizeof(gUmaskStr)); gConn.xferTimeout = 60 * 60; gConn.connTimeout = 30; gConn.ctrlTimeout = 135; gConn.debugLog = NULL; gConn.errLog = stderr; (void) STRNCPY(gConn.user, "anonymous"); progmeters = GetDefaultProgressMeterSetting(); GetoptReset(&opt); while ((c = Getopt(&opt, argc, argv, "P:u:p:e:d:t:vUVFyl")) > 0) switch(c) { case 'P': gConn.port = atoi(opt.arg); break; case 'u': (void) STRNCPY(gConn.user, opt.arg); break; case 'p': (void) STRNCPY(gConn.pass, opt.arg); /* Don't recommend doing this! */ break; case 'e': if (strcmp(opt.arg, "stdout") == 0) gConn.errLog = stdout; else if (opt.arg[0] == '-') gConn.errLog = stdout; else if (strcmp(opt.arg, "stderr") == 0) gConn.errLog = stderr; else gConn.errLog = fopen(opt.arg, "a"); break; case 'd': SetDebugLog(opt.arg); break; case 't': SetTimeouts(&gConn, opt.arg); break; case 'v': progmeters = 1; break; case 'V': progmeters = 0; break; case 'F': if (gConn.dataPortMode == kPassiveMode) gConn.dataPortMode = kSendPortMode; else gConn.dataPortMode = kPassiveMode; break; case 'y': tryUtime = 1; break; case 'U': updateListOnly++; break; case 'l': showListOnly = 1; break; default: Usage(); } if (opt.ind > argc - 1) Usage(); ReadSyncputConfigFile(argv[opt.ind], &gConn); if (gLDir[0] == '\0') { fprintf(stderr, "You haven't specified a local directory.\n"); Usage(); } StrRemoveTrailingSlashes(gLDir); if (gRDir[0] == '\0') { fprintf(stderr, "You haven't specified a remote directory.\n"); Usage(); } StrRemoveTrailingSlashes(gRDir); if (gCatalogFile[0] == '\0') { fprintf(stderr, "You haven't specified a catalog file.\n"); Usage(); } if (gConn.host[0] == '\0') { fprintf(stderr, "You haven't specified a remote host.\n"); Usage(); } InitOurDirectory(); LoadFirewallPrefs(); if ((strcmp(gConn.user, "anonymous") != 0) && (strcmp(gConn.user, "ftp") != 0) && (gConn.pass[0] == '\0')) (void) GetPass("Password: ", gConn.pass, sizeof(gConn.pass)); if (progmeters != 0) gConn.progress = PrStatBar; if ((tryUtime == 0) && (gConn.hasSITE_UTIME < 1)) gConn.hasSITE_UTIME = 0; if (MayUseFirewall(gConn.host) != 0) { gConn.firewallType = gFirewallType; (void) STRNCPY(gConn.firewallHost, gFirewallHost); (void) STRNCPY(gConn.firewallUser, gFirewallUser); (void) STRNCPY(gConn.firewallPass, gFirewallPass); gConn.firewallPort = gFirewallPort; } CollectListOfChangedFiles(); if ((gFiles.nFileInfos < 1) && (gFilesToDelete.nFileInfos < 1)) { (void) fprintf(stdout, "No files have been added, removed, or changed since the last update.\n"); es = kExitSuccess; DisposeWinsock(); exit((int) es); } if (showListOnly != 0) { if (gFiles.nFileInfos > 0) { (void) fprintf(stdout, "New or changed files:\n"); PrintFileList(&gFiles); } if (gFilesToDelete.nFileInfos > 0) { (void) fprintf(stdout, "\nDeleted files:\n"); PrintFileList(&gFilesToDelete); } es = kExitSuccess; DisposeWinsock(); exit((int) es); } if (updateListOnly >= 2) { /* -UU */ UpdateCatalogFile(); es = kExitSuccess; DisposeWinsock(); exit((int) es); } es = kExitOpenTimedOut; if ((result = FTPOpenHost(&gConn)) < 0) { (void) fprintf(stderr, "NcFTPSyncPut: cannot open %s: %s.\n", gConn.host, FTPStrError(result)); es = kExitOpenFailed; DisposeWinsock(); exit((int) es); } if (gUmaskStr[0] != '\0') { result = FTPUmask(&gConn, gUmaskStr); if (result != 0) (void) fprintf(stderr, "NcFTPSyncPut: umask failed: %s.\n", FTPStrError(result)); } result = FTPChdir3(&gConn, gRDir, gRDirActual, sizeof(gRDirActual), (kChdirAndMkdir|kChdirAndGetCWD|kChdirOneSubdirAtATime)); if (result != 0) { (void) fprintf(stderr, "NcFTPSyncPut: chdir %s failed: %s.\n", gRDir, FTPStrError(result)); } if (result >= 0) { es = kExitXferTimedOut; (void) signal(SIGINT, Abort); if (CopyFiles() == 0) { DeleteFiles(); es = kExitSuccess; } } (void) FTPCloseHost(&gConn); if ((es == kExitSuccess) && (UpdateCatalogFile() < 0)) es = kExitBadConfigFile; DisposeWinsock(); exit((int) es);} /* main */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -