new: working on the gen command

This commit is contained in:
ngn 2024-05-02 22:53:52 +03:00
parent 0d00678c30
commit e29c3ce419
11 changed files with 380 additions and 113 deletions

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-05-02 00:49+0300\n" "POT-Creation-Date: 2024-05-02 22:51+0300\n"
"PO-Revision-Date: 2024-05-01 13:34+0300\n" "PO-Revision-Date: 2024-05-01 13:34+0300\n"
"Last-Translator: <ngn@ngn.tf>\n" "Last-Translator: <ngn@ngn.tf>\n"
"Language-Team: Turkish <gnome-turk@gnome.org>\n" "Language-Team: Turkish <gnome-turk@gnome.org>\n"
@ -17,45 +17,84 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src/config.c:13
msgid "Configuration target is missing a name"
msgstr ""
#: src/config.c:18
#, c-format
msgid "Configuration target \"%s\" does not have \"dst\" field"
msgstr ""
#: src/config.c:23 #: src/config.c:23
#, c-format
msgid "Configuration target \"%s\" does not have \"src\" field"
msgstr ""
#: src/config.c:32
msgid "Configuration does not have a name field" msgid "Configuration does not have a name field"
msgstr "" msgstr ""
#: src/config.c:37 #: src/config.c:28
msgid "Configuration does not have an author field" msgid "Configuration does not have an author field"
msgstr "" msgstr ""
#: src/config.c:42 #: src/config.c:33
msgid "Configuration does not have any targets" msgid "Configuration does not have any targets"
msgstr "" msgstr ""
#: src/config.c:120 #: src/config.c:91
msgid "Configuration contains multiple targets with the same name"
msgstr ""
#: src/config.c:113
#, c-format #, c-format
msgid "Key %s is unknown" msgid "Key %s is unknown"
msgstr "" msgstr ""
#: src/config.c:156 #: src/config.c:143
msgid "Configuration file not found" msgid "Configuration file not found"
msgstr "" msgstr ""
#: src/config.c:170 #: src/config.c:158
msgid "Failed to parse configuration file" msgid "Failed to parse configuration file"
msgstr "" msgstr ""
#: src/config.c:174
msgid "Configuration details:\n"
msgstr ""
#: src/config.c:175
msgid "Name"
msgstr ""
#: src/config.c:176
msgid "Author"
msgstr ""
#: src/config.c:178
msgid "Keywords"
msgstr ""
#: src/gen.c:15
msgid "Please specify a directory for the repository"
msgstr ""
#: src/gen.c:20
msgid "Failed to access the directory"
msgstr ""
#: src/gen.c:25
msgid "Failed to change directory to the specified directory"
msgstr ""
#: src/gen.c:29 src/gen.c:36 src/pull.c:82
msgid "Loaded repository configuration"
msgstr ""
#: src/gen.c:31 src/pull.c:77
msgid "Failed to load the configuration file (mc.cfg):"
msgstr ""
#: src/gen.c:42
msgid "Copying all the targets"
msgstr ""
#: src/gen.c:47
msgid "Failed to copy the target:"
msgstr ""
#: src/gen.c:53
#, c-format
msgid "%s: copy success"
msgstr ""
#: src/log.c:145 #: src/log.c:145
msgid "y" msgid "y"
msgstr "" msgstr ""
@ -146,43 +185,58 @@ msgstr ""
msgid "Failed to chdir to %s" msgid "Failed to chdir to %s"
msgstr "" msgstr ""
#: src/pull.c:77
msgid "Failed to load the configuration file (mc.cfg):"
msgstr ""
#: src/pull.c:82
msgid "Loaded repository configuration"
msgstr ""
#: src/pull.c:83
msgid "Configuration details:\n"
msgstr ""
#: src/pull.c:84
msgid "Name"
msgstr ""
#: src/pull.c:85 #: src/pull.c:85
msgid "Author"
msgstr ""
#: src/pull.c:87
msgid "Keywords"
msgstr ""
#: src/pull.c:92
msgid "Do you want to continue?" msgid "Do you want to continue?"
msgstr "" msgstr ""
#: src/pull.c:95 #: src/pull.c:88
msgid "Checking all the targets" msgid "Checking all the targets"
msgstr "" msgstr ""
#: src/pull.c:99 #: src/pull.c:92
#, c-format #, c-format
msgid "Failed to access the source for the target \"%s\"" msgid "Failed to access the source for the target \"%s\""
msgstr "" msgstr ""
#: src/pull.c:105 #: src/pull.c:98
msgid "All the targets are OK" msgid "All the targets are OK"
msgstr "" msgstr ""
#: src/target.c:13
msgid "Configuration target is missing a name"
msgstr ""
#: src/target.c:18
#, c-format
msgid "Configuration target \"%s\" does not have \"dst\" field"
msgstr ""
#: src/target.c:23
#, c-format
msgid "Configuration target \"%s\" does not have \"src\" field"
msgstr ""
#: src/target.c:38
#, c-format
msgid "Failed to open the directory: %s"
msgstr ""
#: src/target.c:76
#, c-format
msgid "Source directory \"%s\" does not exist"
msgstr ""
#: src/util.c:115 src/util.c:126
#, c-format
msgid "Failed to create directory: %s"
msgstr ""
#: src/util.c:205
#, c-format
msgid "Failed to open \"%s\" for reading"
msgstr ""
#: src/util.c:207
#, c-format
msgid "Failed to open \"%s\" for writing"
msgstr ""

