├── .gitignore ├── Makefile ├── README.md └── transfer.c /.gitignore: -------------------------------------------------------------------------------- 1 | transfer -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # SPDX-License-Identifier: GPL-3.0-or-later 3 | # 4 | # Copyright (C) 2018, Harshit Jain 5 | # 6 | 7 | CFLAGS="-DGET_FILE_SIZE" "-Wall" "-DPROGRESS_BAR" "-DUPLOAD_MULTIPLE" 8 | 9 | CC ?= gcc 10 | CLANG_FORMAT ?= clang-format 11 | OPT_LEVEL ?= -O2 12 | 13 | default: transfer 14 | 15 | transfer.o: transfer.c 16 | $(CC) $(CFLAGS) $(OPT_LEVEL) -c transfer.c -o transfer.o 17 | 18 | transfer: transfer.o 19 | $(CC) $(CFLAGS) transfer.o -o transfer 20 | -rm -f transfer.o 21 | 22 | clean: 23 | @-rm -f transfer.o transfer 24 | @echo "[~] Cleaned Successfully" 25 | 26 | clang-format: 27 | @$(CLANG_FORMAT) -style='{IndentWidth: 4}' -i transfer.c 28 | @echo "[~] Source code formatted" 29 | 30 | install: transfer 31 | sudo mv transfer /usr/local/bin/ 32 | @echo "\033[01;33mNow you can use transfer binary with command line" 33 | @echo "Example: transfer myfile.txt\033[0m" 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Transfer [![Codacy Badge](https://api.codacy.com/project/badge/Grade/edcd58027a3e412d90ce3cd98917d547)](https://app.codacy.com/app/dev-harsh1998/Transfer?utm_source=github.com&utm_medium=referral&utm_content=dev-harsh1998/Transfer&utm_campaign=Badge_Grade_Dashboard) [ ![Codeship Status for dev-harsh1998/Transfer](https://app.codeship.com/projects/6cfba370-60d1-0136-95b6-3296b091a39e/status?branch=master)](https://app.codeship.com/projects/296378) 2 | 3 | 4 | 5 | Transfer is a command line utility built as a wrapper around cURL for one purpose - Uploading files to [transfer.sh](https://transfer.sh). It abstracts away all the manual cURL syntax to make usage effortless. 6 | This utility even has the ability to upload multiple files with a single command or you can just use it to 7 | upload one, Transfer can adapt to your fingers. 8 | 9 | ## How to use? 10 | 11 | ``` 12 | $ transfer myfile.file myflile2.flie ... 13 | https://transfer.sh/t9a5Q/myfile.file 14 | https://transfer.sh/ab069/myfile2.file 15 | .. 16 | ``` 17 | 18 | ## Installation 19 | You can simply install transfer by following these instructions, make sure you have `git` and `curl` installed. 20 | 21 | ``` 22 | # Clone the repository. 23 | git clone https://github.com/dev-harsh1998/Transfer 24 | # Navigate to cloned directory. 25 | cd Transfer 26 | # Compile latest binary on your own machine!!. 27 | make transfer 28 | # Install it for direct access. 29 | sudo make install 30 | ``` 31 | 32 | Additionally you can supply parameters to change the compiler and optimisation level, like `CC=clang OPT_LEVEL=-O3 make transfer` 33 | 34 | 35 | BOOM! Easy right? There you are done you have successfully built and installed transfer on your machine. 36 | 37 | ## Supported Platforms 38 | - Linux x86 39 | - Linux x86_64 40 | - macOS 41 | 42 | ## Issue or feature request? 43 | 44 | Please write about issues and feature request [here](https://github.com/dev-harsh1998/Transfer/issues). 45 | -------------------------------------------------------------------------------- /transfer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: GPL-3.0-or-later 3 | * 4 | * Copyright (C) 2019, Harshit Jain 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #ifdef GET_FILE_SIZE 14 | /* ISSUE 1 File size */ 15 | #include 16 | #include 17 | #endif 18 | 19 | static inline char uploader(char s[]) { return system(s); } 20 | 21 | /* Implementation based on popen documentation */ 22 | static bool can_run_command(const char *cmd) { 23 | if (strchr(cmd, '/')) { 24 | // if cmd includes a slash, no path search must be performed, 25 | // go straight to checking if it's executable 26 | 27 | /* ************************************** */ 28 | // For current linux based systems this check is useless 29 | // but would rather be used when implementing this for windows 30 | // powershell. 31 | /* ************************************** */ 32 | 33 | return access(cmd, X_OK) == 0; 34 | } 35 | const char *path = getenv("PATH"); 36 | if (!path) 37 | return false; // something is horribly wrong... 38 | // we are sure we won't need a buffer any longer 39 | char *buf = malloc(strlen(path) + strlen(cmd) + 3); 40 | if (!buf) 41 | return false; // actually useless, see comment 42 | // loop as long as we have stuff to examine in path 43 | for (; *path; ++path) { 44 | // start from the beginning of the buffer 45 | char *p = buf; 46 | // copy in buf the current path element 47 | for (; *path && *path != ':'; ++path, ++p) { 48 | *p = *path; 49 | } 50 | // empty path entries are treated like "." 51 | if (p == buf) 52 | *p++ = '.'; 53 | // slash and command name 54 | if (p[-1] != '/') 55 | *p++ = '/'; 56 | strcpy(p, cmd); 57 | // check if we can execute it 58 | if (access(buf, X_OK) == 0) { 59 | free(buf); 60 | return true; 61 | } 62 | // quit at last cycle 63 | if (!*path) 64 | break; 65 | } 66 | // not found 67 | free(buf); 68 | return false; 69 | } 70 | 71 | int main(int argc, char *argv[]) { 72 | /* Linux curl check */ 73 | const char curl[5] = "curl"; 74 | static bool x; 75 | 76 | #ifdef UPLOAD_MULTIPLE 77 | int holder = argc; 78 | int q; 79 | #endif 80 | 81 | x = can_run_command(curl); 82 | /* Only run the uploader when curl binary is found & is executable */ 83 | if (x) { 84 | 85 | #ifdef UPLOAD_MULTIPLE 86 | /* Argument check */ 87 | if (argc <= 1) { 88 | printf("ERROR: This binary expects atleast one command " 89 | "line argument\n"); 90 | /* bail out */ 91 | return -1; 92 | } 93 | if (argc > 2) { 94 | printf("The no of files that are going to be uploaded are %d\n", 95 | argc - 1); 96 | } 97 | printf("\n"); 98 | /* Display names of file (Ignore the first argument as its transfer 99 | * itself) */ 100 | for (q = 1; q < holder; q++) { 101 | printf("File no. %d is %s\n", q, argv[q]); 102 | } 103 | printf("\n"); 104 | printf("The above listed files would be uploaded now.\n\n"); 105 | #else 106 | /* Argument check */ 107 | if (argc != 2) { 108 | printf("ERROR: This binary expects atleast and only one command " 109 | "line argument\n"); 110 | /* bail out */ 111 | return -1; 112 | } 113 | #endif 114 | 115 | #ifdef GET_FILE_SIZE 116 | if (getenv("TRANSFER_DISABLE_FILESIZE") == NULL) { 117 | static struct stat st; 118 | #ifdef UPLOAD_MULTIPLE 119 | for (q = 1; q < holder; q++) { 120 | stat(argv[q], &st); 121 | const float mb = (float)st.st_size / 1048576; 122 | printf("The size of the %d file going to be uploaded is near " 123 | "to %.2f " 124 | "megabytes\n", 125 | q, mb); 126 | } 127 | } 128 | #else 129 | stat(argv[1], &st); 130 | // convert bytes to mb (devide by 1024*1024) 131 | const float mb = (float)st.st_size / 1048576; 132 | printf("The size of the file going to be uploaded is near to %.2f " 133 | "megabytes\n", 134 | mb); 135 | } 136 | #endif 137 | printf("\n"); 138 | #endif 139 | static char cmdbuf[256]; 140 | static int ret; 141 | 142 | #ifdef PROGRESS_BAR 143 | #ifdef UPLOAD_MULTIPLE 144 | for (q = 1; q < holder; q++) { 145 | sprintf(cmdbuf, "curl --progress-bar -T %s %s | tee /dev/null", 146 | argv[q], "https://transfer.sh"); 147 | ret = uploader(cmdbuf); 148 | printf("\n"); 149 | } 150 | #else 151 | sprintf(cmdbuf, "curl --progress-bar -T %s %s | tee /dev/null", argv[1], 152 | "https://transfer.sh"); 153 | ret = uploader(cmdbuf); 154 | #endif 155 | #else 156 | #ifdef UPLOAD_MULTIPLE 157 | for (q = 1; q < holder; q++) { 158 | sprintf(cmdbuf, "curl -T %s %s", argv[q], "https://transfer.sh"); 159 | ret = uploader(cmdbuf); 160 | printf("\n"); 161 | } 162 | #else 163 | sprintf(cmdbuf, "curl -T %s %s", argv[1], "https://transfer.sh"); 164 | ret = uploader(cmdbuf); 165 | #endif 166 | #endif 167 | return ret; 168 | } else { 169 | printf("Either curl binary is not installed or is corrupt somehow, " 170 | "This binary is based on curl and can't run without it\n"); 171 | printf("Install curl from source or with the package manager of your " 172 | "choice \n"); 173 | printf("ERROR\n"); 174 | return -1; 175 | } 176 | } 177 | --------------------------------------------------------------------------------