Adding code for password generator

This commit is contained in:
2026-06-16 12:35:18 -04:00
parent a626a7e681
commit e0c44f4841
15 changed files with 313 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
build/
out/
View File
View File
View File
View File
+46
View File
@@ -0,0 +1,46 @@
{
// Language version of C3.
"langrev": "1",
// Warnings used for all targets.
"warnings": [ "no-unused" ],
// Directories where C3 library files may be found.
"dependency-search-paths": [ "lib" ],
// Libraries to use for all targets.
"dependencies": [ ],
// Authors, optionally with email.
"authors": [ "John Doe <john.doe@example.com>" ],
// Version using semantic versioning.
"version": "0.1.0",
// Sources compiled for all targets.
"sources": [ "src/**" ],
// Test sources compiled for all targets.
"test-sources": [ "test/**" ],
// C sources if the project also compiles C sources
// relative to the project file.
// "c-sources": [ "csource/**" ],
// Include directories for C sources relative to the project file.
// "c-include-dirs": [ "csource/include" ],
// Build location, relative to project file.
"build-dir": "build",
// Output location, relative to project file.
"output": "build",
// Architecture and OS target.
// You can use 'c3c --list-targets' to list all valid targets.
// "target": "windows-x64",
// Targets.
"targets": {
"passgen": {
// Executable or library.
"type": "executable",
// Additional libraries, sources
// and overrides of global settings here.
"linked-libraries": ["sqlite3"],
},
},
// Global settings.
// CPU name, used for optimizations in the LLVM backend.
"cpu": "generic",
// Optimization: "O0", "O1", "O2", "O3", "O4", "O5", "Os", "Oz".
"opt": "O0"
// See resources/examples/project_all_settings.json and 'c3c --list-project-properties' to see more properties.
}
View File
+8
View File
@@ -0,0 +1,8 @@
create table passwords (
Id integer primary key not null,
Key varchar(256) not null,
Password varchar(256) not null
);
insert into passwords values(NULL, 'test', 'supersecret');
Binary file not shown.
View File
View File
+174
View File
@@ -0,0 +1,174 @@
module passgen;
import std::io;
import sql3;
import randpass;
SqlHandle *db;
fn int main(String[] args) {
// TODO: init sqlite
if (args.len < 2) {
io::eprintn("error: incorrect number of args");
io::eprintfn("usage: %s <passwords.db file>", args[0]);
return -1;
}
String dbFile = args[1];
SqlResult res = sql3::open((ZString)dbFile, &db);
if (res != SqlResult.OK) {
io::printfn("error: could not open database: %s", sql3::errMsg(db));
return -1;
}
menu();
return 0;
}
fn void menu() {
bool quit = false;
io::printn("Welcome to the password generator");
io::printn("=================================\n");
while (!quit) {
io::printn("\noptions:\n(c)create password \n(g)get password");
io::printn("(d)delete password\n(a)get all passwords\n(q)quit\n");
io::print("> ");
String? input = io::treadline();
if (catch error = input) {
io::printfn("invalid input: %s\n", error);
continue;
}
if (input[0] == 'q' || input[0] == 'Q') {
quit = true;
continue;
}
if (input[0] == 'c' || input[0] == 'C') {
createPassword();
} else if (input[0] == 'g' || input[0] == 'G') {
getPassword();
} else if (input[0] == 'a' || input[0] == 'A') {
getAllFromDB();
} else if (input[0] == 'd' || input[0] == 'D') {
deletePassword();
}
}
io::printn("\nThank you for using the password generator. Good bye");
io::printn("======================================================");
}
fn void createPassword() {
io::printn("\ncreate new password\nEnter the name of password");
io::print("> ");
String? key = io::treadline();
if (catch error = key) {
io::printfn("error incorrect input: %s\n", error);
return;
}
io::printn("Enter the length of the password");
io::print("> ");
int? len = io::treadline().to_int();
if (catch error = len) {
io::printfn("incorrect input for length: %s\n", error);
return;
}
ZString password = randpass::getPassword(len);
io::printfn("Your password for %s is %s", key, password);
insertIntoDB(key, password);
}
fn void insertIntoDB(String key, ZString password) {
ZString query = (ZString)string::format(mem, "insert into passwords values(NULL, '%s', '%s');", key, password);
SqlStmt stmt;
ZString *errMsg;
SqlResult res = sql3::exec(db, query, null, null, errMsg);
if (res != SqlResult.OK) {
io::eprintfn("error storing password: %s", errMsg);
sql3::free(errMsg);
return;
}
}
fn void getPassword() {
io::printn("\nget password\nEnter the name of password");
io::print("> ");
String? key = io::treadline();
if (catch error = key) {
io::printfn("error incorrect input: %s\n", error);
return;
}
queryPassword(key);
}
fn void queryPassword(String key) {
ZString query = (ZString)string::format(mem, "select password from passwords where key='%s';", key);
SqlStmt stmt;
SqlResult res = sql3::prepareV2(db, query, -1, &stmt, null);
if (res != SqlResult.OK) {
io::eprintfn("error querying from db: %s", sql3::errMsg(db));
return;
}
res = sql3::step(stmt);
if (res == SqlResult.ROW) {
ZString password = sql3::columnText(stmt, 0);
io::printfn("the password for %s is %s", key, password);
sql3::finalize(stmt);
}
}
fn void getAllFromDB() {
io::printn("\nall passwords");
ZString query = "select * from passwords;";
SqlStmt stmt;
SqlResult res = sql3::prepareV2(db, query, -1, &stmt, null);
if (res != SqlResult.OK) {
io::eprintfn("error querying from db: %s", sql3::errMsg(db));
return;
}
while ((res = sql3::step(stmt)) == SqlResult.ROW) {
ZString key = sql3::columnText(stmt, 1);
ZString password = sql3::columnText(stmt, 2);
io::printfn("%s : %s", key, password);
}
sql3::finalize(stmt);
}
fn void deletePassword() {
io::printn("\ndelete password\nEnter the name of password");
io::print("> ");
String? key = io::treadline();
if (catch error = key) {
io::eprintfn("error incorrect input: %s\n", error);
return;
}
deleteFromDB(key);
}
fn void deleteFromDB(String key) {
ZString query = (ZString)string::format(mem, "delete from passwords where key='%s';", key);
SqlStmt stmt;
ZString *errMsg;
SqlResult res = sql3::exec(db, query, null, null, errMsg);
if (res != SqlResult.OK) {
io::eprintfn("error deleting password: %s", errMsg);
sql3::free(errMsg);
return;
}
}
+16
View File
@@ -0,0 +1,16 @@
module randpass;
import std::io, std::math::random, std::time;
char[] chars = "0123456789abcdefghijklmnoqprstuvwyzxABCDEFGHIJKLMNOQPRSTUYWVZX!@#$%^&*?[]{}-_=+,";
uint numChars = 80;
fn ZString getPassword(int len) {
srand((ulong)time::now());
char *password = malloc(len * char.sizeof);
for (int i=0; i<len; i++) {
password[i] = chars[rand(numChars)];
}
return (ZString)password;
}
+67
View File
@@ -0,0 +1,67 @@
module sql3;
alias SqlHandle = void*;
alias SqlStmt = void*;
alias SqlCallback = fn SqlResult (void *context, CInt nCols, ZString* result, ZString* colNames);
extern fn SqlResult open(ZString file, SqlHandle *db) @cname("sqlite3_open");
extern fn SqlResult close(SqlHandle db) @cname("sqlite3_close");
extern fn SqlResult prepareV2(SqlHandle handle, ZString sql,
CInt byte, SqlStmt* stmt,
ZString* tail ) @cname("sqlite3_prepare_v2");
extern fn SqlResult exec(SqlHandle db, ZString sql,
SqlCallback callback,
void* arg, ZString* errmsg) @cname("sqlite3_exec");
extern fn ZString errMsg(SqlHandle db) @cname("sqlite3_errmsg");
extern fn void free(ZString *errmsg) @cname("sqlite3_free");
extern fn SqlResult step(SqlStmt stmt) @cname("sqlite3_step");
extern fn SqlResult finalize(SqlStmt stmt) @cname("sqlite3_finalize");
extern fn ZString columnText(SqlStmt stmt, int col) @cname("sqlite3_column_text");
constdef SqlColType : int {
INTEGER = 1,
FLOAT = 2,
BLOB = 4,
NULL = 5,
TEXT = 3,
}
constdef SqlResult : int {
OK = 0,
ERROR = 1,
INTERNAL = 2,
PERM = 3,
ABORT = 4,
BUSY = 5,
LOCKED = 6,
NOMEM = 7,
READONLY = 8,
INTERRUPT = 9,
IOERR = 10,
CORRUPT = 11,
NOTFOUND = 12,
FULL = 13,
CANTOPEN = 14,
PROTOCOL = 15,
EMPTY = 16,
SCHEMA = 17,
TOOBIG = 18,
CONSTRAINT = 19,
MISMATCH = 20,
MISUSE = 21,
NOLFS = 22,
AUTH = 23,
FORMAT = 24,
RANGE = 25,
NOTADB = 26,
NOTICE = 27,
WARNING = 28,
ROW = 100,
DONE = 101,
}
View File