/* * @(#)Client2.cpp * * This file is part of webCDwriter - Network CD Writing. * * Copyright (C) 2000-2003 Jörg P. M. Haeger * * webCDwriter is free software. See rcdrecord.cpp for details. */ #define _FILE_OFFSET_BITS 64 #include #include #include #include #include #include #include #include #include "Error.h" #include "Client2.h" typedef unsigned long long uint64; Client2::Client2() { force = 0; strcpy(prefix, ""); numOfBytes = numOfCannotRead = numOfDoesNotExist = numOfFiles = 0; } void Client2::handle(const char *format, ...) { va_list ap; va_start(ap, format); char str[1024]; vsprintf(str, format, ap); va_end(ap); if (force) printf("%s\n", str); else throw new Error(str); } void Client2::putFile(const char *path) { struct stat statBuf; if (stat(path, &statBuf) != 0) { if (errno == ENOENT) { handle("%s does not exist", path); numOfDoesNotExist++; return; } throw new Error("Cannot stat file \"%s\".", path); } char tmpName[8 * 1024]; sprintf(tmpName, "%s/%s", prefix, path); wchar_t name[8 * 1024]; if (mbstowcs(name, tmpName, 8 * 1024) == -1) { handle("Invalid character code in \"%s\".", tmpName); numOfCannotRead++; return; } if (S_ISDIR(statBuf.st_mode)) { DIR *dir = opendir(path); if (dir == NULL) { handle("Cannot open directory \"%s\".", path); numOfCannotRead++; return; } struct dirent *dirEntry; while ((dirEntry = readdir(dir)) != NULL) { if (strcmp(dirEntry->d_name, ".") == 0 || strcmp(dirEntry->d_name, "..") == 0) continue; char *tmpPathName = new char[strlen(path) + 1 + strlen(dirEntry->d_name) + 1]; sprintf(tmpPathName, "%s/%s", path, dirEntry->d_name); putFile(tmpPathName); delete[] tmpPathName; } closedir(dir); // make empty dir and/or set the modification time mkdir(name, statBuf.st_mode, statBuf.st_mtime); return; } else if (!S_ISREG(statBuf.st_mode)) { handle("%s is not a regular file", path); numOfCannotRead++; return; } FILE *inStream = fopen(path, "rb"); if (inStream == NULL) { handle("Cannot open file \"%s\".", path); numOfCannotRead++; return; } printf("%s %6.2f%%", path, 0.0); fflush(stdout); Client::putFile(name, statBuf.st_size, statBuf.st_mode, statBuf.st_mtime, inStream); fclose(inStream); printf("\n"); numOfFiles++; numOfBytes += statBuf.st_size; } void Client2::putTrack(const char *type, const char *path) { uint64 length = 0; FILE *inStream; if (path == NULL || strcmp(path, "-") == 0 || strcmp(path, "--stdin") == 0) { path = "stdin"; inStream = stdin; } else { struct stat statBuf; if (stat(path, &statBuf) != 0) { if (errno == ENOENT) { handle("%s does not exist", path); numOfDoesNotExist++; return; } throw new Error("Cannot stat file \"%s\".", path); } if (S_ISDIR(statBuf.st_mode)) throw new Error("%s is a directory", path); if (S_ISREG(statBuf.st_mode)) length = statBuf.st_size; inStream = fopen(path, "rb"); if (inStream == NULL) { handle("Cannot open track \"%s\".", path); numOfCannotRead++; return; } } printf("Track (%s) %s ", type, path); if (length > 0) printf("%9.2f%%", 0.0); else printf("%8d KB", 0); fflush(stdout); uint64 bytesTransmitted = 0; while (1) { static char buf[64 * 1024]; int n = fread(buf, 1, sizeof buf, inStream); if (n == 0) break; Client::putTrack(type, n, buf); bytesTransmitted += n; if (length > 0) { printf("\b\b\b\b\b\b\b\b\b\b%9.2f%%", 100.0 * bytesTransmitted / length); fflush(stdout); } else { printf("\b\b\b\b\b\b\b\b\b\b\b%8d KB", (int) (bytesTransmitted / 1024)); fflush(stdout); } type = "continue"; } printf("\n"); if (inStream != stdin) fclose(inStream); if (bytesTransmitted == 0) throw new Error("Track \"%s\" seems to be empty.", path); numOfFiles++; numOfBytes += bytesTransmitted; } void Client2::setForce() { force = 1; } void Client2::setPrefix(const char *path) { strcpy(prefix, path); }