# HG changeset patch # User John "Elwin" Edwards # Date 1342656005 25200 # Node ID c08717cb779393376a7841b9d0fd126f88324b49 # Parent d7d7cdcba3b49fdc0f9c80283356f7d36078c946 sqlickrypt: add getmail and setmail commands. Add the ability to retrieve and alter users' e-mail addresses, and clean up some of the code too. diff -r d7d7cdcba3b4 -r c08717cb7793 sqlickrypt.c --- a/sqlickrypt.c Mon Jul 16 14:52:04 2012 -0700 +++ b/sqlickrypt.c Wed Jul 18 17:00:05 2012 -0700 @@ -9,6 +9,39 @@ #define DATABASE "/dgldir/dgamelaunch.db" #define IBUFSIZE 200 +/* General idea for return status: + * 0: success + * 1: password check failed + * 2: username not found + * 3: database error + * 4: invalid input + */ + +/* Opens the database and, less obviously, initializes a statement. */ +int opendb(sqlite3 **dbp, sqlite3_stmt **stmtp, char *query) { + int status; + status = sqlite3_open(DATABASE, dbp); + if (status) { + sqlite3_close(*dbp); + exit(3); + } + sqlite3_prepare_v2(*dbp, query, -1, stmtp, NULL); + if (*stmtp == NULL) { + sqlite3_close(*dbp); + exit(3); + } + return 0; +} + +void cleanup(sqlite3 *db, sqlite3_stmt *stmt, int status) { + if (stmt) + sqlite3_finalize(stmt); + sqlite3_close(db); + if (status) + exit(status); + return; +} + int check(char *uname, char *pw) { char *pwhash, *comphash; char *query = "SELECT password FROM dglusers WHERE username=?;"; @@ -16,22 +49,10 @@ sqlite3 *db; sqlite3_stmt *qstmt; - status = sqlite3_open(DATABASE, &db); - if (status) { - sqlite3_close(db); - return 3; - } - sqlite3_prepare_v2(db, query, -1, &qstmt, NULL); - if (qstmt == NULL) { - sqlite3_close(db); - return 3; - } + opendb(&db, &qstmt, query); status = sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT); - if (status) { - sqlite3_finalize(qstmt); - sqlite3_close(db); - return 3; - } + if (status) + cleanup(db, qstmt, 3); status = sqlite3_step(qstmt); if (status != SQLITE_ROW) { sqlite3_finalize(qstmt); @@ -41,9 +62,7 @@ return 3; } pwhash = strdup((char *) sqlite3_column_text(qstmt, 0)); - /* Clean up */ - sqlite3_finalize(qstmt); - sqlite3_close(db); + cleanup(db, qstmt, 0); /* Check the password */ comphash = crypt(pw, pwhash); @@ -62,22 +81,11 @@ sqlite3 *db; sqlite3_stmt *qstmt; - status = sqlite3_open(DATABASE, &db); - if (status) { - sqlite3_close(db); - return 3; - } + opendb(&db, &qstmt, checkquery); /* Check for existing account in the same transaction with creating it. */ status = sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL); - if (status) { - sqlite3_close(db); - return 3; - } - sqlite3_prepare_v2(db, checkquery, -1, &qstmt, NULL); - if (qstmt == NULL) { - sqlite3_close(db); - return 3; - } + if (status) + cleanup(db, qstmt, 3); sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT); status = sqlite3_step(qstmt); if (status != SQLITE_DONE) { @@ -90,51 +98,98 @@ /* The username doesn't exist yet, so create a new account. */ sqlite3_finalize(qstmt); sqlite3_prepare_v2(db, addquery, -1, &qstmt, NULL); - if (qstmt == NULL) { - sqlite3_close(db); - return 3; - } + if (qstmt == NULL) + cleanup(db, NULL, 3); sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT); sqlite3_bind_text(qstmt, 2, strdup(crypt(pw, pw)), -1, free); sqlite3_bind_text(qstmt, 3, email, -1, SQLITE_TRANSIENT); status = sqlite3_step(qstmt); - if (status != SQLITE_DONE) { - sqlite3_finalize(qstmt); - sqlite3_close(db); - return 3; - } + if (status != SQLITE_DONE) + cleanup(db, qstmt, 3); status = sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL); - sqlite3_finalize(qstmt); - sqlite3_close(db); + cleanup(db, qstmt, 0); return status; } +int getmail(char *uname) { + char *mailquery = "SELECT email FROM dglusers WHERE username = ?;"; + int status; + sqlite3 *db; + sqlite3_stmt *qstmt; + + opendb(&db, &qstmt, mailquery); + status = sqlite3_bind_text(qstmt, 1, uname, -1, SQLITE_TRANSIENT); + if (status) + cleanup(db, qstmt, 3); + status = sqlite3_step(qstmt); + if (status != SQLITE_ROW) { + sqlite3_finalize(qstmt); + sqlite3_close(db); + if (status == SQLITE_DONE) + return 2; /* User not found */ + return 3; + } + printf("%s\n", sqlite3_column_text(qstmt, 0)); + cleanup(db, qstmt, 0); + return 0; +} + +int setmail(char *uname, char *newmail) { + char *setquery = "UPDATE dglusers SET email = ? WHERE username = ?;"; + sqlite3 *db; + sqlite3_stmt *qstmt; + int status; + + opendb(&db, &qstmt, setquery); + status = sqlite3_bind_text(qstmt, 2, uname, -1, SQLITE_TRANSIENT); + if (status) + cleanup(db, qstmt, 3); + status = sqlite3_bind_text(qstmt, 1, newmail, -1, SQLITE_TRANSIENT); + if (status) + cleanup(db, qstmt, 3); + status = sqlite3_step(qstmt); + if (status != SQLITE_DONE) + cleanup(db, qstmt, 3); + cleanup(db, qstmt, 0); + return 0; +} + int main(int argc, char *argv[]) { - char ibuf[IBUFSIZE], *uname, *pw, *email; + char ibuf[IBUFSIZE], *uname, *line1, *line2; char *cptr; // Utility pointer int status; /* Read in the username and password */ fgets(ibuf, IBUFSIZE, stdin); uname = ibuf; - pw = strchr(uname, '\n'); - if (pw == NULL) + line1 = strchr(uname, '\n'); + if (line1 == NULL) exit(4); /* Truncated */ - *pw = '\0'; - pw++; - fgets(pw, IBUFSIZE - (pw - ibuf), stdin); - if (pw[strlen(pw) - 1] == '\n') - pw[strlen(pw) - 1] = '\0'; - else - exit(4); /* Truncated */ + *line1 = '\0'; + if (argc == 1 || strcmp(argv[1], "getmail")) { + line1++; + fgets(line1, IBUFSIZE - (line1 - ibuf), stdin); + if (line1[strlen(line1) - 1] == '\n') + line1[strlen(line1) - 1] = '\0'; + else + exit(4); /* Truncated */ + } + if (argc > 1 && !strcmp(argv[1], "setmail")) { + /* E-mail, sanitize */ + for (cptr = line1; *cptr != '\0'; cptr++) { + if (!isalnum(*cptr) && !strchr("@._-", *cptr)) { + exit(4); + } + } + } if (argc > 1 && !strcmp(argv[1], "register")) { - email = pw + strlen(pw) + 1; - fgets(email, IBUFSIZE - (email - ibuf), stdin); - if (email[strlen(email) - 1] == '\n') - email[strlen(email) - 1] = '\0'; + line2 = line1 + strlen(line1) + 1; + fgets(line2, IBUFSIZE - (line2 - ibuf), stdin); + if (line2[strlen(line2) - 1] == '\n') + line2[strlen(line2) - 1] = '\0'; else exit(4); - for (cptr = email; *cptr != '\0'; cptr++) { + for (cptr = line2; *cptr != '\0'; cptr++) { if (!isalnum(*cptr) && !strchr("@._-", *cptr)) { exit(4); } @@ -147,9 +202,15 @@ } } if (argc == 1 || !strcmp(argv[1], "check")) - status = check(uname, pw); + status = check(uname, line1); else if (!strcmp(argv[1], "register")) { - status = insertuser(uname, pw, email); + status = insertuser(uname, line1, line2); + } + else if (!strcmp(argv[1], "getmail")) { + status = getmail(uname); + } + else if (!strcmp(argv[1], "setmail")) { + status = setmail(uname, line1); } else status = 127;