/* * @(#) Config.cpp * * This file is part of webCDwriter - Network CD/DVD Writing. * * Copyright (C) 1999-2006 Jörg P. M. Haeger * * webCDwriter is free software. See CDWserver.cpp for details. * * Jörg Haeger, 25.05.1999 */ #include #include #include "Accounts.h" #include "Config.h" #include "FileInputStream.h" #include "PrintWriter.h" #include "String.h" #include "StringTokenizer.h" #include "Version.h" class DevicesParser { private: StringTokenizer tokenizer; private: String dev, raw; public: DevicesParser(String &devices) : tokenizer(devices.getBytes()) { } public: String *getCdrecordDevArg() { return new String(dev); } public: String *getRawDevice() { return new String(raw); } public: bool next() { try { dev = tokenizer.nextToken(" )(;"); if (dev.equals(",")) dev = tokenizer.nextToken(" (;"); raw = tokenizer.nextToken(" ;)"); } catch (NoSuchElementException *e) { delete e; return false; } return true; } }; Config::Config() { accountsFile = "/etc/CDWserver/accounts"; debugCache = ""; logLevelCache = 0; mimeTypes = ""; supportFormCache = false; } int Config::addDevice(String &dev, String &rawDevice) { if (numOfWriters == maxNumOfWriters) return -1; // create the device name prepareDevice(rawDevice); if (isMounted(rawDevice)) return -1; String model = cdrecordInq(dev.getBytes()); int stop = model.lastIndexOf(" "); if (stop <= 0) stop = model.length(); StringBuffer deviceBuf = "device."; for (int i = 0; i < stop; i++) { char ch = model.charAt(i); if (ch > 32 && ch != '=') deviceBuf.append(ch); } String device = new String(deviceBuf); log.put(5, S.e + "" + device + ""); // avoid duplicates by adding a number String deviceTmp = device; deviceTmp = deviceTmp + "-1"; int count = 1; for (int i = 0; i < numOfWriters; i++) if (writers[i].id.equals(deviceTmp)) { count++; deviceTmp = device; deviceTmp = deviceTmp + "-" + count; i = 0; } device = deviceTmp; String str = device; str = str + ".no"; if (search(str.getBytes()) < 0) { add(str.getBytes(), 99); String value = ""; value = value + ++lastDeviceNo; setConfig(str.getBytes(), value.getBytes()); int index = search(str.getBytes()); if (index >= 0) items[index]->activateConfig(); } str = device; str = str + ".CD"; if (search(str.getBytes()) < 0) add(str.getBytes(), 48); if (getActiveInt(str.getBytes()) > 0) hasReader = true; // CD/DVD writer autodetection Process prcap(getCdrecordPath()); prcap.addArg(S.e + "dev=" + dev); prcap.addArg("-prcap"); prcap.start(); while (true) { const char *lineStr = prcap.readLine(); if (lineStr == NULL) break; String line = lineStr; if (line.indexOf("Does write CD-R ") >= 0) setDefault(device, "CD-R", 8); if (line.indexOf("Does write CD-RW") >= 0) setDefault(device, "CD-RW", 4); if (getActiveBoolean(DVDSUPPORT)) { if (line.indexOf("Does read DVD") >= 0) setDefault(device, "DVD", 16); if (line.indexOf("Does write DVD-R ") >= 0) { setDefault(device, "DVD-R", 2); setDefault(device, "DVD-RW", 2); } if (model.indexOf("DVD+") >= 0) { setDefault(device, "DVD+R", 2); setDefault(device, "DVD+RW", 2); } if (line.indexOf("Does write DVD-RAM ") >= 0) setDefault(device, "DVD-RAM", 2); } } if (prcap.getResult() != 0) throw new Exception(S.e + "\"cdrecord dev=" + dev + " -prcap\" failed", S.e + "/config/error/cdrecord_prcap.html"); writers[numOfWriters].dev = dev; writers[numOfWriters].id = device; writers[numOfWriters].info = model; writers[numOfWriters].rawDevice = rawDevice; writers[numOfWriters].no = getMaxSpeed(numOfWriters, "no"); writers[numOfWriters].CD = getMaxSpeed(numOfWriters, "CD"); writers[numOfWriters].CDR = getMaxSpeed(numOfWriters, "CD-R"); writers[numOfWriters].CDRW = getMaxSpeed(numOfWriters, "CD-RW"); writers[numOfWriters].DVD = getMaxSpeed(numOfWriters, "DVD"); writers[numOfWriters].DVDMinusR = getMaxSpeed(numOfWriters, "DVD-R"); writers[numOfWriters].DVDMinusRW = getMaxSpeed(numOfWriters, "DVD-RW"); writers[numOfWriters].DVDPlusR = getMaxSpeed(numOfWriters, "DVD+R"); writers[numOfWriters].DVDPlusRW = getMaxSpeed(numOfWriters, "DVD+RW"); writers[numOfWriters].DVDRAM = getMaxSpeed(numOfWriters, "DVD-RAM"); writers[numOfWriters].DVDPlusR_DL = getMaxSpeed(numOfWriters, DVDPlusR_DL); String supports = ""; if (writers[numOfWriters].CDR > 0) supports = supports + "CD-R, "; if (writers[numOfWriters].CDRW > 0) supports = supports + "CD-RW, "; #ifdef PRO if (writers[numOfWriters].DVDMinusR > 0) supports = supports + "DVD-R, "; if (writers[numOfWriters].DVDMinusRW > 0) supports = supports + "DVD-RW, "; if (writers[numOfWriters].DVDPlusR > 0) supports = supports + "DVD+R, "; if (writers[numOfWriters].DVDPlusRW > 0) supports = supports + "DVD+RW, "; if (writers[numOfWriters].DVDRAM > 0) supports = supports + "DVD-RAM, "; if (writers[numOfWriters].DVDPlusR_DL > 0) supports = supports + "DVD+R DL, "; #endif if (writers[numOfWriters].no < 1 || supports.length() < 2) writers[numOfWriters].supports = "-"; else writers[numOfWriters].supports = supports.substring(0, supports.length() - 2); numOfWriters++; try { String str = device; str = str + ".CD-R"; int speed = getActiveInt(str.getBytes()); if (speed > maxSpeed) maxSpeed = speed; } catch (Exception *e) { delete e; } return 0; } String *Config::cdrecordInq(const char *dev) { Process p(getCdrecordPath()); char str[4 * 1024]; sprintf(str, "dev=%s", dev); p.addArg(str); p.addArg("-inq"); p.start(); String info = ""; int errorCode = 0; str[0] = 0; while (1) { const char *lineStr = p.readLine(); if (lineStr == NULL) break; String line = lineStr; if (line.startsWith("Vendor_info") || line.startsWith("Identifikation") || line.startsWith("Revision")) { int p = line.indexOf("'"); if (p >= 0 && p + 1 < line.length()) { line = line.substring(p + 1); p = line.indexOf("'"); while (p > 0 && line.charAt(p - 1) <= 32) p--; if (p > 0) { if (info.length() > 0) info = info + " "; info = info + line.substring(0, p); } } } } if (p.getResult() != 0) throw new Exception(S.e + "Error running cdrecord dev=" + dev + " -inq"); return new String(info); } int Config::cdrecordScanbus() { log.put(5, S.e + "Config::cdrecordScanbus()"); Process p(getCdrecordPath()); p.addArg("-scanbus"); p.start(); int numOfCDROMs = 0; while (true) { const char *lineStr = p.readLine(); if (lineStr == NULL) break; String line = lineStr; if (line.indexOf("devname: ") == 0 && line.indexOf("ATA") > 0) break; if (line.indexOf("CD-ROM") < 0 && line.indexOf("WORM") < 0) // skip non-CD device continue; log.put(5, S.e + "SCSI [" + line + "]"); int p0 = 0, len = line.length(); while (p0 < len && line.charAt(p0) <= 32) p0++; int p1 = p0 + 1, counter = 0; while (p1 < len) { char ch = line.charAt(p1); if (ch == ',') counter++; else if (ch < '0' || ch > '9') break; p1++; } if (counter != 2) continue; String dev = line.substring(p0, p1); String rawDevice = getRawDevice(dev, numOfCDROMs); log.put(3, S.e + "SCSI [" + dev + "] [" + rawDevice + "]"); addDevice(dev, rawDevice); numOfCDROMs++; } return p.getResult(); } void Config::cdrecordVersion() { Process p(getCdrecordPath()); p.addArg("-version"); p.start(); String name = "", version = ""; cdrecordInfo = ""; while (true) { const char *lineStr = p.readLine(); if (lineStr == NULL) break; String line = lineStr; if (line.indexOf("Copyright") > 0 && cdrecordInfo.length() == 0) { int p0 = line.indexOf(" "); if (p0 > 0) { name = line.substring(0, p0); int p1 = line.indexOf(" ", p0 + 1); if (p1 > 0) version = line.substring(p0 + 1, p1); } cdrecordInfo = cdrecordInfo + name + " " + version; log.put(3, S.e + "cdrecord: " + cdrecordInfo); } } if (cdrecordInfo.length() == 0) cdrecordInfo = "unknown cdrecord"; if (!getActiveBoolean(SIMULATION)) checkForResMgrPatch("cdrecord"); if (p.getResult() != 0) throw new Exception("Error running \"cdrecord -version\""); if (!config.getActiveBoolean("tryPatchedCdrecord")) { if (name.indexOf("DVD") >= 0 || name.indexOf("dvd") >= 0 || version.indexOf("dvd") >= 0) throw new Exception(S.e + "no original cdrecord", S.e + "/config/error/noOriginalCdrecord.html"); } } void Config::checkExecAsRoot(const char *execName) { struct stat statBuf; if (stat(execName, &statBuf) != 0) throw new Exception(S.e + "Cannot find " + execName); if (uid == 0) return; if (statBuf.st_uid != 0 || (statBuf.st_mode & S_ISUID) == 0 || (((statBuf.st_mode & S_IXGRP) == 0 || statBuf.st_gid != gid) && (statBuf.st_mode & S_IXOTH) == 0)) throw new Exception(S.e + "Cannot run " + execName + " as root", S.e + "Try\n"); } void Config::checkFile(const char *name, String &path) { if (uid == 0) return; if (File(path).isReadAndWritable(uid, gid) != 0) throw new Exception(S.e + "The user \"" + user + "\" cannot read and/or write the " + name + " \"" + path + "\"", S.e + "Try\n"); } String *Config::createCheckbox(Device &device, const char *medium) { String str = device.id; str = str + "." + medium; String checked = ""; try { if (getEditorBoolean(str)) checked = " checked=\"checked\""; } catch (Exception *e) { delete e; } String input = ""; input = input + "" + "\n"; return new String(input); } String *Config::createSpeedbox(Device &device, const char *medium) { String str = device.id; str = str + "." + medium; String checked = ""; int speed = 0; try { int index = indexOf(str.getBytes()); Object &object = items[index]->editor; if (!object.instanceof("Integer")) throw new Exception("Integer expected"); Integer *i = (Integer *)&object; speed = i->intValue(); } catch (Exception *e) { delete e; } String select = ""; select = select + "\n"; return new String(select); } void Config::evaluate( int lineNo, const char *str1, const char *str2) { String item = str1, value = str2; if (strcasecmp(str1, "maxSpeed") == 0 || strcasecmp(str1, "maxVerifySpeed") == 0) return; if (strcasecmp(str1, "maxOpenSessions") == 0 && strcasecmp(str2, "auto") == 0) str2 = "3"; int index = search(str1); if (index >= 0) { if (items[index]->lineInConfig >= 0) throw new Exception(S.e + str1 + " already set in line " + items[index]->lineInConfig); items[index]->setConfig(str2); items[index]->lineInConfig = lineNo; } else if (item.startsWith("device.")) { int defaultValue = 0; if (item.indexOf(".no") > 0) { defaultValue = 99; int no = Integer::getInt(value.getBytes()); if (no > lastDeviceNo) lastDeviceNo = no; } add(item.getBytes(), defaultValue); setConfig(item.getBytes(), value.getBytes()); int index = search(item.getBytes()); if (index >= 0) items[index]->activateConfig(); } else if (strcasecmp(str1, "cdrecordDevArg") == 0 || strcasecmp(str1, "CDwriter") == 0 || strcasecmp(str1, "CDwriters") == 0) // parseCDROMs(str2, writers, numOfWriters); // throw new Exception(S.e + "CDwriters"); log.put(2, "CDwriters line found -> ignored"); else if (strcasecmp(str1, "CDROM") == 0 || strcasecmp(str1, "CDROMs") == 0) // parseCDROMs(str2, CDROMs, numOfReaders); log.put(2, "CDROMs line found"); else if (strcasecmp(str1, "eMailOnError") == 0) eMailOnError = strDup(str2); else if (strcasecmp(str1, "group") == 0) { if (!userSave) { gid = toGid(str2); group = strDup(str2); log.put(2, S.e + "group = " + group + ", gid = " + gid); } } else if (strcasecmp(str1, "homeDir") == 0) setenv("HOME", str2, 1); else if (strcasecmp(str1, "imageFile") == 0) throw new Exception("now internal, remove line"); else if (strcasecmp(str1, "laser") == 0) laserOn = toBoolean(str2); else if (strcasecmp(str1, "logRequests") == 0) { if (toBoolean(str2) && getLogLevel() < 3) setConfig("logLevel", "3"); } else if (strcasecmp(str1, "logSubProcess") == 0) { if (toBoolean(str2) && getLogLevel() < 5) setConfig("logLevel", "5"); } else if (strcasecmp(str1, "logVerbose") == 0) { if (toBoolean(str2) && getLogLevel() < 4) setConfig("logLevel", "4"); } else if (strcasecmp(str1, "maxCopies") == 0) maxCopies = toInteger(str2); else if (strcasecmp(str1, "maxStoreMBs") == 0) throw new Exception( ": use maxMBytesInSpoolDir (see CDWserver/config.eg)"); else if (strcasecmp(str1, "organization") == 0) organization = strDup(str2); else if (strcasecmp(str1, "removeSessions") == 0) removeSessions = toBoolean(str2); else if (strcasecmp(str1, "setuid") == 0) setuid = toBoolean(str2); else if (strcasecmp(str1, "statusPortNo") == 0) statusPortNo = toInteger(str2); else if (strcasecmp(str1, "user") == 0) { if (!userSave) { uid = toUid(str2); user = strDup(str2); log.put(2, S.e + "user = " + user + ", uid = " + uid); } } else throw new Exception("unknown symbol"); } String *Config::getMimeType(File &file) { String key = file.getPath(); int p0 = key.lastIndexOf("."); if (p0 >= 0) key = key.substring(p0 + 1); p0 = 1; while (true) { int p = mimeTypes.indexOf(key.getBytes(), p0); if (p < p0) return new String("application/octet-stream"); char ch0 = mimeTypes.charAt(p - 1); char ch1 = ' '; if (p + key.length() < mimeTypes.length()) ch1 = mimeTypes.charAt(p + key.length()); p0 = p + 1; if (ch0 == ' ' || ch0 == '\t') if (ch1 == ' ' || ch1 == '\t' || ch1 == '\n' || ch1 == '\r') break; } while (p0 > 0 && mimeTypes.charAt(p0 - 1) != '\n') p0--; int p = p0; while (mimeTypes.charAt(p) != '\t' && mimeTypes.charAt(p) != ' ') p++; return mimeTypes.substring(p0, p); } String *Config::getRawDevice(String &dev, int no) { String path = ""; #ifdef FreeBSD path = path + "/dev/su" + dev.replace(',', '-'); File f = new File(path); if (!f.exists()) { String path2 = ""; path2 = path2 + "/dev/cd" + no; f = new File(path2); if (f.exists()) path = path2; } #else path = path + "/dev/scd" + no; File f = new File(path); if (!f.exists()) { String path2 = ""; path2 = path2 + "/dev/sr" + no; f = new File(path2); if (f.exists()) path = path2; } #endif return new String(path); } String *Config::getWritersForm() { String td = "colorTableCellBackground\">"; String TD = ""; String str = ""; for (int i = 0; i < getNumOfWriters(); i++) { str = str + "" + td + createSpeedbox(writers[i], "no") + TD // + td + "" + TD // + td + writers[i].rawDevice + TD + td + getWriterInfo(i) + TD + td + writers[i].dev + TD + td + createSpeedbox(writers[i], "CD") + TD + td + createSpeedbox(writers[i], "CD-R") + TD + td + createSpeedbox(writers[i], "CD-RW") + TD + td + createSpeedbox(writers[i], "DVD") + TD + td + createSpeedbox(writers[i], "DVD-R") + TD + td + createSpeedbox(writers[i], "DVD-RW") + TD + td + createSpeedbox(writers[i], "DVD+R") + TD + td + createSpeedbox(writers[i], DVDPlusR_DL) + TD + td + createSpeedbox(writers[i], "DVD+RW") + TD + td + createSpeedbox(writers[i], "DVD-RAM") + TD + ""; } return new String(str); } void Config::initDevices() { hasReader = false; numOfWriters = 0; for (int i = 0; i < maxNumOfWriters; i++) writers[i].rawDevice = ""; maxSpeed = 1; String devices = getActiveValue("devices"); bool autoDetect = devices.indexOf("auto") >= 0; // scan Linux IDE devices String kernelBoot = ""; for (char i = 'a'; i <= 'z'; i++) { String dev = "/dev/hd"; dev = dev + i; String file = "/proc/ide/hd"; file = file + i + "/media"; String media = readValue(file); if (media.length() == 0) continue; if (media.endsWith("\n")) media = media.substring(0, media.length() - 1); file = "/proc/ide/hd"; file = file + i + "/driver"; String driver = readValue(file); if (driver.length() == 0) continue; int p0 = driver.indexOf(" "); if (p0 > 0) driver = driver.substring(0, p0); log.put(5, S.e + "IDE: " + dev + " " + media + " " + driver); if (media.equals("cdrom") && driver.startsWith("ide-cd")) { File f = new File(dev); if (kernelBoot.length() > 0) kernelBoot = kernelBoot + " "; kernelBoot = kernelBoot + f.getName() + "=ide-scsi"; if (autoDetect) { String rawDevice = dev; addDevice(dev, rawDevice); } } } bool cdrecordError = false; if (autoDetect) cdrecordError = cdrecordScanbus() != 0; else { DevicesParser parser(devices); while (parser.next()) { String dev = parser.getCdrecordDevArg(); String rawDevice = parser.getRawDevice(); addDevice(dev, rawDevice); } } // sort the devices by their numbers for (int i = 0; i < numOfWriters - 1; i++) { for (int j = i + 1; j < numOfWriters; j++) { Device d1 = writers[i], d2 = writers[j]; String str = d1.id; str = str + ".no"; int no1 = getActiveInt(str.getBytes()); if (no1 == 0) no1 = 999; str = d2.id; str = str + ".no"; int no2 = getActiveInt(str.getBytes()); if (no2 == 0) no2 = 999; if (no1 > no2) { Device buf = writers[i]; writers[i] = writers[j]; writers[j] = buf; } } } log.put(2, S.e + "writers = " + numOfWriters); String file = "/proc/version"; String version = readValue(file); log.put(5, S.e + "/proc/version: " + version); if (numOfWriters == 0) { String str; if (kernelBoot.length() == 0 || version.indexOf(" 2.4.") < 0) str = str + "Install a CD- or DVD-writer or try the " + "" + "simulation mode!"; else str = str + "Add \"" + kernelBoot + "\" to your kernel boot parameters!"; if (cdrecordError) throw new Exception(S.e + "Error running \"cdrecord -scanbus\"", S.e + str); else throw new Exception(S.e + "Cannot autodetect a writer.", S.e + str); } for (int i = 0; i < numOfWriters; i++) { if (writers[i].rawDevice.length() == 0) throw new Exception(S.e + "Cannot find writer " + writers[i].dev); String name = "cdimage"; name = name + i + ".iso"; File f = new File(getSpoolDir(), name); writers[i].imageFile = f.getPath(); // writers[i].info = "unknown"; log.put(2, S.e + "writer = [" + writers[i].dev + "], writerRawDevice = [" + writers[i].rawDevice + "]"); } } bool Config::isMounted(const String &rawDevice) { try { String str = rawDevice; str = str + " "; File file = new File("/proc/mounts"); FileInputStream in = new FileInputStream(file); StringBuffer sb = new StringBuffer(file.getSize()); while (true) { char buf[4094]; int n = in.read(buf, 0, sizeof buf); if (n <= 0) break; sb.append(buf, 0, n); } if (sb.indexOf(str.getBytes()) >= 0) return true; } catch (Exception *e) { delete e; } return false; } void Config::load(String &aFileName) { try { load2(aFileName); } catch (Exception *e) { String msg = "Config::load(): "; msg = msg + e->toString(); printf("%s\n", msg.getBytes()); } } void Config::load2(String &aFileName) { cdrdaoInfo = ""; cdrecordInfo = "cdrecord"; growisofsInfo = ""; mkisofsInfo = "mkisofs"; mpg123Info = ""; ogg123Info = ""; soxInfo = ""; pthread_mutex_init(&mutex, NULL); const char *envStr = getenv("CONFIGDIR"); if (envStr == NULL) configDir = ::configDir; else configDir = envStr; File file = new File(configDir, "config"); fileName = file.getPath(); envStr = getenv("CDWserverConfig"); if (envStr != NULL) { file = new File(envStr); configDir = file.getParent(); fileName = file.getPath(); } if (aFileName.length() > 0) fileName = aFileName; firstError = ""; firstErrorHelp = ""; firstErrorPriority = 0; hasReader = false; lastDeviceNo = numOfWriters = 0; // values accounts = 1; file = new File(configDir, "accounts"); accountsFile = file.getPath(); debugCache = ""; eMailOnError = NULL; group = defaultGroup; file = new File(configDir, "greeting"); infoFile = file.getPath(); file = new File(configDir, "insertCD.html"); insertCD_MsgFile = file.getPath(); laserOn = 1; maxCopies = 10; maxSpeed = 8; mkisofsWithUTF8 = false; organization = "unknown"; removeSessions = 0; setuid = true; statusPortNo = 0; supportFormCache = true; user = defaultUser; userSave = true; numOfItems = 0; add("anonymousUse", true); add("askForProjectInfo", false); add("ATAPIRawDeviceSupport", runsOnLinux26()); add("audioCDSupport", true); add("binDir", path(BINDIR, binDir)); add("burnProof", false); add("cdrdao", false); add("cdrdaoArgs", "--on-the-fly" " --source-driver generic-mmc-raw --driver generic-mmc"); add("cdrdaoInternalPath", path(TOOLSDIR, toolsDir, "cdrdao")); add("cdrdaoPath", path(BINDIR, binDir, "cdrdao")); add("cdrdaoSimulationPath", path(BINDIR, binDir, "cdrdao-dummy")); add("cdrecordArgs", ""); add("cdrecordInternalPath", path(TOOLSDIR, toolsDir, "cdrecord")); add("cdrecordPath", path(BINDIR, binDir, "cdrecord")); add("cdrecordSimulationPath", path(BINDIR, binDir, "cdrecord-dummy")); add(CDRECORDWANTSTAO, false); add("copySupport", true); add("CSSFile", "/default.css"); add("debug", debugCache.getBytes()); file = new File(configDir, "default_files"); add("defaultFilesDir", file.getPath().getBytes()); add(DEFAULTSPEED, 8); add(DEFAULTSPEEDAUDIO, 4); add(DEFAULTSPEEDCDRW, 4); add("devices", "auto"); add("dvd+rw-formatPath", path(BINDIR, binDir, "dvd+rw-format")); add("dvd+rw-formatSimulationPath", path(BINDIR, binDir, "dvd+rw-format-dummy")); add("dvd+rw-mediainfoPath", path(BINDIR, binDir, "dvd+rw-mediainfo")); add(DVDSUPPORT, false); add("ejectOnDone", true); add("ejectOnReservation", true); add("exportArchive", true); add("exportDir", path("EXPORTDIR", exportDir)); add("exportOnly", false); add("feature.calculateMD5", 2); add("gracetime", 9); add("growisofsPath", path(BINDIR, binDir, "growisofs")); add("growisofsSimulationPath", path(BINDIR, binDir, "growisofs-dummy")); add("historyLength", 10); add("httpDir", path("HTTPDIR", httpDir)); add("imageOnTheFly", true); add(IMPORT_IMAGE_SUPPORT, false); add("logDir", path("LOGDIR", logDir)); add("logLevel", 1); logLevelCache = getActiveInt("logLevel"); add("logoURL", "http://@SERVER@:@PORT@/penguin.png"); add("managedAccounts", false); add("maxMBytesInSpoolDir", 4000); maxMBytesInSpoolDirCache = getActiveInt("maxMBytesInSpoolDir"); add("maxMBytesPerSession", 800); maxMBytesPerSessionCache = getActiveInt("maxMBytesPerSession"); add("maxOpenConnections", 10); add("maxOpenSessions", 3); add("mkisofsArgs", "-disable-deep-relocation -joliet-long"); add("mkisofsInternalPath", path(TOOLSDIR, toolsDir, "mkisofs")); add("mkisofsPath", path(BINDIR, binDir, "mkisofs")); add("MP3decoding", false); add("mpg123Args", "-q -r 44100 -s --stereo -"); add("mpg123Path", path(BINDIR, binDir, "mpg123")); add("ogg123Path", path(BINDIR, binDir, "ogg123")); add("oggDecoding", false); add("overburnSupport", false); add("overburnSupportArgs", "-dao -overburn"); add("PAM", false); add(PASSWORD, ""); add("portNo", defaultPort); add("projectsDir", path("PROJECTSDIR", projectsDir)); add("readcdInternalPath", path(TOOLSDIR, toolsDir, "readcd")); add("readcdPath", path(BINDIR, binDir, "readcd")); add("reservedMBytes", 100); reservedMBytesCache = getActiveInt("reservedMBytes"); add("rootGatePath", path(BINDIR, binDir, "CDWrootGate")); add("saveImageAs", true); add("showUsers", true); add(SIMULATION, false); // add("SMTPserver", "localhost"); add("soxPath", path(BINDIR, binDir, "sox")); add("spoolDir", path("SPOOLDIR", spoolDir)); add("SSL", true); add("supportForm", supportFormCache); add("transferLimitMB", 5000); add("tryPatchedCdrecord", false); add("useBurnFree", true); add("useUTF8", false); add("verify", 2); add("verifyPath", path(BINDIR, binDir, "CDWverify")); add("verifySimulationPath", path(BINDIR, binDir, "CDWverify-dummy")); add("waitForCD", 10); add("webCDcreatorDir", "webCDcreator"); add("writeProtection", true); try { gid = toGid(group); } catch (Exception *error) { gid = 0; String str = toGroup(gid); group = strDup(str.getBytes()); delete error; } try { uid = toUid(user); } catch (Exception *error) { uid = 0; String str = toUser(uid); user = strDup(str.getBytes()); delete error; } try { readConfigFile(); } catch (Exception *error) { if (firstErrorPriority < 100) { firstError = error->toString(); firstErrorPriority = 100; } delete error; } String password = readPassword(); if (password.equals("changeit")) { char passwd[8 + 2]; time_t t; time(&t); srandom(t); for (int i = 0; i < sizeof passwd - 2; i++) passwd[i] = '0' + random() % ('z' - '0' + 1); passwd[sizeof passwd - 2] = '\n'; passwd[sizeof passwd - 1] = 0; password = passwd; writePassword(password); } } void Config::parseLine( const char *lineStr, char *str1, char *str2) { str1[0] = str2[0] = 0; if (lineStr[0] == '#') return; int i = 0; while (lineStr[i] == '\t' || lineStr[i] == ' ') i++; int j = 0; for (; lineStr[i] != 0 && lineStr[i] != '\n' && lineStr[i] != '\t' && lineStr[i] != ' ' && lineStr[i] != '='; i++) str1[j++] = lineStr[i]; str1[j] = 0; while (lineStr[i] == '\t' || lineStr[i] == ' ' || lineStr[i] == '=') i++; j = 0; while (lineStr[i] != 0 && lineStr[i] != '\n') str2[j++] = lineStr[i++]; // truncate trailing whitespace while (j > 0 && (str2[j - 1] == '\t' || str2[j - 1] == ' ')) j--; str2[j] = 0; } String *Config::path(const char *env, const char *configure) { const char *dir = getenv(env); if (dir == NULL) dir = configure; return new String(dir); } String *Config::path( const char *env, const char *configure, String command) { String dir = path(env, configure); File f = new File(dir.getBytes(), command); if (env == BINDIR && !f.exists()) { File f2 = new File("/usr/bin", command); if (f2.exists()) f = f2; else { f2 = new File("/usr/local/bin", command); if (f2.exists()) f = f2; } } return new String(f.getPath()); } void Config::readConfigFile() { if (!File(fileName).exists() || File(fileName).getSize() == 0) writeConfigFile(); if (!File(infoFile).exists() || File(infoFile).getSize() == 0) writeInfoFile(); if (!File(insertCD_MsgFile).exists() || File(insertCD_MsgFile).getSize() == 0) writeInsertCD_MsgFile(); String name = fileName; log.put(2, S.e + "Reading config file " + name + "..."); userSave = true; readConfigFile(name); name = name + "-root"; log.put(2, S.e + "Reading root config file " + name + "..."); userSave = false; readConfigFile(name); activateConfig(); } void Config::readConfigFile(String &name) { FILE *inStream = fopen(name.getBytes(), "r"); if (inStream == NULL) if (userSave) throw new Exception(S.e + "Cannot open the config file " + name); else return; if (userSave) { resetItems(); lastDeviceNo = numOfWriters = 0; } try { readConfigFile(name, inStream); } catch (Exception *e) { fclose(inStream); throw e; } fclose(inStream); } void Config::readConfigFile(String &name, FILE *inStream) { int lineNo = 0; char lineStr[1024]; while (fgets(lineStr, sizeof lineStr, inStream) != NULL) { lineNo++; char str1[1024], str2[1024]; parseLine(lineStr, str1, str2); try { if (strlen(str1) == 0 && strlen(str2) == 0) continue; else evaluate(lineNo, str1, str2); } catch (Exception *error) { if (firstErrorPriority < 100) { firstError = firstError + "Error in " + name + ": line " + lineNo + ": \"" + str1 + "=" + str2 + "\": " + error->toString(); firstErrorPriority = 100; log.put(1, S.e + firstError); } delete error; } } } String *Config::readPassword() { File file = new File(getConfigDir(), PASSWORD); FILE *in = fopen(file.getPath().getBytes(), "r"); if (in == NULL) return new String("changeit"); StringBuffer sb = new StringBuffer(20); while (true) { int ch = fgetc(in); if (ch == EOF || ch < 32) break; sb.append((char)ch); } fclose(in); return new String(sb); } void Config::reload() { log.put(1, "Config::reload() started"); if (firstErrorPriority >= 100 || firstError.indexOf("pending") >= 0) { firstError = ""; firstErrorHelp = ""; firstErrorPriority = 0; } { Process p("/bin/uname"); p.setProtoFile(NULL); p.addArg("-a"); // p.show(); p.start(); while (1) { const char *lineStr = p.readLine(); if (lineStr == NULL) break; String line = lineStr; if (line.startsWith("1")) ; } } { Process p("/bin/rpm"); p.setProtoFile(NULL); p.addArg("-q"); p.addArg("webCDwriter"); p.run(); } { Process p(getActiveValue("cdrecordInternalPath")); p.setProtoFile(NULL); p.addArg("-version"); p.run(); } { Process p(getActiveValue("mkisofsInternalPath")); p.setProtoFile(NULL); p.addArg("-version"); p.run(); } try { File file = new File(getConfigDir(), "mime.types"); FileInputStream in = new FileInputStream(file); StringBuffer sb = new StringBuffer(file.getSize()); while (true) { char buf[4094]; int n = in.read(buf, 0, sizeof buf); if (n <= 0) break; sb.append(buf, 0, n); } mimeTypes = new String(sb); } catch (Exception *e) { delete e; } try { readConfigFile(); try { for (int i = 0; i < numOfItems; i++) log.put(5, S.e + "\"" + items[i]->key + "\" \"" + items[i]->active.toString() + "\""); } catch (Exception *e) { log.put(2, S.e + e->getMessage()); delete e; } if (uid != geteuid() || gid != getegid()) throw new Exception(S.e + "Cannot set user \"" + user + "\" and group \"" + group + "\"", S.e + "Restart " + product + " as root by" + " [" + initDir + "/CDWserver restart]"); log.put(5, S.e + "Config::reload(): geteuid() = " + (int) geteuid()); String logDir = getActiveValue("logDir"); if (!File(logDir).exists()) throw new Exception(S.e + "logDir " + logDir + " does not exist", S.e + "/config/directories.html#logDir"); log.put(5, S.e + "Config::reload(): logDir = " + logDir); String projectsDir = getActiveValue("projectsDir"); if (accounts && !File(projectsDir).exists()) throw new Exception(S.e + "projectsDir " + projectsDir + " does not exist", S.e + "/config/directories.html#projectsDir"); log.put(5, S.e + "Config::reload(): projectsDir = " + projectsDir); String spoolDir = getActiveValue("spoolDir"); if (!File(spoolDir).exists()) throw new Exception(S.e + "spoolDir " + spoolDir + " does not exist", S.e + "/config/directories.html#store"); log.put(5, S.e + "Config::reload(): spoolDir = " + spoolDir); if (getActiveBoolean("cdrdao")) preparePath("cdrdao", PATH_COPY | PATH_DUMMY); preparePath("cdrecord", PATH_COPY | PATH_DUMMY); if (config.getActiveBoolean(DVDSUPPORT)) { preparePath("dvd+rw-format", PATH_DUMMY); preparePath("dvd+rw-mediainfo"); preparePath("growisofs", PATH_DUMMY); testGrowisofs(); } preparePath("mkisofs", PATH_COPY); if (getActiveBoolean(SIMULATION)) checkCopy("mkisofs"); if (getActiveBoolean("audioCDSupport")) { if (getActiveBoolean("MP3decoding")) preparePath("mpg123"); if (getActiveBoolean("oggDecoding")) preparePath("ogg123"); preparePath("sox"); } preparePath("rootGate", PATH_ROOT); if (getActiveInt("verify") > 0) preparePath("verify", PATH_DUMMY | PATH_ROOT); activateConfig(); checkFile("accounts", accountsFile); checkFile("config", fileName); File file = new File(getConfigDir(), PASSWORD); checkFile(PASSWORD, file.getPath()); if (uid != 0 && File(logDir).isReadAndWritable(uid, gid) != 0) throw new Exception(S.e + "logDir " + logDir + " or a file below it" + " is not read and/or writable by the user \"" + user + "\"", S.e + "Try one of\n"); if (uid != 0 && File(projectsDir).isReadAndWritable(uid, gid) != 0) throw new Exception(S.e + "projectsDir " + projectsDir + " or a file below it" + " is not read and/or writable by the user \"" + user + "\"", S.e + "Try one of\n"); if (uid != 0 && File(spoolDir).checkOwner(uid) != 0) throw new Exception(S.e + "spoolDir " + spoolDir + " or a file below it" + " is not owned by the user \"" + user + "\"", S.e + "Try one of\n"); testMkisofs(); cdrecordVersion(); cdrecordHelp(); initDevices(); checkRawDevices(); if (getActiveBoolean("audioCDSupport")) { if (getActiveBoolean("MP3decoding")) testMpg123(); if (getActiveBoolean("oggDecoding")) { testOgg123(); if (ogg123Info.indexOf("1.0rc") >= 0) throw new Exception(S.e + "ogg123 " + ogg123Info + " does not work with webCDwriter. Get 1.0!", S.e + "/config/error/ogg123.html"); } testSox(); } activateConfig(); resetEditor(); } catch (Exception *error) { log.put(1, S.e + "reload(): " + error->toString()); if (firstErrorPriority < 100) { firstError = error->toString(); firstErrorHelp = error->getHelp(); firstErrorPriority = 100; } delete error; } } void Config::setPermissions() { char fileName[4*1024]; sprintf(fileName, "%s/connects", config.getLogDir()); chown(fileName, uid, gid); sprintf(fileName, "%s/log", config.getLogDir(), version); chown(fileName, uid, gid); // chown(imageFile, uid, gid); } void Config::testGrowisofs() { String helpURL = "/config/error/dvd+rw-tools.html"; Process growisofs(getActiveBinPath("growisofs")); growisofs.addArg("-version"); growisofs.start(); const char *lineStr = growisofs.readLine(); if (lineStr == NULL) throw new Exception(S.e + "Cannot run growisofs (" + getActiveValue("growisofsPath") + ")", S.e + helpURL); String line = lineStr; int a = 0, b = -1; if (line.startsWith("growisofs ")) growisofsInfo = line.substring(10); else if (line.indexOf("growisofs by") >= 0) { int p = line.indexOf("version "); if (p >= 0) growisofsInfo = line.substring(p + 8); } sscanf(growisofsInfo.getBytes(), "%d.%d", &a, &b); if (b < 0) throw new Exception(S.e + "Unexpected output of \"growisofs -version\"", S.e + helpURL); if (a < 5 || (a == 5 && b < 10)) throw new Exception(S.e + "growisofs " + a + "." + b + " is too old", S.e + helpURL); int comma = growisofsInfo.indexOf(","); if (comma > 0) growisofsInfo = growisofsInfo.substring(0, comma); } void Config::testMkisofs() { Process p(getMkisofsPath()); p.addArg("-version"); p.start(); String line = ""; while (true) { const char *str = p.readLine(); if (str == NULL) break; line = str; if (line.indexOf(".mkisofsrc") < 0) break; } if (line.length() == 0) throw new Exception("Cannot run mkisofs"); if (p.getResult() != 0) throw new Exception("Error running mkisofs -version"); log.put(3, S.e + "Config::testMkisofs(): " + line); String command = "", version = ""; StringTokenizer tokenizer(line.getBytes(), " \t"); try { command = tokenizer.nextToken(); version = tokenizer.nextToken(); } catch (NoSuchElementException *e) { delete e; throw new Exception("Cannot get the version of mkisofs"); } mkisofsWithUTF8 = version.indexOf("UTF-8") >= 0; mkisofsInfo = ""; mkisofsInfo = mkisofsInfo + command + " " + version; } void Config::testMpg123() { Process mpg123(config.getActiveValue("mpg123Path")); mpg123.addArg("--longhelp"); mpg123.start(); const char *lineStr = mpg123.readLine(); if (lineStr == NULL) throw new Exception(S.e + "Cannot run mpg123 (" + config.getActiveValue("mpg123Path") + ")", S.e + "/config/error/mpg123.html"); do { char str[strlen(lineStr) + 1]; if (sscanf(lineStr, "Version %s", str) == 1) mpg123Info = str; lineStr = mpg123.readLine(); } while (lineStr != NULL); } void Config::testOgg123() { Process ogg123(getActiveValue("ogg123Path")); ogg123.addArg("--version"); ogg123.start(); const char *lineStr = ogg123.readLine(); if (lineStr == NULL) throw new Exception(S.e + "Cannot run ogg123 (" + getActiveValue("ogg123Path") + ")", S.e + "/config/error/ogg123.html"); do { char str1[strlen(lineStr) + 1], str2[strlen(lineStr) + 1]; if (sscanf(lineStr, "%s %[^:]", str1, str2) == 2) ogg123Info = str2; lineStr = ogg123.readLine(); } while (lineStr != NULL); } void Config::testSox() { Process sox(getActiveValue("soxPath")); sox.addArg("-h"); sox.start(); const char *lineStr = sox.readLine(); if (lineStr == NULL) throw new Exception(S.e + "Cannot run sox (" + getActiveValue("soxPath") + ")", S.e + "/config/error/sox.html"); do { char str1[strlen(lineStr) + 1], str2[strlen(lineStr) + 1]; if (sscanf(lineStr, "%[^:]: Version %s", str1, str2) == 2) soxInfo = str2; lineStr = sox.readLine(); } while (lineStr != NULL); } String *getTabItem(const char *file, String &key, int inCol, int getCol) { FILE *in = fopen(file, "r"); if (in == NULL) return new String(); String value = ""; while (true) { char line[1024]; if (fgets(line, sizeof line, in) == NULL) break; String str = line; int p0 = 0; for (int i = 0; i < inCol && p0 < str.length(); p0++) if (str.charAt(p0) == ':') i++; int p1 = p0 + 1; for (; p1 < str.length(); p1++) if (str.charAt(p1) == ':') break; String item = str.substring(p0, p1); if (!item.equals(key)) continue; p0 = 0; for (int i = 0; i < getCol && p0 < str.length(); p0++) if (str.charAt(p0) == ':') i++; p1 = p0 + 1; for (; p1 < str.length(); p1++) if (str.charAt(p1) == ':') break; value = str.substring(p0, p1); // printf("<%s><%s>\n", item.getBytes(), value.getBytes()); break; } fclose(in); return new String(value); } int Config::toGid(const char *groupName) { String name = groupName; String id = getTabItem("/etc/group", name, 0, 2); if (id.length() == 0) throw new Exception(S.e + "Unknown group: " + name); return Integer::getInt(id.getBytes()); } String *Config::toGroup(int gid) { String id = String::valueOf(gid); String name = getTabItem("/etc/group", id, 2, 0); if (name.length() == 0) return new String(id); else return new String(name); } String &Config::toHTML() { text = ""; HTML = 1; text = text + "\n" + "Configuration of CDWserver" + "\n\n" + "

