source: trunk/utils/create.c @ 14615

Last change on this file since 14615 was 14615, checked in by jordan, 6 years ago

fix const warnings

In particular, in passing argv around as a "const char * const *"
instead of a "const char *".

  • Property svn:keywords set to Date Rev Author Id
File size: 5.4 KB
Line 
1/*
2 * This file Copyright (C) 2012-2014 Mnemosyne LLC
3 *
4 * It may be used under the GNU GPL versions 2 or 3
5 * or any future license endorsed by Mnemosyne LLC.
6 *
7 * $Id: create.c 14615 2015-12-06 22:39:14Z jordan $
8 */
9
10#include <stdio.h> /* fprintf() */
11#include <stdlib.h> /* strtoul(), EXIT_FAILURE */
12
13#include <libtransmission/transmission.h>
14#include <libtransmission/error.h>
15#include <libtransmission/file.h>
16#include <libtransmission/makemeta.h>
17#include <libtransmission/tr-getopt.h>
18#include <libtransmission/utils.h>
19#include <libtransmission/version.h>
20
21#include "units.h"
22
23#define MY_NAME "transmission-create"
24
25#define MAX_TRACKERS 128
26static const uint32_t KiB = 1024;
27static tr_tracker_info trackers[MAX_TRACKERS];
28static int trackerCount = 0;
29static bool isPrivate = false;
30static bool showVersion = false;
31static const char * comment = NULL;
32static const char * outfile = NULL;
33static const char * infile = NULL;
34static uint32_t piecesize_kib = 0;
35
36static tr_option options[] =
37{
38  { 'p', "private", "Allow this torrent to only be used with the specified tracker(s)", "p", 0, NULL },
39  { 'o', "outfile", "Save the generated .torrent to this filename", "o", 1, "<file>" },
40  { 's', "piecesize", "Set how many KiB each piece should be, overriding the preferred default", "s", 1, "<size in KiB>" },
41  { 'c', "comment", "Add a comment", "c", 1, "<comment>" },
42  { 't', "tracker", "Add a tracker's announce URL", "t", 1, "<url>" },
43  { 'V', "version", "Show version number and exit", "V", 0, NULL },
44  { 0, NULL, NULL, NULL, 0, NULL }
45};
46
47static const char *
48getUsage (void)
49{
50  return "Usage: " MY_NAME " [options] <file|directory>";
51}
52
53static int
54parseCommandLine (int argc, const char * const * argv)
55{
56  int c;
57  const char * optarg;
58
59  while ((c = tr_getopt (getUsage (), argc, argv, options, &optarg)))
60    {
61      switch (c)
62        {
63          case 'V':
64            showVersion = true;
65            break;
66
67          case 'p':
68            isPrivate = true;
69            break;
70
71          case 'o':
72            outfile = optarg;
73            break;
74
75          case 'c':
76            comment = optarg;
77            break;
78
79          case 't':
80            if (trackerCount + 1 < MAX_TRACKERS)
81              {
82                trackers[trackerCount].tier = trackerCount;
83                trackers[trackerCount].announce = (char*) optarg;
84                  ++trackerCount;
85              }
86            break;
87
88          case 's':
89            if (optarg)
90              {
91                char * endptr = NULL;
92                piecesize_kib = strtoul (optarg, &endptr, 10);
93                if (endptr && *endptr=='M')
94                  piecesize_kib *= KiB;
95              }
96            break;
97
98          case TR_OPT_UNK:
99            infile = optarg;
100            break;
101
102          default:
103            return 1;
104        }
105    }
106
107  return 0;
108}
109
110static char*
111tr_getcwd (void)
112{
113  char * result;
114  tr_error * error = NULL;
115
116  result = tr_sys_dir_get_current (&error);
117
118  if (result == NULL)
119    {
120      fprintf (stderr, "getcwd error: \"%s\"", error->message);
121      tr_error_free (error);
122      result = tr_strdup ("");
123    }
124
125  return result;
126}
127
128int
129tr_main (int    argc,
130         char * argv[])
131{
132  char * out2 = NULL;
133  tr_metainfo_builder * b = NULL;
134
135  tr_logSetLevel (TR_LOG_ERROR);
136  tr_formatter_mem_init (MEM_K, MEM_K_STR, MEM_M_STR, MEM_G_STR, MEM_T_STR);
137  tr_formatter_size_init (DISK_K, DISK_K_STR, DISK_M_STR, DISK_G_STR, DISK_T_STR);
138  tr_formatter_speed_init (SPEED_K, SPEED_K_STR, SPEED_M_STR, SPEED_G_STR, SPEED_T_STR);
139
140  if (parseCommandLine (argc, (const char* const *)argv))
141    return EXIT_FAILURE;
142
143  if (showVersion)
144    {
145      fprintf (stderr, MY_NAME" "LONG_VERSION_STRING"\n");
146      return EXIT_SUCCESS;
147    }
148
149  if (!infile)
150    {
151      fprintf (stderr, "ERROR: No input file or directory specified.\n");
152      tr_getopt_usage (MY_NAME, getUsage (), options);
153      fprintf (stderr, "\n");
154      return EXIT_FAILURE;
155    }
156
157  if (outfile == NULL)
158    {
159      char * base = tr_sys_path_basename (infile, NULL);
160      char * end = tr_strdup_printf ("%s.torrent", base);
161      char * cwd = tr_getcwd ();
162      outfile = out2 = tr_buildPath (cwd, end, NULL);
163      tr_free (cwd);
164      tr_free (end);
165      tr_free (base);
166    }
167
168  if (!trackerCount)
169    {
170      if (isPrivate)
171        {
172          fprintf (stderr, "ERROR: no trackers specified for a private torrent\n");
173          return EXIT_FAILURE;
174        }
175        else
176        {
177          printf ("WARNING: no trackers specified\n");
178        }
179    }
180
181  printf ("Creating torrent \"%s\" ...", outfile);
182  fflush (stdout);
183
184  b = tr_metaInfoBuilderCreate (infile);
185
186  if (piecesize_kib != 0)
187    tr_metaInfoBuilderSetPieceSize (b, piecesize_kib * KiB);
188
189  tr_makeMetaInfo (b, outfile, trackers, trackerCount, comment, isPrivate);
190  while (!b->isDone)
191    {
192      tr_wait_msec (500);
193      putc ('.', stdout);
194      fflush (stdout);
195    }
196
197  putc (' ', stdout);
198  switch (b->result)
199    {
200      case TR_MAKEMETA_OK:
201        printf ("done!");
202        break;
203
204      case TR_MAKEMETA_URL:
205        printf ("bad announce URL: \"%s\"", b->errfile);
206        break;
207
208      case TR_MAKEMETA_IO_READ:
209        printf ("error reading \"%s\": %s", b->errfile, tr_strerror (b->my_errno));
210        break;
211
212      case TR_MAKEMETA_IO_WRITE:
213        printf ("error writing \"%s\": %s", b->errfile, tr_strerror (b->my_errno));
214        break;
215
216      case TR_MAKEMETA_CANCELLED:
217        printf ("cancelled");
218        break;
219    }
220  putc ('\n', stdout);
221
222  tr_metaInfoBuilderFree (b);
223  tr_free (out2);
224  return EXIT_SUCCESS;
225}
Note: See TracBrowser for help on using the repository browser.