source: trunk/utils/create.c @ 11865

Last change on this file since 11865 was 11865, checked in by jordan, 11 years ago

(trunk) improvement to r11864

Since the contents of getcwd() are undefined on error, explicitly terminate the buffer string if getcwd() fails.

  • Property svn:keywords set to Date Rev Author Id
File size: 4.6 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 11865 2011-02-09 06:10:01Z jordan $
11 */
12
13#include <errno.h>
14#include <stdio.h>
15#include <unistd.h> /* getcwd() */
16
17#include <libtransmission/transmission.h>
18#include <libtransmission/makemeta.h>
19#include <libtransmission/tr-getopt.h>
20#include <libtransmission/utils.h>
21#include <libtransmission/version.h>
22
23#define MY_NAME "transmission-create"
24
25#define MAX_TRACKERS 128
26static tr_tracker_info trackers[MAX_TRACKERS];
27static int trackerCount = 0;
28static tr_bool isPrivate = FALSE;
29static tr_bool showVersion = FALSE;
30const char * comment = NULL;
31const char * outfile = NULL;
32const char * infile = NULL;
33
34static tr_option options[] =
35{
36  { 'p', "private", "Allow this torrent to only be used with the specified tracker(s)", "p", 0, NULL },
37  { 'o', "outfile", "Save the generated .torrent to this filename", "o", 1, "<file>" },
38  { 'c', "comment", "Add a comment", "c", 1, "<comment>" },
39  { 't', "tracker", "Add a tracker's announce URL", "t", 1, "<url>" },
40  { 'V', "version", "Show version number and exit", "V", 0, NULL },
41  { 0, NULL, NULL, NULL, 0, NULL }
42};
43
44static const char *
45getUsage( void )
46{
47    return "Usage: " MY_NAME " [options] <file|directory>";
48}
49
50static int
51parseCommandLine( int argc, const char ** argv )
52{
53    int c;
54    const char * optarg;
55
56    while(( c = tr_getopt( getUsage( ), argc, argv, options, &optarg )))
57    {
58        switch( c )
59        {
60            case 'V': showVersion = TRUE; break;
61            case 'p': isPrivate = TRUE; break;
62            case 'o': outfile = optarg; break;
63            case 'c': comment = optarg; break;
64            case 't': if( trackerCount + 1 < MAX_TRACKERS ) {
65                          trackers[trackerCount].tier = trackerCount;
66                          trackers[trackerCount].announce = (char*) optarg;
67                          ++trackerCount;
68                      }
69                      break;
70            case TR_OPT_UNK: infile = optarg; break;
71            default: return 1;
72        }
73    }
74
75    return 0;
76}
77
78static char*
79tr_getcwd( void )
80{
81    char * result;
82    char buf[2048];
83#ifdef WIN32
84    result = _getcwd( buf, sizeof( buf ) );
85#else
86    result = getcwd( buf, sizeof( buf ) );
87#endif
88    if( result == NULL ) 
89    {
90        fprintf( stderr, "getcwd error: \"%s\"", tr_strerror( errno ) );
91        *buf = '\0';
92    }
93    return tr_strdup( buf );
94}
95
96int
97main( int argc, char * argv[] )
98{
99    char * out2 = NULL;
100    tr_metainfo_builder * b = NULL;
101
102    tr_setMessageLevel( TR_MSG_ERR );
103
104    if( parseCommandLine( argc, (const char**)argv ) )
105        return EXIT_FAILURE;
106
107    if( showVersion ) {
108        fprintf( stderr, MY_NAME" "LONG_VERSION_STRING"\n" );
109        return 0;
110    }
111
112    if( !infile )
113    {
114        fprintf( stderr, "ERROR: No input file or directory specified.\n" );
115        tr_getopt_usage( MY_NAME, getUsage( ), options );
116        fprintf( stderr, "\n" );
117        return EXIT_FAILURE;
118    }
119
120    if( outfile == NULL )
121    {
122        char * base = tr_basename( infile );
123        char * end = tr_strdup_printf( "%s.torrent", base );
124        char * cwd = tr_getcwd( );
125        outfile = out2 = tr_buildPath( cwd, end, NULL );
126        tr_free( cwd );
127        tr_free( end );
128        tr_free( base );
129    }
130
131    if( !trackerCount )
132    {
133        if( isPrivate )
134        {
135            fprintf( stderr, "ERROR: no trackers specified for a private torrent\n" );
136            return EXIT_FAILURE;
137        }
138        else
139        {
140            printf( "WARNING: no trackers specified\n" );
141        }
142    }
143
144    printf( "Creating torrent \"%s\" ...", outfile );
145    fflush( stdout );
146
147    b = tr_metaInfoBuilderCreate( infile );
148    tr_makeMetaInfo( b, outfile, trackers, trackerCount, comment, isPrivate );
149    while( !b->isDone ) {
150        tr_wait_msec( 500 );
151        putc( '.', stdout );
152        fflush( stdout );
153    }
154
155    putc( ' ', stdout );
156    switch( b->result ) {
157        case TR_MAKEMETA_OK:        printf( "done!" ); break;
158        case TR_MAKEMETA_URL:       printf( "bad announce URL: \"%s\"", b->errfile ); break;
159        case TR_MAKEMETA_IO_READ:   printf( "error reading \"%s\": %s", b->errfile, tr_strerror(b->my_errno) ); break;
160        case TR_MAKEMETA_IO_WRITE:  printf( "error writing \"%s\": %s", b->errfile, tr_strerror(b->my_errno) ); break;
161        case TR_MAKEMETA_CANCELLED: printf( "cancelled" ); break;
162    }
163    putc( '\n', stdout );
164
165    tr_metaInfoBuilderFree( b );
166    tr_free( out2 );
167    return 0;
168}
Note: See TracBrowser for help on using the repository browser.