View File

@ -8,23 +8,14 @@
#include "log.h" #include "log.h"
#include "util.h" #include "util.h"
bool target_is_valid(target_t *target) { bool config_contains_target(config_t *config, char *name) {
if (NULL == target->name) { target_t *cur = config->t_last;
error_set(_("Configuration target is missing a name")); while (cur) {
return false; if (eq(cur->name, name))
}
if (NULL == target->dst) {
error_set(_("Configuration target \"%s\" does not have \"dst\" field"), target->name);
return false;
}
if (NULL == target->src) {
error_set(_("Configuration target \"%s\" does not have \"src\" field"), target->name);
return false;
}
return true; return true;
cur = cur->next;
}
return false;
} }
bool config_is_valid(config_t *config) { bool config_is_valid(config_t *config) {
@ -55,13 +46,10 @@ bool config_is_valid(config_t *config) {
bool config_add_target(config_t *config, char *name) { bool config_add_target(config_t *config, char *name) {
target_t *new = malloc(sizeof(target_t)); target_t *new = malloc(sizeof(target_t));
clist_init(&new->requires); target_init(new);
new->next = NULL;
new->name = name; new->name = name;
new->desc = NULL;
new->dst = NULL; config->t_len++;
new->src = NULL;
if (NULL == config->t_first || NULL == config->t_last) { if (NULL == config->t_first || NULL == config->t_last) {
config->t_first = new; config->t_first = new;
@ -99,6 +87,11 @@ int config_handler(void *data, const char *section, const char *key, const char
if (NULL == config->t_last || (NULL != config->t_last->name && !eq(config->t_last->name, (char *)section))) { if (NULL == config->t_last || (NULL != config->t_last->name && !eq(config->t_last->name, (char *)section))) {
debug("adding new target => %s", section); debug("adding new target => %s", section);
if (config_contains_target(config, (char *)section)) {
error_set(_("Configuration contains multiple targets with the same name"));
errno = ConfigMultiple;
return 0;
}
config_add_target(config, strdup(section)); config_add_target(config, strdup(section));
} }
@ -122,15 +115,6 @@ UNKNOWN:
return 0; return 0;
} }
void target_free(target_t *target) {
free(target->name);
free(target->desc);
free(target->dst);
free(target->src);
clist_free(&target->requires);
free(target);
}
void config_free(config_t *config) { void config_free(config_t *config) {
free(config->name); free(config->name);
free(config->author); free(config->author);
@ -139,7 +123,9 @@ void config_free(config_t *config) {
while (cur != NULL) { while (cur != NULL) {
prev = cur; prev = cur;
cur = cur->next; cur = cur->next;
target_free(prev); target_free(prev);
free(prev);
} }
clist_free(&config->keywords); clist_free(&config->keywords);
@ -148,6 +134,7 @@ void config_free(config_t *config) {
config->author = NULL; config->author = NULL;
config->t_first = NULL; config->t_first = NULL;
config->t_last = NULL; config->t_last = NULL;
config->t_len = 0;
clist_init(&config->keywords); clist_init(&config->keywords);
} }
@ -162,11 +149,12 @@ bool config_load(config_t *config, char *path) {
config->author = NULL; config->author = NULL;
config->t_first = NULL; config->t_first = NULL;
config->t_last = NULL; config->t_last = NULL;
config->t_len = 0;
clist_init(&config->keywords); clist_init(&config->keywords);
if (ini_parse(path, config_handler, config) < 0) { if (ini_parse(path, config_handler, config) < 0) {
config_free(config); config_free(config);
if (errno != ConfigUnknown) { if (errno != ConfigUnknown || errno != ConfigMultiple) {
error_set(_("Failed to parse configuration file")); error_set(_("Failed to parse configuration file"));
errno = ConfigParseFail; errno = ConfigParseFail;
} }
@ -181,3 +169,14 @@ bool config_load(config_t *config, char *path) {
return true; return true;
} }
void config_print(config_t *config) {
info(_("Configuration details:\n"));
printf(COLOR_BOLD " %s " COLOR_RESET "=> %s\n", _("Name"), config->name);
printf(COLOR_BOLD " %s " COLOR_RESET "=> %s\n", _("Author"), config->author);
printf(COLOR_BOLD " %s " COLOR_RESET "=> ", _("Keywords"));
for (int i = 0; i < config->keywords.s; i++)
printf("%s ", config->keywords.c[i]);
printf("\n\n");
}

View File

@ -1,21 +1,13 @@
#pragma once #pragma once
#include "target.h"
#include "util.h" #include "util.h"
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
typedef struct target {
struct target *next;
clist_t
requires;
char *name;
char *desc;
char *src;
char *dst;
} target_t;
typedef struct config { typedef struct config {
target_t *t_first; target_t *t_first;
target_t *t_last; target_t *t_last;
size_t t_len;
char *name; char *name;
char *author; char *author;
@ -24,3 +16,4 @@ typedef struct config {
bool config_load(config_t *, char *); bool config_load(config_t *, char *);
void config_free(config_t *); void config_free(config_t *);
void config_print(config_t *);

View File

@ -5,6 +5,13 @@ enum ErrorCodes {
ConfigNotFound = 954, ConfigNotFound = 954,
ConfigInvalid = 953, ConfigInvalid = 953,
ConfigParseFail = 952, ConfigParseFail = 952,
ConfigMultiple = 951,
TargetSrcFail = 950,
OpendirFail = 948,
MkdirFail = 945,
OpenFail = 944,
}; };
extern int errno; extern int errno;

View File

@ -1,5 +1,64 @@
#include "gen.h" #include "gen.h"
#include "args.h"
#include "config.h"
#include "error.h"
#include "intl.h"
#include "log.h"
#include "util.h"
#include <unistd.h>
bool gen_cmd() { bool gen_cmd() {
return true; bool ret = false;
config_t cfg;
if (args.count != 2) {
error(_("Please specify a directory for the repository"));
return ret;
}
if (!exists(args.list[1]) || !is_dir(args.list[1])) {
error(_("Failed to access the directory"));
return ret;
}
if (chdir(args.list[1]) < 0) {
error(_("Failed to change directory to the specified directory"));
return ret;
}
success(_("Loaded repository configuration"));
if (!config_load(&cfg, "mc.cfg")) {
error(_("Failed to load the configuration file (mc.cfg):"));
details(errch);
return ret;
}
success(_("Loaded repository configuration"));
config_print(&cfg);
target_t *cur = cfg.t_first;
int counter = 0;
info(_("Copying all the targets"));
bar_init();
while (cur && counter++) {
if(!target_copy(cur, true)){
error(_("Failed to copy the target:"));
details(errch);
bar_free();
goto END;
}
success(_("%s: copy success"));
bar(counter, cfg.t_len);
cur = cur->next;
}
bar_free();
ret = true;
END:
config_free(&cfg);
return ret;
} }

View File

@ -80,14 +80,7 @@ COPY:
} }
success(_("Loaded repository configuration")); success(_("Loaded repository configuration"));
info(_("Configuration details:\n")); config_print(&repo_cfg);
printf(COLOR_BOLD " %s " COLOR_RESET "=> %s\n", _("Name"), repo_cfg.name);
printf(COLOR_BOLD " %s " COLOR_RESET "=> %s\n", _("Author"), repo_cfg.author);
printf(COLOR_BOLD " %s " COLOR_RESET "=> ", _("Keywords"));
for (int i = 0; i < repo_cfg.keywords.s; i++)
printf("%s ", repo_cfg.keywords.c[i]);
printf("\n\n");
if (!yesno(_("Do you want to continue?"))) if (!yesno(_("Do you want to continue?")))
goto END; goto END;

110
src/target.c Normal file
View File

@ -0,0 +1,110 @@
#include "target.h"
#include "error.h"
#include "intl.h"
#include "util.h"
#include <libgen.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
bool target_is_valid(target_t *t) {
if (NULL == t->name) {
error_set(_("Configuration target is missing a name"));
return false;
}
if (NULL == t->dst) {
error_set(_("Configuration target \"%s\" does not have \"dst\" field"), t->name);
return false;
}
if (NULL == t->src) {
error_set(_("Configuration target \"%s\" does not have \"src\" field"), t->name);
return false;
}
return true;
}
bool target_copy_dir(char *src, char *dst) {
if (!mksubdirsp(dst, 755))
return false;
DIR *dir = opendir(src);
struct dirent *ent = NULL;
if (NULL == dir) {
error_set(_("Failed to open the directory: %s"), src);
errno = OpendirFail;
return false;
}
size_t src_len = strlen(src);
size_t dst_len = strlen(dst);
while ((ent = readdir(dir)) != NULL) {
size_t len = strlen(ent->d_name);
char src_fp[src_len + len + 2], dst_fp[dst_len + len + 2];
join(src_fp, src, ent->d_name);
join(dst_fp, dst, ent->d_name);
if (is_dir(src_fp)) {
if (!target_copy_dir(src_fp, dst_fp))
return false;
continue;
}
if (!copyfile(src_fp, dst_fp))
return false;
}
return true;
}
bool target_copy(target_t *t, bool fromdst) {
char *src = t->src, *dst = t->dst;
bool ret = false;
if (fromdst) {
src = t->dst;
dst = t->src;
}
if (!exists(t->src)) {
error_set(_("Source directory \"%s\" does not exist"), src);
errno = TargetSrcFail;
return ret;
}
if (is_dir(src))
return target_copy_dir(src, dst);
char *dstcp = strdup(dst);
char *dstdir = dirname(dst);
if(!mksubdirsp(dstdir, 0755))
return ret;
ret = copyfile(src, dstcp);
free(dstcp);
return ret;
}
void target_init(target_t *t) {
clist_init(&t->requires);
t->next = NULL;
t->name = NULL;
t->desc = NULL;
t->dst = NULL;
t->src = NULL;
}
void target_free(target_t *t) {
free(t->name);
free(t->desc);
free(t->dst);
free(t->src);
clist_free(&t->requires);
}

17
src/target.h Normal file
View File

@ -0,0 +1,17 @@
#include "util.h"
#include <stdbool.h>
typedef struct target {
struct target *next;
clist_t
requires;
char *name;
char *desc;
char *src;
char *dst;
} target_t;
bool target_is_valid(target_t *);
void target_init(target_t *);
void target_free(target_t *);
bool target_copy(target_t *, bool);

View File

@ -8,6 +8,8 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include "error.h"
#include "intl.h"
#include "util.h" #include "util.h"
bool eq(char *s1, char *s2) { bool eq(char *s1, char *s2) {
@ -109,16 +111,22 @@ bool mksubdirsp(char *path, int perms) {
for (char *c = path; *c != '\0'; c++) { for (char *c = path; *c != '\0'; c++) {
if (*c == '/' && indx != 0) { if (*c == '/' && indx != 0) {
cur[indx] = '\0'; cur[indx] = '\0';
if (!exists(cur) && mkdir(cur, perms) < 0) if (!exists(cur) && mkdir(cur, perms) < 0){
error_set(_("Failed to create directory: %s"), cur);
errno = MkdirFail;
return false; return false;
} }
}
cur[indx] = *c; cur[indx] = *c;
indx++; indx++;
} }
if (!exists(cur) && mkdir(cur, perms) < 0) if (!exists(cur) && mkdir(cur, perms) < 0){
error_set(_("Failed to create directory: %s"), cur);
errno = MkdirFail;
return false; return false;
}
return true; return true;
} }
@ -187,3 +195,29 @@ void clist_add(clist_t *l, char *en) {
l->c[l->s] = en; l->c[l->s] = en;
l->s++; l->s++;
} }
bool copyfile(char *src, char *dst){
FILE *srcf = fopen(src, "r");
FILE *dstf = fopen(dst, "w");
if(NULL == srcf || NULL == dstf){
if(NULL == srcf)
error_set(_("Failed to open \"%s\" for reading"), srcf);
else
error_set(_("Failed to open \"%s\" for writing"), dstf);
errno = OpenFail;
return false;
}
char buffer[32];
int read = -1;
bzero(buffer, 32);
while((read = fread(buffer, 1, 32, srcf)) > 0)
fwrite(buffer, 1, read, dstf);
fclose(srcf);
fclose(dstf);
return true;
}

View File

@ -18,6 +18,7 @@ int randint(int, int);
bool is_dir(char *); bool is_dir(char *);
bool mksubdirsp(char *, int); bool mksubdirsp(char *, int);
bool rmrf(char *); bool rmrf(char *);
bool copyfile(char *, char *);
void clist_init(clist_t *); void clist_init(clist_t *);
void clist_from_str(clist_t *, char *); void clist_from_str(clist_t *, char *);