# Configuration of CDWserver

\n\n"; write(); text = text + "\n" + "\n"; return text; } const char *Config::toString(boolean b) { if (b) return "on"; else return "off"; } int Config::toUid(const char *userName) { String name = userName; String id = getTabItem("/etc/passwd", name, 0, 2); if (id.length() == 0) throw new Exception(S.e + "Unknown user: " + name); return Integer::getInt(id.getBytes()); } String *Config::toUser(int uid) { String id = String::valueOf(uid); String name = getTabItem("/etc/passwd", id, 2, 0); if (name.length() == 0) return new String(id); else return new String(name); } void Config::updateConfigFile() { FILE *in = fopen(fileName.getBytes(), "r"); if (in == NULL) throw new Exception(S.e + "Cannot open " + fileName); StringBuffer sb = new StringBuffer(10000); while (true) { int ch = fgetc(in); if (ch == EOF) break; sb.append((char)ch); } fclose(in); if (sb.length() > 0 && sb.charAt(sb.length() - 1) != '\n') sb.append('\n'); for (int i = 0; i < numOfItems; i++) { if (items[i]->key.equals(CDRECORDWANTSTAO) || items[i]->key.equals("gracetime") || items[i]->key.equals(PASSWORD)) continue; int done = false; for (int p0 = 0; ; p0++) { String key = items[i]->key; key = key + "="; p0 = sb.indexOf(key.getBytes(), p0); if (p0 < 0) break; if (p0 > 0 && sb.charAt(p0 - 1) != '\n') continue; int p1 = sb.indexOf("\n", p0); if (p1 < 0) p1 = sb.length(); sb.delete_(p0, p1); String str = createConfigLine(i); if (str.startsWith("device.")) { if (sb.length() > p0 && sb.charAt(p0) == '\n') sb.delete_(p0, p0 + 1); if (!items[i]->isDefault()) { str = str + "\n"; sb.append(str.getBytes()); } } else sb.insert(p0, str.getBytes()); done = true; break; } if (done || items[i]->isDefault()) continue; String key = "#"; key = key + items[i]->key; for (int p0 = 0; ; p0++) { p0 = sb.indexOf(key.getBytes(), p0); if (p0 < 0) break; if (p0 > 0 && sb.charAt(p0 - 1) != '\n') continue; int p1 = sb.indexOf("\n", p0); if (p1 < 0) p1 = sb.length(); sb.delete_(p0, p1); String str = createConfigLine(i); sb.insert(p0, str.getBytes()); done = true; break; } if (done) continue; String str = createConfigLine(i); str = str + "\n"; sb.append(str.getBytes()); } FILE *out = fopen(fileName.getBytes(), "w"); if (out == NULL) throw new Exception(S.e + "Cannot write " + fileName); String str = new String(sb); fwrite(str.getBytes(), 1, str.length(), out); fclose(out); } void Config::updateEditor(String &str) { log.debug("POST", S.e + str); int configChanges = 0; bool newPasswordMode = false; String newPassword1 = "", newPassword2 = ""; int i = 0; while (true) { while (i < str.length() && (str.charAt(i) == '\n' || str.charAt(i) == ' ')) i++; if (i == str.length()) break; int p0 = i; while (i < str.length() && str.charAt(i) != '\n' && str.charAt(i) != ' ' && str.charAt(i) != '=') i++; if (i == p0) continue; String key = str.substring(p0, i); while (i < str.length() && str.charAt(i) == ' ') i++; if (i == str.length() || str.charAt(i) != '=') continue; i++; p0 = i; while (i < str.length() && str.charAt(i) != '\n') i++; String value = str.substring(p0, i); if (key.equals("newPassword")) { newPasswordMode = true; newPassword1 = value; continue; } if (key.equals("newPassword2")) { newPasswordMode = true; newPassword2 = value; continue; } int index = search(key.getBytes()); if (index < 0) continue; items[index]->setEditor(value); configChanges++; } String passwdKey = PASSWORD; String password = getEditorValue(passwdKey); log.debug(PASSWORD, S.e + "input = <" + password + ">"); String password0 = readPassword(); log.debug(PASSWORD, S.e + "file = <" + password0 + ">"); if (!password.equals(password0)) { setError(PASSWORD, "Invalid password"); throw new Exception(S.e + "Invalid password"); } if (newPasswordMode) if (newPassword1.equals(newPassword2)) { writePassword(newPassword1); setEditor(PASSWORD, newPassword1); } else { setError(PASSWORD, "Do not match"); throw new Exception(S.e + "Do not match"); } updateConfig(); if (configChanges > 2) updateConfigFile(); setWarning(95, S.e + "Reload config pending", "Close all connections to CDWserver!"); } void Config::write() { write("# 1. Features"); // write("accounts", toString(accounts)); write("audioCDSupport", toString(getActiveBoolean("audioCDSupport"))); write("cdrdao", toString(getActiveBoolean("cdrdao"))); write("copySupport", toString(getActiveBoolean("copySupport"))); write("imageOnTheFly", toString(getImageOnTheFly())); write("laser", toString(laserOn)); write("MP3decoding", toString(getActiveBoolean("MP3decoding"))); write(SIMULATION, toString(getActiveBoolean(SIMULATION))); write("useUTF8", toString(getMkisofsWithUTF8())); write("verify", getVerify()); write("# 2. Server"); if (!HTML) { write("group", group); write("user", user); } write("portNo", getActiveInt("portNo")); write("statusPortNo", statusPortNo); write("maxOpenConnections", getMaxOpenConnections()); write("# 3. Directories"); write("exportDir", getActiveValue("exportDir").getBytes()); write("logDir", getLogDir()); write("projectsDir", getProjectsDir()); write("spoolDir", getSpoolDir()); write("# 4. Cache"); write("maxMBytesInSpoolDir", getMaxMBytesInSpoolDir()); write("maxMBytesPerSession", getMaxMBytesPerSession()); write("maxOpenSessions", getMaxOpenSessions()); write("reservedMBytes", getReservedMBytes()); write("# 5. CD-ROM(s) and CD-writer(s)"); write(DEFAULTSPEED, getDefaultSpeed()); write("maxSpeed", maxSpeed); write("useBurnFree", toString(getBurnFree())); write("# 6. Programs"); write("cdrdaoPath", getCdrdaoPath()); write("cdrecordPath", getCdrecordPath()); if (config.getActiveBoolean(DVDSUPPORT)) { write("dvd+rw-formatPath", getActiveBinPath("dvd+rw-format")); write("dvd+rw-mediainfoPath", getActiveBinPath("dvd+rw-mediainfo")); write("growisofsPath", getActiveBinPath("growisofs")); } write("mkisofsPath", getMkisofsPath()); write("mpg123Path", getActiveValue("mpg123Path").getBytes()); write("ogg123Path", getActiveValue("ogg123Path").getBytes()); write("readcdPath", getReadcdPath()); write("soxPath", getActiveValue("soxPath").getBytes()); write("# 7. Options"); write("anonymousUse", toString(getAnonymousUse())); write("cdrecordArgs", getCdrecordArgs()); write("debug", getActiveValue("debug").getBytes()); write("defaultFilesDir", getDefaultFilesDir()); write("ejectOnDone", toString(getEjectOnDone())); write("ejectOnReservation", toString(getEjectOnReservation())); if (eMailOnError == NULL) write("#eMailOnError", "unknown@unknown.org"); else write("eMailOnError", eMailOnError); write("logLevel", getLogLevel()); write("logoURL", getLogoURL().getBytes()); write("maxCopies", maxCopies); write("mkisofsArgs", getMkisofsArgs()); write("organization", organization); write("removeSessions", toString(removeSessions)); write("showUsers", toString(getShowUsers())); write("waitForCD", getWaitForCD()); } void Config::write(const char *str) { if (HTML) text = text + "

