きったんの頭

/*
 * sm.c - generates sitemap.xml
 * @example
 *      sm foo http://foo.bar/ > sitemap.xml
 * @url
 *      https://mind.kittttttan.info/c/sm
 */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
#include <time.h>

enum {
  MAX_DOMAIN = 128,
  MAX_PATHNAME = 260,
  MAX_LASTMOD = 12
};

static char domain[MAX_DOMAIN] = "http://your.domain.here/";

static void help() {
    puts("Usage:");
    puts("  sm target_dir [domain]");
}

static void walk(const char *dir) {
    static char path[MAX_PATHNAME];
    static char lastmod[MAX_LASTMOD];

    DIR *dp;
    struct dirent *ep;
    struct stat st;
    struct tm *tmp;

    dp = opendir(dir);
    if (!dp) {
        fprintf(stderr, "Failed to open directory %s\n", dir);
        return;
    }

    while ((ep = readdir(dp))) {
        if (strcmp(ep->d_name, ".") && strcmp(ep->d_name, "..")) {
            strcpy(path, dir);
            strcat(path, "/");
            strcat(path, ep->d_name);
            if (stat(path, &st)) {
                fprintf(stderr, "Failed to get stat %s\n", path);
                break;
            }
            if (S_ISDIR(st.st_mode)) {
                walk(path);
            } else {
                tmp = localtime(&st.st_mtime);
                strftime(lastmod, MAX_LASTMOD - 1, "%Y-%m-%d", tmp);
                printf(
                    "<url><loc>%s%s</loc><lastmod>%s</lastmod></url>\n",
                    domain, path, lastmod);
            }
        }
    }

    closedir(dp);
}

int main(int argc, char **argv) {
    if (argc > 1) {
        if (argc > 2) {
          strncpy(domain, argv[2], MAX_DOMAIN);
        }
        puts("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        puts("<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">");
        walk(argv[1]);
        puts("</urlset>");
    } else {
        help();
    }

    return 0;
}