178 行
4.1 KiB
C
178 行
4.1 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
#include <curl/curl.h>
|
|
#include <time.h>
|
|
#include <sys/stat.h>
|
|
//#include <libxml/tree.h>
|
|
#include <stdlib.h>
|
|
//#include <errno.h>
|
|
#include<unistd.h>
|
|
// http
|
|
// regex
|
|
|
|
// http://かhttps://で始まるかどうか
|
|
bool checkprefix (const char *url) {
|
|
return strncmp("http://", url, 7) == 0 || strncmp("https://", url, 8) == 0;
|
|
}
|
|
|
|
void mkdirs (char *path, int perm) {
|
|
char **res = NULL;
|
|
char *subpath = strtok(path, "/");
|
|
int nsla = 0, i;
|
|
|
|
while (subpath) {
|
|
res = realloc(res, sizeof(char*) * ++nsla);
|
|
if (res == NULL) exit(-1);
|
|
res[nsla-1] = subpath;
|
|
subpath = strtok(NULL, "/");
|
|
}
|
|
|
|
res = realloc (res, sizeof (char*) * (nsla+1));
|
|
res[nsla] = 0;
|
|
|
|
for (i = 0; i < (nsla+1); ++i) {
|
|
mkdir(res[i], perm);
|
|
chdir(res[i]);
|
|
}
|
|
|
|
free(res);
|
|
}
|
|
|
|
char *preparepage (char *url) {
|
|
// URLは「/」で終わなければ、追加
|
|
char *ext = url + strlen(url)-1;
|
|
char surl[strlen(url)+1];
|
|
strncpy(surl, url, sizeof(surl));
|
|
if (!strcmp(ext, "/") == 0) {
|
|
strcat(surl, "/");
|
|
}
|
|
else {
|
|
strcat(surl, "");
|
|
}
|
|
|
|
// タイムスタンプ
|
|
int timestamp = time(NULL);
|
|
char strtimestamp[10];
|
|
|
|
// パス
|
|
int sublen;
|
|
if (strncmp("http://", url, 7) == 0) sublen = 6;
|
|
else if (strncmp("https://", url, 8) == 0) sublen = 7;
|
|
int reslen = strlen(surl);
|
|
char nurl[reslen];
|
|
int j = 0;
|
|
int i = 0;
|
|
|
|
while (surl[i] != '\0') {
|
|
i++;
|
|
if (i >= sublen) {
|
|
nurl[j] = surl[i];
|
|
j++;
|
|
}
|
|
}
|
|
|
|
// タイムスタンプはintからchar *に交換
|
|
sprintf(strtimestamp, "%d", timestamp);
|
|
|
|
// パスの創作
|
|
char *path = malloc(strlen("archive/") + strlen(strtimestamp) + strlen(nurl));
|
|
strcpy(path, "archive/");
|
|
strcat(path, strtimestamp);
|
|
strcat(path, nurl);
|
|
|
|
// フォルダの創作
|
|
char mpath[strlen(path)];
|
|
strcpy(mpath, path);
|
|
mkdirs(mpath, 0755);
|
|
|
|
return(path);
|
|
}
|
|
|
|
// TODO
|
|
void scanpage (char *url) {}
|
|
|
|
int getpage (char *url, char *path) {
|
|
char fpath[strlen(path) + strlen("index.html")];
|
|
strcpy(fpath, path);
|
|
strcat(fpath, "index.html");
|
|
//strncpy(fpath, path, sizeof(fpath));
|
|
//strncat(fpath, "index.html", sizeof(fpath));
|
|
printf("FPATH: %s\n", fpath);
|
|
FILE* file = fopen(fpath, "w");
|
|
CURL* curl = curl_easy_init();
|
|
CURLcode curlres;
|
|
|
|
// ウェブページを読み込む
|
|
if (curl) {
|
|
// CURLの実行
|
|
curl_easy_setopt(curl, CURLOPT_URL, url);
|
|
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
|
|
|
|
// リターンコード
|
|
curlres = curl_easy_perform(curl);
|
|
|
|
// エラーの確認
|
|
if (curlres != CURLE_OK) {
|
|
fprintf(stderr, "curl_easy_perform()の実行に失敗しました。 %s\n", curl_easy_strerror(curlres));
|
|
return(-1);
|
|
}
|
|
|
|
// 掃除
|
|
curl_easy_cleanup(curl);
|
|
|
|
// TODO: JS、動画等の削除
|
|
// TODO: CSS、画像等ファイルのダウンロード
|
|
// TODO: 全部/usr/(local/)share/hozonsite/archiveに保存する
|
|
|
|
return(0);
|
|
}
|
|
|
|
return(-1);
|
|
}
|
|
|
|
// TODO
|
|
void startsrv (int port) {
|
|
printf("http://127.0.0.1:%d でサーバーを実行中。終了するには、CTRL+Cを押して下さい。\n", port);
|
|
}
|
|
|
|
int main (int argc, char *argv[]) {
|
|
if (argc == 2) {
|
|
if (!strcmp("-v", argv[1])) {
|
|
printf("hozonsite-"VERSION);
|
|
printf("\n");
|
|
return(0);
|
|
}
|
|
else if (!strcmp("-s", argv[1])) {
|
|
startsrv(9920);
|
|
}
|
|
else {
|
|
if (checkprefix(argv[1]) == 1) {
|
|
printf("archive\n");
|
|
char * path = preparepage(argv[1]);
|
|
getpage(argv[1], path);
|
|
free(path);
|
|
}
|
|
else {
|
|
printf("URLは不正です。終了…\n");
|
|
return(0);
|
|
}
|
|
}
|
|
}
|
|
else if (argc == 3 && !strcmp("-s", argv[1])) {
|
|
char *ptr;
|
|
int port = strtol(argv[2], &ptr, 10);
|
|
startsrv(port);
|
|
}
|
|
else {
|
|
printf("使い方:\n");
|
|
printf("hozonsite -v : バージョンの確認\n");
|
|
printf("hozonsite -s <ポート番号> : ウェブサーバーの実行\n");
|
|
printf("hozonsite <URL> : コマンドラインでウェブサイトを保存する\n");
|
|
return(0);
|
|
}
|
|
|
|
return(0);
|
|
}
|