]> granicus.if.org Git - curl/commitdiff
Factored out some code into a few independent functions
authorDan Fandrich <dan@coneharvesters.com>
Tue, 16 Mar 2010 05:18:21 +0000 (05:18 +0000)
committerDan Fandrich <dan@coneharvesters.com>
Tue, 16 Mar 2010 05:18:21 +0000 (05:18 +0000)
src/main.c

index 8acf032feb565ce3dd61f69916567bc213981f98..a0096b7904df409a73a3ebb6f0042a98173420bb 100644 (file)
@@ -168,6 +168,7 @@ static int vms_show = 0;
 
 static const char *msdosify(const char *);
 static char *rename_if_dos_device_name(char *);
+static char *sanitize_dos_name(char *);
 
 #ifndef S_ISCHR
 #  ifdef S_IFCHR
@@ -4091,6 +4092,83 @@ static bool stdin_upload(const char *uploadfile)
                 curlx_strequal(uploadfile, "."));
 }
 
+/* Adds the file name to the URL if it doesn't already have one.
+ * url will be freed before return if the returned pointer is different
+ */
+static char *add_file_name_to_url(CURL *curl, char *url, const char *filename)
+{
+  /* If no file name part is given in the URL, we add this file name */
+  char *ptr=strstr(url, "://");
+  if(ptr)
+    ptr+=3;
+  else
+    ptr=url;
+  ptr = strrchr(ptr, '/');
+  if(!ptr || !strlen(++ptr)) {
+    /* The URL has no file name part, add the local file name. In order
+       to be able to do so, we have to create a new URL in another
+       buffer.*/
+
+    /* We only want the part of the local path that is on the right
+       side of the rightmost slash and backslash. */
+    const char *filep = strrchr(filename, '/');
+    char *file2 = strrchr(filep?filep:filename, '\\');
+    char *encfile;
+
+    if(file2)
+      filep = file2+1;
+    else if(filep)
+      filep++;
+    else
+      filep = filename;
+
+    /* URL encode the file name */
+    encfile = curl_easy_escape(curl, filep, 0 /* use strlen */);
+    if(encfile) {
+      char *urlbuffer = malloc(strlen(url) + strlen(encfile) + 3);
+      if(!urlbuffer) {
+        free(url);
+        return NULL;
+      }
+      if(ptr)
+        /* there is a trailing slash on the URL */
+        sprintf(urlbuffer, "%s%s", url, encfile);
+      else
+        /* there is no trailing slash on the URL */
+        sprintf(urlbuffer, "%s/%s", url, encfile);
+
+      curl_free(encfile);
+
+      free(url);
+      url = urlbuffer; /* use our new URL instead! */
+    }
+  }
+  return url;
+}
+
+/* Extracts the name portion of the URL.
+ * Returns a heap-allocated string, or NULL if no name part
+ */
+static char *get_url_file_name(const char *url)
+{
+  char *fn = NULL;
+
+  /* Find and get the remote file name */
+  const char * pc =strstr(url, "://");
+  if(pc)
+    pc+=3;
+  else
+    pc=url;
+  pc = strrchr(pc, '/');
+
+  if(pc) {
+    /* duplicate the string beyond the slash */
+    pc++;
+    fn = *pc ? strdup(pc): NULL;
+  }
+  return fn;
+}
+
 static char*
 parse_filename(char *ptr, int len)
 {
@@ -4539,19 +4617,8 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
            */
 
           if(!outfile) {
-            /* Find and get the remote file name */
-            char * pc =strstr(url, "://");
-            if(pc)
-              pc+=3;
-            else
-              pc=url;
-            pc = strrchr(pc, '/');
-
-            if(pc) {
-              /* duplicate the string beyond the slash */
-              pc++;
-              outfile = *pc ? strdup(pc): NULL;
-            }
+            /* extract the file name from the URL */
+            outfile = get_url_file_name(url);
             if((!outfile || !*outfile) && !config->content_disposition) {
               helpf(config->errors, "Remote file name has no length!\n");
               res = CURLE_WRITE_ERROR;
@@ -4559,20 +4626,12 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
               break;
             }
 #if defined(MSDOS) || defined(WIN32)
-            {
-              /* For DOS and WIN32, we do some major replacing of
-                 bad characters in the file name before using it */
-              char file1[PATH_MAX];
-              if(strlen(outfile) >= PATH_MAX)
-                outfile[PATH_MAX-1]=0; /* cut it */
-              strcpy(file1, msdosify(outfile));
-              free(outfile);
-
-              outfile = strdup(rename_if_dos_device_name(file1));
-              if(!outfile) {
-                res = CURLE_OUT_OF_MEMORY;
-                break;
-              }
+            /* For DOS and WIN32, we do some major replacing of
+             bad characters in the file name before using it */
+            outfile = sanitize_dos_name(outfile);
+            if(!outfile) {
+              res = CURLE_OUT_OF_MEMORY;
+              break;
             }
 #endif /* MSDOS || WIN32 */
           }
@@ -4639,53 +4698,11 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
            */
           struct_stat fileinfo;
 
-          /* If no file name part is given in the URL, we add this file name */
-          char *ptr=strstr(url, "://");
-          if(ptr)
-            ptr+=3;
-          else
-            ptr=url;
-          ptr = strrchr(ptr, '/');
-          if(!ptr || !strlen(++ptr)) {
-            /* The URL has no file name part, add the local file name. In order
-               to be able to do so, we have to create a new URL in another
-               buffer.*/
-
-            /* We only want the part of the local path that is on the right
-               side of the rightmost slash and backslash. */
-            char *filep = strrchr(uploadfile, '/');
-            char *file2 = strrchr(filep?filep:uploadfile, '\\');
-
-            if(file2)
-              filep = file2+1;
-            else if(filep)
-              filep++;
-            else
-              filep = uploadfile;
-
-            /* URL encode the file name */
-            filep = curl_easy_escape(curl, filep, 0 /* use strlen */);
-
-            if(filep) {
-              char *urlbuffer = malloc(strlen(url) + strlen(filep) + 3);
-              if(!urlbuffer) {
-                helpf(config->errors, "out of memory\n");
-                free(url);
-                res = CURLE_OUT_OF_MEMORY;
-                break;
-              }
-              if(ptr)
-                /* there is a trailing slash on the URL */
-                sprintf(urlbuffer, "%s%s", url, filep);
-              else
-                /* there is no trailing slash on the URL */
-                sprintf(urlbuffer, "%s/%s", url, filep);
-
-              curl_free(filep);
-
-              free(url);
-              url = urlbuffer; /* use our new URL instead! */
-            }
+          url = add_file_name_to_url(curl, url, uploadfile);
+          if(!url) {
+            helpf(config->errors, "out of memory\n");
+            res = CURLE_OUT_OF_MEMORY;
+            break;
           }
           /* VMS Note:
            *
@@ -5782,7 +5799,7 @@ rename_if_dos_device_name (char *file_name)
 
   strncpy(fname, file_name, PATH_MAX-1);
   fname[PATH_MAX-1] = 0;
-  base = basename (fname);
+  base = basename(fname);
   if (((stat(base, &st_buf)) == 0) && (S_ISCHR(st_buf.st_mode))) {
     size_t blen = strlen (base);
 
@@ -5798,4 +5815,17 @@ rename_if_dos_device_name (char *file_name)
   }
   return file_name;
 }
+
+/* Replace bad characters in the file name before using it.
+ * fn will always be freed before return
+ * The returned pointer must be freed by the caller if not NULL
+ */
+static char *sanitize_dos_name(char *fn)
+{
+  char tmpfn[PATH_MAX];
+  fn[PATH_MAX-1]=0; /* ensure fn is not too long by possibly truncating it */
+  strcpy(tmpfn, msdosify(fn));
+  free(fn);
+  return strdup(rename_if_dos_device_name(tmpfn));
+}
 #endif /* MSDOS || WIN32 */