commit 1cbec25e63e0a6243547ceda6f6cd880a6926d5a
parent 2dd1881b35fdeb12f7a696ee437a52a7e61ab6b3
Author: Paco Esteban <paco@e1e0.net>
Date: Thu, 11 Jun 2020 19:42:29 +0200
process markdown and assets in the same way
and copy/process recursively.
Diffstat:
M | .gitignore | | | 2 | +- |
M | ssnail.c | | | 153 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
2 files changed, 124 insertions(+), 31 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -2,7 +2,7 @@ ssnail
*.d
*.o
*.core
-data
+source
destHtml
destTxt
_*.html
diff --git a/ssnail.c b/ssnail.c
@@ -50,15 +50,18 @@ struct article {
struct article *a = NULL;
SLIST_HEAD(listhead, article) head;
-char *str_rep(const char *, const char *, const char *);
-int gen_html(struct article *);
-int build_full_path(char *, char *, char *);
-int load_from_file(char **, char *);
-void usage();
-int populate_article_entry(struct article *);
-int write_html(struct article *, char *, char *);
-void articleq_free(struct listhead *);
-int generate_index(struct listhead *, char *, char *, char *);
+char *str_rep(const char *, const char *, const char *);
+int gen_html(struct article *);
+int build_full_path(char *, char *, char *);
+int load_from_file(char **, char *);
+void usage();
+int populate_article_entry(struct article *);
+int write_html(struct article *, char *, char *);
+void articleq_free(struct listhead *);
+int generate_index(struct listhead *, char *, char *, char *);
+int process_dir(char[PATH_MAX], char[PATH_MAX], int);
+const char *get_filename_ext(const char *);
+int copy_file(const char *, const char *, int);
int
main(int argc, char *argv[])
@@ -104,24 +107,8 @@ main(int argc, char *argv[])
if (srcdir[0] == '\0' || dstdir[0] == '\0')
usage();
- 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);
- }
- }
- closedir(dirp);
- free(fbuf);
+ if (process_dir(srcdir, dstdir, force) == -1)
+ err(1, "cannot process src dir");
printf("Generate html files ... \n");
SLIST_FOREACH(ap, &head, entries) {
@@ -173,9 +160,11 @@ generate_index(struct listhead *h, char head_tpl[PATH_MAX],
// TODO: make this list reverse date ordered
fprintf(fout, "<ul>\n");
SLIST_FOREACH(a, h, entries) {
- if (strcmp(a->type, "article") == 0)
- fprintf(fout, "<li><a href='%s'>%s</a></li>\n",
- a->dst_path, a->title);
+ if (strcmp(a->type, "article") == 0) {
+ char *href = strchr(a->dst_path, '/') + 1;
+ fprintf(fout, "<li><a href=\"%s\">%s</a></li>\n",
+ href, a->title);
+ }
}
fprintf(fout, "</ul>\n");
fwrite(footer, 1, strlen(footer), fout);
@@ -426,3 +415,107 @@ usage()
printf("usage\n");
exit(1);
}
+
+int
+process_dir(char orig[PATH_MAX], char dest[PATH_MAX], int force)
+{
+ DIR *dirp;
+ struct dirent *dp;
+ struct stat st;
+ int retval = -1;
+
+ if (stat(dest, &st) == -1 && errno == ENOENT) {
+ if (mkdir(dest, 0755) == -1)
+ return -1;
+ }
+
+ if ((dirp = opendir(orig)) == NULL)
+ goto out;
+
+ while ((dp = readdir(dirp)) != NULL) {
+ if (strcmp(dp->d_name, ".") == 0
+ || strcmp(dp->d_name, "..") == 0)
+ continue;
+
+ char orig_path[PATH_MAX], dest_path[PATH_MAX];
+
+ if (build_full_path(orig_path, orig, dp->d_name) == -1)
+ goto out;
+ if (build_full_path(dest_path, dest, dp->d_name) == -1)
+ goto out;
+
+ if (dp->d_type == DT_REG) {
+ if (strcmp(get_filename_ext(orig_path), "md") == 0) {
+ char *fbuf = NULL;
+ a = malloc(sizeof(struct article));
+
+ (void)strlcpy(a->src_path, orig_path, PATH_MAX);
+ fbuf = str_rep(dest_path, ".md", ".html");
+ (void)strlcpy(a->dst_path, fbuf, PATH_MAX);
+ free(fbuf);
+
+ if((populate_article_entry(a) == -1))
+ err(2, "cannot populate article");
+ SLIST_INSERT_HEAD(&head, a, entries);
+ } else {
+ if (copy_file(orig_path, dest_path, force) == -1)
+ goto out;
+ }
+ }
+ if (dp->d_type == DT_DIR) {
+ if (process_dir(orig_path, dest_path, force) == -1)
+ goto out;
+ }
+ }
+
+ retval = 0;
+
+out:
+ closedir(dirp);
+ return retval;
+}
+
+const char *
+get_filename_ext(const char *filename) {
+ const char *dot = strrchr(filename, '.');
+ if(!dot || dot == filename)
+ return "";
+ return dot + 1;
+}
+
+int
+copy_file(const char *source_file, const char *dest_file, int force)
+{
+ FILE *src, *dst;
+ struct stat st;
+ char ch;
+ long long src_mtime, dst_mtime;
+
+ if (stat(source_file, &st) == -1)
+ return -1;
+ src_mtime = st.st_mtim.tv_sec;
+
+ if (stat(dest_file, &st) == -1) { // dst file does not have to exist
+ if (errno != ENOENT)
+ return -1;
+ dst_mtime = 0;
+ } else {
+ dst_mtime = st.st_mtim.tv_sec;
+ }
+
+ if ((src_mtime > dst_mtime) || force) {
+ if ((src = fopen(source_file, "r")) == NULL)
+ return -1;
+ if ((dst = fopen(dest_file, "w")) == NULL)
+ return -1;
+
+ printf("copying %s --> %s\n", source_file, dest_file);
+ while ((ch = fgetc(src)) != EOF)
+ fputc(ch, dst);
+
+ fclose(src);
+ fclose(dst);
+ }
+
+ return 0;
+}