" + str + "

\n"; else text = text + "\n" + str + "\n\n"; } void Config::write(const char *str1, const char *str2) { if (HTML) text = text + str1 + " = " + str2 + "
\n"; else text = text + str1 + "=" + str2 + "\n"; } void Config::write(const char *str, int number) { if (HTML) text = text + str + " = " + number + "
\n"; else text = text + str + "=" + number + "\n"; } void Config::writeConfigFile() { int out = open(fileName.getBytes(), O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (out < 0) throw new Exception(S.e + "Cannot create configFile " + fileName); PrintWriter writer = new PrintWriter(out); text = ""; HTML = 0; text = text + "# Configuration of CDWserver\n" + "# See config.html for details\n\n"; write(); writer.write(text); writer.flush(); close(out); chown(fileName.getBytes(), uid, gid); } void Config::writeInfoFile() { FILE *out = fopen(infoFile.getBytes(), "w"); if (out == NULL) throw new Exception(S.e + "Cannot create " + infoFile); fprintf(out, "Welcome to CDWserver.\n"); fprintf(out, "\n"); fprintf(out, "This is the contents of %s.\n", infoFile.getBytes()); fclose(out); } void Config::writeInsertCD_MsgFile() { FILE *out = fopen(insertCD_MsgFile.getBytes(), "w"); if (out == NULL) throw new Exception(S.e + "Cannot create " + insertCD_MsgFile); fprintf(out, "The CD-writer No. @NO@ (@NAME@) " "was reserved for @MINUTES@ minutes.\n"); fprintf(out, "Please insert a CD-R(W) " "and wait until it is ejected!\n"); fprintf(out, "\n"); fprintf(out, "To change this default message edit the file\n" " %s\n" "on the server.\n", insertCD_MsgFile.getBytes()); fclose(out); } void Config::writePassword(String &password) { File file = new File(getConfigDir(), PASSWORD); int out = creat(file.getPath().getBytes(), S_IRUSR | S_IWUSR); int res; if (out < 0) res = -1; else { res = ::write(out, password.getBytes(), password.length()); close(out); chown(file.getPath().getBytes(), uid, gid); } if (res < 0) throw new Exception(S.e + "Cannot write password to " + file.getPath()); }