/* * @(#)Accounts.cpp * * This file is part of webCDwriter - Network CD/DVD Writing. * * Copyright (C) 2001-2006 Jörg P. M. Haeger * * webCDwriter is free software. See CDWserver.cpp for details. * * Jörg Haeger, 25.04.2001 */ #include #include #include "Accounts.h" #include "Config.h" #include "Exception.h" #include "StringBuffer.h" Accounts::Accounts() { pthread_mutex_init(&mutex, NULL); } Accounts::~Accounts() { } void Accounts::add(const char *ID, const char *passwd, const char *eMail) { char ID2[strlen(ID) + 1]; strcpy(ID2, ID); replaceColons(ID2); char passwd2[strlen(passwd) + 1]; strcpy(passwd2, passwd); replaceColons(passwd2); char eMail2[strlen(eMail) + 1]; strcpy(eMail2, eMail); replaceColons(eMail2); try { pthread_mutex_lock(&mutex); char passwd3[1024], eMail3[sizeof passwd3]; getByID(ID2, passwd3, eMail3, sizeof passwd3); if (passwd3[0] != 0) throw new Exception("ID already in use."); FILE *out = fopen(config.getAccountsFile(), "a"); if (out == NULL) throw new Exception("Cannot write to the accounts file."); fprintf(out, "%s:%s:%s\n", ID2, passwd2, eMail2); fclose(out); pthread_mutex_unlock(&mutex); } catch (Exception *exception) { pthread_mutex_unlock(&mutex); throw exception; } } void Accounts::changePassword(const char *ID, const char *newPasswd) { char ID2[strlen(ID) + 1]; strcpy(ID2, ID); replaceColons(ID2); char passwd2[strlen(newPasswd) + 1]; strcpy(passwd2, newPasswd); replaceColons(passwd2); try { pthread_mutex_lock(&mutex); char oldPasswd[1024], eMail[sizeof oldPasswd]; getByID(ID, oldPasswd, eMail, sizeof oldPasswd); char newItem[strlen(ID2) + 1 + strlen(passwd2) + 1 + strlen(eMail) + 1]; sprintf(newItem, "%s:%s:%s\n", ID2, passwd2, eMail); replace(ID, newItem); pthread_mutex_unlock(&mutex); } catch (Exception *exception) { pthread_mutex_unlock(&mutex); throw exception; } } void Accounts::check(const char *ID, const char *passwd) { char ID2[strlen(ID) + 1]; strcpy(ID2, ID); replaceColons(ID2); char passwd2[strlen(passwd) + 1]; strcpy(passwd2, passwd); replaceColons(passwd2); try { pthread_mutex_lock(&mutex); char passwd3[1024], eMail3[sizeof passwd3]; getByID(ID2, passwd3, eMail3, sizeof passwd3); if (passwd3[0] == 0) throw new Exception("Unknown user."); if (strcmp(passwd2, passwd3) != 0) throw new Exception("Invalid password."); pthread_mutex_unlock(&mutex); } catch (Exception *exception) { pthread_mutex_unlock(&mutex); throw exception; } } void Accounts::getByID(const char *ID, char *passwd, char *eMail, int size) { if (size < 20) throw new Exception("Accounts::getByID: size = %d.", size); FILE *in = fopen(config.getAccountsFile(), "r"); if (in == NULL) throw new Exception("Cannot open %s.", config.getAccountsFile()); char lineStr[1024], ID2[sizeof lineStr], passwd2[sizeof lineStr], eMail2[sizeof lineStr]; ID2[0] = passwd2[0] = eMail2[0] = 0; passwd[0] = eMail[0] = 0; while (fgets(lineStr, sizeof lineStr, in) != NULL) { if (sscanf(lineStr, "%[^:]:%[^:]:%[^:\n]", ID2, passwd2, eMail2) < 2) continue; if (strcmp(ID2, ID) == 0) break; } fclose(in); if (strcmp(ID2, ID) != 0) return; strncpy(passwd, passwd2, size); passwd[size - 1] = 0; strncpy(eMail, eMail2, size); eMail[size - 1] = 0; } void Accounts::remove(const char *ID) { try { pthread_mutex_lock(&mutex); replace(ID, ""); pthread_mutex_unlock(&mutex); } catch (Exception *exception) { pthread_mutex_unlock(&mutex); throw exception; } } void Accounts::replace(const char *ID, const char *newItem) { char ID2[strlen(ID) + 1]; strcpy(ID2, ID); replaceColons(ID2); String key = ID2; key = key + ":"; FILE *in = fopen(config.getAccountsFile(), "r"); if (in == NULL) throw new Exception(S.e + "Cannot open " + config.getAccountsFile()); StringBuffer sb = new StringBuffer(10000); while (true) { int ch = fgetc(in); if (ch == EOF) break; sb.append((char)ch); } fclose(in); 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() - 1; sb.delete_(p0, p1 + 1); sb.insert(p0, newItem); } FILE *out = fopen(config.getAccountsFile(), "w"); if (out == NULL) throw new Exception(S.e + "Cannot write " + config.getAccountsFile()); String str = new String(sb); fwrite(str.getBytes(), 1, str.length(), out); fclose(out); } char *Accounts::replaceColons(char *str) { char *ptr = str; while (*ptr != 0) { if (*ptr == ':') *ptr = '_'; ptr++; } return str; } Accounts *accounts;