source: trunk/utils/create.c @ 13800

Last change on this file since 13800 was 13800, checked in by jordan, 8 years ago

(utils) #4137 'support user-defined piece sizes in transmission-create' -- done. Initial patch by lav.

  • Property svn:keywords set to Date Rev Author Id
File size: 5.3 KB
Line 
1/*
2 * This file Copyright (C) Mnemosyne LLC
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2
6 * as published by the Free Software Foundation.
7 *
8 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
9 *
10 * $Id: create.c 13800 2013-01-17 18:55:51Z jordan $
11 */
12
13#include <errno.h>
14#include <stdio.h> /* fprintf() */
15#include <stdlib.h> /* strtoul(), EXIT_FAILURE */
16#include <unistd.h> /* getcwd() */
17
18#include <libtransmission/transmission.h>
19#include <libtransmission/makemeta.h>
20#include <libtransmission/tr-getopt.h>
21#include <libtransmission/utils.h>
22#include <libtransmission/version.h>
23
24#define MY_NAME "transmission-create"
25
26#define MAX_TRACKERS 128
27static const uint32_t KiB = 1024;
28static tr_tracker_info trackers[MAX_TRACKERS];
29static int trackerCount = 0;
30static bool isPrivate = false;
31static bool showVersion = false;
32static const char * comment = NULL;
33static const char * outfile = NULL;
34static const char * infile = NULL;
35static uint32_t piecesize_kib = 0;
36
37static tr_option options[] =
38{
39  { 'p', "private", "Allow this torrent to only be used with the specified tracker(s)", "p", 0, NULL },
40  { 'o', "outfile", "Save the generated .torrent to this filename", "o", 1, "<file>" },
41  { 's', "piecesize", "Set how many KiB each piece should be, overriding the preferred default", "s", 1, "<size in KiB>" },
42  { 'c', "comment", "Add a comment", "c", 1, "<comment>" },
43  { 't', "tracker", "Add a tracker's announce URL", "t", 1, "<url>" },
44  { 'V', "version", "Show version number and exit", "V", 0, NULL },
45  { 0, NULL, NULL, NULL, 0, NULL }
46};
47
48static const char *
49getUsage (void)
50{
51  return "Usage: " MY_NAME " [options] <file|directory>";
52}
53
54static int
55parseCommandLine (int argc, const char ** argv)
56{
57  int c;
58  const char * optarg;
59
60  while ((c = tr_getopt (getUsage (), argc, argv, options, &optarg)))
61    {
62      switch (c)
63        {
64          case 'V':
65            showVersion = true;
66            break;
67
68          case 'p':
69            isPrivate = true;
70            break;
71
72          case 'o':
73            outfile = optarg;
74            break;
75
76          case 'c':
77            comment = optarg;
78            break;
79
80          case 't':
81            if (trackerCount + 1 < MAX_TRACKERS)
82              {
83                trackers[trackerCount].tier = trackerCount;
84                trackers[trackerCount].announce = (char*) optarg;
85                  ++trackerCount;
86              }
87            break;
88
89          case 's':
90            if (optarg) 
91              { 
92                char * endptr = NULL;
93                piecesize_kib = strtoul (optarg, &endptr, 10);
94                if (endptr && *endptr=='M')
95                  piecesize_kib *= KiB; 
96              }
97            break;
98
99          case TR_OPT_UNK:
100            infile = optarg;
101            break;
102
103          default:
104            return 1;
105        }
106    }
107
108  return 0;
109}
110
111static char*
112tr_getcwd (void)
113{
114  char * result;
115  char buf[2048];
116
117#ifdef WIN32
118  result = _getcwd (buf, sizeof (buf));
119#else
120  result = getcwd (buf, sizeof (buf));
121#endif
122
123  if (result == NULL)
124    {
125      fprintf (stderr, "getcwd error: \"%s\"", tr_strerror (errno));
126      *buf = '\0';
127    }
128
129  return tr_strdup (buf);
130}
131
132int
133main (int argc, char * argv[])
134{
135  char * out2 = NULL;
136  tr_metainfo_builder * b = NULL;
137
138  tr_setMessageLevel (TR_MSG_ERR);
139
140  if (parseCommandLine (argc, (const char**)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_basename (infile);
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.