]> Nishi Git Mirror - odl.git/commitdiff
名前として保存オプション
author諏訪子 <suwako@076.moe>
Fri, 26 Apr 2024 09:14:15 +0000 (18:14 +0900)
committer諏訪子 <suwako@076.moe>
Fri, 26 Apr 2024 09:14:15 +0000 (18:14 +0900)
CHANGELOG.md
main.c

index 2185549a8e231f332aeef1bde130c4b699c2115b..9c80fdbd9a88622f5c933b6385b4d37ce8f0e645 100644 (file)
@@ -1,5 +1,6 @@
 # 0.2.0
 * ファイル名はパラメートルを付いたら、ファイル名は拡張子に
+* 名前として保存オプション
 
 # 0.1.0
 * 最初リリース
diff --git a/main.c b/main.c
index 241578058c0102e67181ec651d98195d6ee51d1b..42803050a68b41c8242502955024fd8969a4af05 100644 (file)
--- a/main.c
+++ b/main.c
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include <libgen.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <curl/curl.h>
 
@@ -9,6 +10,11 @@ const char* sofname = "odl";
 const char* version = "0.2.0";
 char* filename;
 
+int opt;
+int output_flag = 0;
+int version_flag = 0;
+int err_flag = 0;
+
 char* get_filename(const char* url) {
   char* fn_start = strrchr(url, '/');
   if (fn_start == NULL) {
@@ -71,52 +77,124 @@ int progress_callback(void *cp, double dt, double dn, double ut, double un) {
   return 0;
 }
 
+void handle_o(int argc, char* argv[]) {
+  output_flag = 1;
+  if (optind < argc) {
+    if (filename != NULL) {
+      fprintf(
+        stderr,
+        "-oをご利用する場合、1つのファイルだけをダウンロード出来ます。\n"
+      );
+    }
+    filename = argv[optind];
+  } else {
+    fprintf(stderr, "-oの後でファイル名がありません。");
+    err_flag = 1;
+  }
+}
+
+void flags(int opt, int argc, char* argv[]) {
+  switch (opt) {
+    case 'o':
+      handle_o(argc, argv);
+      break;
+    case 'v':
+      version_flag = 1;
+      break;
+    default:
+      err_flag = 1;
+      printf("usage: %s-%s [-ov] [url ...]\n", sofname, version);
+      break;
+  }
+}
+
+int downloader(CURL* curl, char* filename, const char* url) {
+  curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
+  curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
+
+  FILE* file = fopen(filename, "wb");
+  if (!file) {
+    perror("ファイルを開けません。");
+    curl_easy_cleanup(curl);
+    return -1;
+  }
+
+  curl_easy_setopt(curl, CURLOPT_URL, url);
+  curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
+  CURLcode res = curl_easy_perform(curl);
+  fclose(file);
+
+  if (res != CURLE_OK) {
+    fprintf(stderr, "\nダウンロードに失敗: %s\n", curl_easy_strerror(res));
+    curl_easy_cleanup(curl);
+    return -1;
+  }
+
+  printf("\n");
+
+  return 0;
+}
+
 int main(int argc, char* argv[]) {
   if (argc < 2) {
-    printf("usage: %s-%s [url ...]\n", sofname, version);
+    printf("usage: %s-%s [-ov] [url ...]\n", sofname, version);
     return 1;
   }
 
+  while ((opt = getopt(argc, argv, "ov")) != -1) {
+    flags(opt, argc, argv);
+  }
+
+  if (err_flag == 1) {
+    return 1;
+  }
+
+  if (version_flag == 1) {
+    printf("%s-%s\n", sofname, version);
+    return 0;
+  }
+
   CURL* curl = curl_easy_init();
   if (!curl) {
     perror("curlを初期設置に失敗。");
     return -1;
   }
 
-  for (int i = 1; i < argc; i++) {
-    const char* url = argv[i];
-    filename = get_filename(url);
+  // 一つのファイルだけが可能
+  if (output_flag == 1) {
+    if (optind >= argc) {
+      fprintf(stderr, "-oの後でURLがありません。");
+      return 1;
+    }
+
     if (filename == NULL) {
-      fprintf(stderr, "URLからファイル名を抽出出来ませんでした。\n");
-      continue;
+      fprintf(stderr, "-oの後でファイル名がありません。");
+      return 1;
     }
 
-    curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
-    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
+    filename = argv[optind];
+    const char* url = argv[optind+1];
+    downloader(curl, filename, url);
 
-    FILE* file = fopen(filename, "wb");
-    if (!file) {
-      curl_easy_cleanup(curl);
-      perror("ファイルを開けません。");
-      return -1;
-    }
+    curl_easy_cleanup(curl);
+    printf("\nダウンロードに完了しました。\n");
 
-    curl_easy_setopt(curl, CURLOPT_URL, url);
-    curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
-    CURLcode res = curl_easy_perform(curl);
-    fclose(file);
+    return 0;
+  }
 
-    if (res != CURLE_OK) {
-      curl_easy_cleanup(curl);
-      fprintf(stderr, "ダウンロードに失敗: %s\n", curl_easy_strerror(res));
-      return -1;
+  // 複数ファイル名可能
+  for (int i = optind; i < argc; i++) {
+    const char* url = argv[i];
+    filename = get_filename(url);
+    if (filename == NULL) {
+      fprintf(stderr, "URLからファイル名を抽出出来ませんでした。\n");
+      continue;
     }
 
-    printf("\n");
+    downloader(curl, filename, url);
   }
 
   curl_easy_cleanup(curl);
-
   printf("\nダウンロードに完了しました。\n");
 
   return 0;