📄 sfs.cpp
字号:
int st = c->WriteHttp("PUT", SFS_SEARCH_URL, NULL, buffer, NULL, size); delete [] buffer; if (st) return -1; buffer = c->ReadHttp(NULL, -1, NULL, &size); if (!buffer) return -1; size = k.Decrypt(buffer, size, buffer); if (size <= 0) { delete [] buffer; return -1; } buffer[size] = '\0'; int count = 0; char *b = (char*) buffer; for (;;) { if (InsertResponse(resps, &count, b, &b)) break; } delete [] buffer; return 0;}static intHandleSearch(PTP::Collection *collect, PTP::List *keys, PTP::Net::Ip localIp, PTP::Net::Port localPort, PTP::Net::Connection *c){ int datasize; BYTE *data = c->ReadHttp(NULL, -1, NULL, &datasize); if (!data) return -1; unsigned long keyid = PTP::Net::Get32(data); Key *key = FindKey(keys, keyid); if (!key) { delete [] data; return -1; } PTP::Key k(key->shared.key); int size = k.Decrypt(data + 4, datasize - 4, data); if (size <= 0) { delete [] data; return -1; } data[size] = '\0'; BYTE buffer[2048]; char *b = (char*) buffer; PTP::Collection::Entry *entry = NULL; b += sprintf(b, "<HTML>\n"); for (;;) { entry = collect->Find((char*) data, entry); if (!entry) break; b += sprintf(b, "<A HREF=\"" "http://%lu.%lu.%lu.%lu:%u/%08lx/%08lx" "\">%s</A><BR>\n", (localIp >> 24) & 0xff, (localIp >> 16) & 0xff, (localIp >> 8) & 0xff, localIp & 0xff, localPort, PTP::Net::Get32(key->shared.keyid), entry->GetId() ^ key->shadow, entry->GetName()); } b += sprintf(b, "</HTML>\n"); size = k.Encrypt(buffer, strlen((char*) buffer), buffer); delete [] data; if (c->WriteHttp(PTP::Net::HTTP_OK, NULL, buffer, NULL, size)) return -1; return 0;}static intGetRead(BYTE *buffer, int size, void *context){ TransferContext *ctx = (TransferContext*) context; return ctx->c->Read(buffer, size);}static intGetWrite(const BYTE *buffer, int size, void *context){ TransferContext *ctx = (TransferContext*) context; return fwrite(buffer, 1, size, ctx->fp);}static intGet(PTP::Net::Connection *c, Key *key, const char *url, const char *path, int *total){ if (STRNCMP_CONST(url, "http://") == 0) url = strchr(url + 7, '/'); else url = strchr(url, '/'); if (c->WriteHttp("GET", url, NULL, NULL, NULL, 0)) return -1; int status; char *hdr = c->ReadHttpHdr(NULL, -1, &status, NULL); delete [] hdr; if (status != PTP::Net::HTTP_OK) return -1; FILE *fp = fopen(path, "wb"); if (!fp) return -1; PTP::Key k(key->shared.key); TransferContext ctx(c, fp); int size = 0; if ((key->flags & SFS_FLAGS_PLAINTEXT_XFER) == 0) size = k.Decrypt(GetRead, GetWrite, &ctx, SFS_READ_SIZE); else { size = PTP::Key::Transfer(GetRead, GetWrite, &ctx, SFS_READ_SIZE); } fclose(fp); if (size <= 0) { unlink(path); return -1; } if (total) *total = size; return 0;}static intHandleGetRead(BYTE *buffer, int size, void *context){ TransferContext *ctx = (TransferContext*) context; return fread(buffer, 1, size, ctx->fp);}static intHandleGetWrite(const BYTE *buffer, int size, void *context){ TransferContext *ctx = (TransferContext*) context; return ctx->c->WriteAll(buffer, size);}static intHandleGet(PTP::Collection *collect, PTP::List *keys, PTP::Net::Connection *c){ char *hdr = c->ReadHttpHdr(NULL, -1, NULL, NULL); if (!hdr) return -1; char *d = hdr + 5; unsigned long keyid = strtoul(d, &d, 16); unsigned long id = strtoul(d + 1, NULL, 16); delete [] hdr; Key *key = FindKey(keys, keyid); if (!key) return -1; id ^= key->shadow; PTP::Collection::Entry *entry = collect->Find(id); if (!entry) return -1; FILE *fp = fopen(entry->GetPath(), "rb"); if (!fp) return -1; PTP::Key k(key->shared.key); int size = k.Encrypt(NULL, entry->GetSize(), NULL); if (c->WriteHttp(PTP::Net::HTTP_OK, NULL, NULL, NULL, size)) return -1; TransferContext ctx(c, fp); if ((key->flags & SFS_FLAGS_PLAINTEXT_XFER) == 0) k.Encrypt(HandleGetRead, HandleGetWrite, &ctx, SFS_READ_SIZE); else { PTP::Key::Transfer(HandleGetRead, HandleGetWrite, &ctx, SFS_READ_SIZE); } fclose(fp); return 0;}static intShare(PTP::Store *store, PTP::List *keys, PTP::Net::Ip localIp, PTP::Net::Port localPort, PTP::Collection *collect){ PTP::Net::Connection serv(PTP::Net::Connection::HTTP, localPort); PTP::Authenticator auth(store); for (;;) { PTP::Net::Connection *client = serv.Accept(1); if (!client) continue; char buf[64]; int size = client->Read((BYTE*) buf, sizeof(buf)); if (size <= 0) { delete client; continue; } client->Unget((BYTE*) buf, size); if (STRNCMP_CONST(buf, "GET ") == 0) HandleGet(collect, keys, client); else if (STRNCMP_CONST(buf, "PUT " SFS_SEARCH_URL)== 0) HandleSearch(collect, keys,localIp, localPort, client); else if (STRNCMP_CONST(buf, "PUT " SFS_AUTH_URL) == 0) HandleAuth(store, &auth, keys, client); else if (STRNCMP_CONST(buf, "PUT " SFS_RESP_URL) == 0) HandleResp(store, &auth, keys, client); delete client; } return 0;}static intMatchOpt(char **args, const char *s2, int count){ char *s1 = *args; if (s1[0] != '-' || s1[1] != '-') return 0; s1 += 2; if (strcmp(s1, s2)) return 0; int cnt = 0; for (; args[cnt]; cnt++) ; return (cnt >= count);}static voidHandleOpts(PTP::Store *store, int argc, char **argv){ PTP::Net::Ip localIp = PTP::Net::Lookup("localhost"); PTP::Net::Port localPort = SFS_DEFAULT_PORT; PTP::Collection collect; PTP::List keys; PTP::List resps; int flags = 0; int i = 1; for (;;) { if (i >= argc) break; char **args = argv + i; i++; if (MatchOpt(args, "search", 3)) { PTP::Net::Connection *c = Connect(args[1]); Key *key = Auth(store, &keys, c, flags); if (!key) printf("%s: authorization failed.\n", prog); else if (Search(c, key, args[2], &resps)) { printf("%s: search of `%s' failed.\n", prog, args[1]); } else ShowResponses(&resps, 0); delete c; i += 2; } else if (MatchOpt(args, "get", 3)) { PTP::Net::Connection *c = Connect(args[1]); Key *key = Auth(store, &keys, c, flags); if (!key) printf("%s: authorization failed.\n", prog); else if (Get(c, key, args[1], args[2], NULL)) { printf("%s: get of `%s' failed.\n", prog, args[1]); } delete c; i++; } else if (MatchOpt(args, "share", 2)) { collect.Add(args[1], NULL); i++; } else if (MatchOpt(args, "port", 2)) { localPort = (PTP::Net::Port) strtoul(args[1], NULL, 10); i++; } else if (MatchOpt(args, "proxy", 2)) { PTP::Net::Port port; PTP::Net::Ip ip = PTP::Net::Lookup(args[1], &port, 80); if (!ip || !port) { printf("%s: invalid proxy `%s'.\n", prog, args[1]); } else PTP::Net::Connection::SetProxy(ip, port); i++; } else { printf("Usage: %s [OPTIONS]\n", prog); printf(" --search URL STRING\n"); printf(" --get URL PATH\n"); printf(" --share DIR\n"); printf(" --port PORT\n"); printf(" --proxy URL\n"); printf(" --help\n"); DestroyKeys(&keys); return; } } collect.Rescan(); if (collect.GetSize()) Share(store, &keys, localIp, localPort, &collect); DestroyKeys(&keys); DestroyResponses(&resps);}static intMatchCmd(char **args, const char *s2, int count){ const char *s1 = *args; for (; *s1 && *s1 == *s2; s1++, s2++) ; if (*s1) return 0; int cnt = 0; for (; args[cnt]; cnt++) ; return (cnt == (count + 1));}#ifdef PERF_TESTstatic unsigned longGetTime(){#ifdef WIN32 return GetTickCount();#else struct timeval tv; gettimeofday(&tv, NULL); return ((unsigned long) tv.tv_sec * 1000 + ((unsigned long) tv.tv_usec / 1000));#endif}#endif // PERF_TESTstatic voidHandleCmds(PTP::Store *store, FILE *in){ PTP::Net::Ip localIp = PTP::Net::Lookup("localhost"); PTP::Net::Port localPort = SFS_DEFAULT_PORT; PTP::Collection collect; PTP::List keys; PTP::List resps; int flags = 0; int quiet = 0;#ifdef PERF_TEST unsigned long mark = 0;#endif // PERF_TEST unsigned long total = 0; for (;;) { if (!quiet) { printf("(sfs) "); fflush(stdout); } char buffer[256]; *buffer = '\0'; if (!fgets(buffer, sizeof(buffer), in) || !*buffer) break; if (in != stdin && !quiet) printf("%s", buffer); int size = strlen(buffer); if (buffer[size - 1] == '\n') buffer[size - 1] = '\0'; char *args[4]; memset(args, 0, sizeof(args)); char *arg = buffer; for (int j = 0; j < 3; j++) { arg += strspn(arg, " \t"); args[j] = *arg ? arg:NULL; arg += strcspn(arg, " \t"); if (!isspace(*arg)) break; *arg++ = '\0'; } if (!args[0]) continue; if (MatchCmd(args, "search", 2)) { PTP::Net::Connection *c = Connect(args[1]); Key *key = Auth(store, &keys, c, flags); if (!key) printf("%s: authorization failed.\n", prog); else if (Search(c, key, args[2], &resps)) { printf("%s: search of `%s' failed.\n", prog, args[1]); } else ShowResponses(&resps, 1); delete c; } else if (MatchCmd(args, "get", 2)) { int id = (int) strtoul(args[1], NULL, 10); Response *resp = FindResponse(&resps, id); if (!resp) continue; PTP::Net::Connection *c = Connect(resp->url); Key *key = Auth(store, &keys, c, flags); if (!key) printf("%s: authorization failed.\n", prog); else { int size = 0; if (Get(c, key, resp->url, args[2], &size)) { printf("%s: get of `%s' " "failed.\n", prog, resp->url); } else total += (unsigned long) size; } delete c; } else if (MatchCmd(args, "share", 1)) { collect.Add(args[1], NULL); } else if (MatchCmd(args, "wait", 0)) { collect.Rescan(); if (collect.GetSize()) { Share(store, &keys, localIp, localPort, &collect); } } else if (MatchCmd(args, "port", 1)) { localPort = (PTP::Net::Port) strtoul(args[1], NULL, 10); } else if (MatchCmd(args, "proxy", 1)) { PTP::Net::Port port; PTP::Net::Ip ip = PTP::Net::Lookup(args[1], &port, 80); if (!ip || !port) { printf("%s: invalid proxy `%s'.\n", prog, args[1]); } else PTP::Net::Connection::SetProxy(ip, port); } else if (MatchCmd(args, "quit", 0)) { break; }#ifdef PERF_TEST else if (MatchCmd(args, "quiet", 1)) { quiet = (int) strtoul(args[1], NULL, 10); } else if (MatchCmd(args, "mark", 0)) { mark = GetTime(); total = 0; } else if (MatchCmd(args, "time", 0)) { unsigned long delta = GetTime() - mark; float mbps = ((float) total / (float) delta / (float) 1024.0 / (float) 1024.0 * (float) 1000.0); printf("%ld bytes received in %.02f secs" " (%.04f MB/s)\n", total, (float) delta / 1000.0, mbps); } else if (MatchCmd(args, "plain", 0)) { flags |= SFS_FLAGS_PLAINTEXT_XFER; }#endif // PERF_TEST else { printf("Commands:\n"); printf(" search URL STRING\n"); printf(" get ID PATH\n"); printf(" share [DIR]\n"); printf(" wait\n"); printf(" port PORT\n"); printf(" proxy URL\n"); printf(" quit\n");#ifdef PERF_TEST printf("\nPerformace testing:\n"); printf(" quiet 0|1\n"); printf(" mark\n"); printf(" time\n"); printf(" plain\n");#endif // PERF_TEST } } DestroyKeys(&keys); DestroyResponses(&resps);}intmain(int argc, char **argv){#ifdef WIN32 prog = strrchr(argv[0], '\\');#else prog = strrchr(argv[0], '/');#endif prog = prog ? (prog + 1):argv[0]; char *s = new char[23]; memset(s, 0x34, 23);#ifdef WIN32 PTP::Store store(HKEY_CURRENT_USER, "Software\\PTL\\Cert", NULL, NULL);#else char path[2048]; sprintf(path, "%s/.ptl/cert", getenv("HOME")); PTP::Store store(path, NULL, NULL);#endif if (store.Load() || !store.Find(NULL, 1)) { printf("%s: cannot load certificates.\n", prog); return 1; } if (argc <= 2) { FILE *in = (argc > 1) ? fopen(argv[1], "rb"):stdin; if (in) { HandleCmds(&store, in); if (in != stdin) fclose(in); } } else HandleOpts(&store, argc, argv); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -