commit 5e52c764c498d83c9a2433dfd9feac6951f31475
parent c881a66f770eba75347951ea58efad70dd0cdabf
Author: Paco Esteban <paco@e1e0.net>
Date: Tue, 12 May 2020 19:58:29 +0200
progress on the struct conversion
Diffstat:
M | ssnail.c | | | 171 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------- |
1 file changed, 117 insertions(+), 54 deletions(-)
diff --git a/ssnail.c b/ssnail.c
@@ -16,7 +16,9 @@
#include <dirent.h>
#include <err.h>
+#include <errno.h>
#include <sys/queue.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <sys/syslimits.h>
#include <stdio.h>
@@ -28,11 +30,27 @@
#define MAX_META 255
+struct article {
+ char src_path[PATH_MAX];
+ char dst_path[PATH_MAX];
+ char *orig_content;
+ size_t origz;
+ char *html_content;
+ size_t htmlz;
+ char title[MAX_META];
+ char author[MAX_META];
+ char date[MAX_META];
+ long long src_mtime;
+ long long dst_mtime;
+ SLIST_ENTRY(article) entries;
+};
+
char *str_rep(const char *, const char *, const char *);
-int gen_html(char *, char *);
+int gen_html(char **, size_t *, char *, char *, char *, char *, size_t);
int build_full_path(char *, char *, char *);
-int load_template(char **, char *);
+int load_from_file(char **, char *);
void usage();
+int populate_article_entry(struct article *);
int
main(int argc, char *argv[])
@@ -40,7 +58,8 @@ main(int argc, char *argv[])
DIR *dirp;
struct dirent *dp;
int ch;
- char srcdir[PATH_MAX] = "", dstdir[PATH_MAX] = "";
+ char srcdir[PATH_MAX] = "", dstdir[PATH_MAX] = "", *fbuf = NULL;
+ struct article *a = NULL, *ap = NULL;
while ((ch = getopt(argc, argv, "s:d:")) != -1) {
switch (ch) {
@@ -57,28 +76,50 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
+ SLIST_HEAD(listhead, article) head;
+ SLIST_INIT(&head); // init the linked list
+
// src and dst dir are mandatory.
if (srcdir[0] == '\0' || dstdir[0] == '\0')
usage();
- if ((dirp = opendir(srcdir)) != NULL) {
- while ((dp = readdir(dirp)) != NULL) {
- if (dp->d_type == DT_REG) { // only take regular files
- char srcpath[PATH_MAX] = "";
- char dstpath[PATH_MAX] = "";
- build_full_path(srcpath, srcdir, dp->d_name);
- build_full_path(dstpath, dstdir, dp->d_name);
- if(!gen_html(srcpath, dstpath))
- err(1, "cannot generate file %s",
- srcpath);
- }
- }
- closedir(dirp);
- } else {
- /* could not open directory */
+ if ((dirp = opendir(srcdir)) == NULL)
err(1, "cannot open src dir");
+
+ while ((dp = readdir(dirp)) != NULL) {
+ if (dp->d_type == DT_REG) {
+ //load all in a linked list
+ a = malloc(sizeof(struct article));
+ build_full_path(a->src_path, srcdir, dp->d_name);
+ // replace markdown extension for html
+ fbuf = str_rep(dp->d_name, ".md", ".html");
+ build_full_path(a->dst_path, dstdir, fbuf);
+ if((populate_article_entry(a) == -1))
+ err(2, "cannot populate article");
+ SLIST_INSERT_HEAD(&head, a, entries);
+ }
+ }
+
+ SLIST_FOREACH(ap, &head, entries) {
+ printf("%s (%lld) --> %s (%lld)\n",
+ ap->src_path, ap->src_mtime,
+ ap->dst_path, ap->dst_mtime
+ );
+ /* printf("----\n%s\n----\nsize(%zd)\n", */
+ /* ap->orig_content, ap->origz); */
+ printf("- Title: %s\n", ap->title);
+ printf("- Author: %s\n", ap->author);
+ printf("- Date: %s\n", ap->date);
+ printf("----\n%s\n----\nsize(%zd)\n",
+ ap->html_content, ap->htmlz);
}
+ closedir(dirp);
+ /* TODO: free the linked list structure <06-05-2020, paco> */
+ free(ap);
+ free(a);
+ free(fbuf);
+
return 0;
}
@@ -134,14 +175,12 @@ str_rep(const char *s, const char *oldW, const char *newW)
}
int
-gen_html(char origfile[PATH_MAX], char destfile[PATH_MAX])
+gen_html(char **dest, size_t *destz,
+ char title[MAX_META], char author[MAX_META], char date[MAX_META],
+ char *orig, size_t origz)
{
- FILE *fin, *fout;
- char *ret = NULL, *head_tpl = NULL, *foot_tpl = NULL,
+ char *head_tpl = NULL, *foot_tpl = NULL,
*header = NULL, *footer = NULL;
- char title[MAX_META] = "", author[MAX_META] = "",
- date[MAX_META] = "";
- size_t retsz = 0;
struct lowdown_opts opts;
struct lowdown_metaq mq;
struct lowdown_meta *md;
@@ -151,7 +190,6 @@ gen_html(char origfile[PATH_MAX], char destfile[PATH_MAX])
memset(&opts, 0, sizeof(struct lowdown_opts)); // init opts to 0
opts.maxdepth = 128;
- /* opts.type = LOWDOWN_TERM; */
opts.type = LOWDOWN_HTML;
opts.feat = LOWDOWN_FOOTNOTES |
LOWDOWN_AUTOLINK |
@@ -166,10 +204,8 @@ gen_html(char origfile[PATH_MAX], char destfile[PATH_MAX])
LOWDOWN_HTML_OWASP |
LOWDOWN_HTML_SKIP_HTML;
- if ((fin = fopen(origfile, "r")) == NULL)
- goto out1;
- if (!lowdown_file(&opts, fin, &ret, &retsz, &mq))
- goto out1;
+ lowdown_buf(&opts, orig, origz, dest, destz, &mq);
+ /* printf("%s\n%zd\n", dest, *destz); */
TAILQ_FOREACH(md, &mq, entries) {
if (strcmp(md->key, "title") == 0 )
@@ -180,40 +216,67 @@ gen_html(char origfile[PATH_MAX], char destfile[PATH_MAX])
(void)strlcpy(date, md->value, MAX_META);
}
- if (strlen(title) == 0 || strlen(author) == 0 || strlen(date) == 0)
- goto out1;
+ /* if (strlen(title) == 0 || strlen(author) == 0 || strlen(date) == 0) */
+ /* goto out; */
- load_template(&head_tpl, "_header.html");
- header = str_rep(head_tpl, "$title$", title);
- header = str_rep(header, "$author$", author);
- header = str_rep(header, "$date$", date);
- load_template(&foot_tpl, "_footer.html");
- footer = str_rep(foot_tpl, "$title$", title);
+ /* load_from_file(&head_tpl, "_header.html"); */
+ /* header = str_rep(head_tpl, "$title$", title); */
+ /* header = str_rep(header, "$author$", author); */
+ /* header = str_rep(header, "$date$", date); */
+ /* load_from_file(&foot_tpl, "_footer.html"); */
+ /* footer = str_rep(foot_tpl, "$title$", title); */
- if ((fout = fopen(destfile, "w")) == NULL)
- goto out2;
- fwrite(header, 1, strlen(header), fout);
- fwrite(ret, 1, retsz, fout);
- fwrite(footer, 1, strlen(footer), fout);
+ /* if ((fout = fopen(destfile, "w")) == NULL) */
+ /* goto out; */
+ /* fwrite(header, 1, strlen(header), fout); */
+ /* fwrite(ret, 1, retsz, fout); */
+ /* fwrite(footer, 1, strlen(footer), fout); */
r = 1;
-out2:
- fclose(fout);
-out1:
- fclose(fin);
- free(ret);
+out:
+ /* free(ret); */
lowdown_metaq_free(&mq);
- free(head_tpl);
- free(header);
- free(footer);
- free(foot_tpl);
+ /* free(head_tpl); */
+ /* free(header); */
+ /* free(footer); */
+ /* free(foot_tpl); */
return r;
}
int
+populate_article_entry(struct article *ap)
+{
+ struct stat st;
+ int retval = -1;
+ int len = 0;
+
+ if (stat(ap->src_path, &st) == -1)
+ goto out;
+ ap->src_mtime = st.st_mtim.tv_sec;
+
+ if (stat(ap->dst_path, &st) == -1) { // dst file does not have to exist
+ if (errno != ENOENT)
+ goto out;
+ ap->dst_mtime = 0;
+ } else {
+ ap->dst_mtime = st.st_mtim.tv_sec;
+ }
+
+ if ((ap->origz = load_from_file(&ap->orig_content, ap->src_path)) == 0)
+ goto out;
+
+ gen_html(&ap->html_content, &ap->htmlz,
+ ap->title, ap->author, ap->date,
+ ap->orig_content, ap->origz);
+ retval = 0;
+out:
+ return retval;
+}
+
+int
build_full_path(char fullpath[PATH_MAX], char *dir, char *file)
{
// build the full path
@@ -226,12 +289,12 @@ build_full_path(char fullpath[PATH_MAX], char *dir, char *file)
}
int
-load_template(char **buffer, char *path)
+load_from_file(char **buffer, char *path)
{
long length;
FILE *f = NULL;
- if ((f = fopen(path, "rb")) == NULL)
+ if ((f = fopen(path, "r")) == NULL)
return 0;
if (f) {
@@ -250,7 +313,7 @@ load_template(char **buffer, char *path)
*(*buffer + length) = '\0';
}
- return 1;
+ return length + 1;
}
void