1//----------------------------------------------------------------------
2//  This software is part of the OpenBeOS distribution and is covered
3//  by the OpenBeOS license.
4//
5//  Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net
6//----------------------------------------------------------------------
7
8/*! \file Shell.cpp
9
10	Command-line shell for makeudfimage
11*/
12
13#include "Shell.h"
14
15#include <stdio.h>
16
17#include "ConsoleListener.h"
18#include "UdfDebug.h"
19#include "UdfBuilder.h"
20
21Shell::Shell()
22	// The following settings are essentially default values
23	// for all the command-line options (except for the last
24	// three vars).
25	: fVerbosityLevel(VERBOSITY_LOW)
26	, fBlockSize(2048)
27	, fDoUdf(true)
28	, fDoIso(false)
29	, fSourceDirectory("")
30	, fOutputFile("")
31	, fUdfVolumeName("")
32	, fUdfRevision(0x0201)
33	, fTruncate(true)
34{
35}
36
37status_t
38Shell::Run(int argc, char *argv[])
39{
40	DEBUG_INIT("Shell");
41	status_t error = _ProcessArguments(argc, argv);
42	if (!error) {
43		if (fUdfVolumeName == "")
44			fUdfVolumeName = "(Unnamed UDF Volume)";
45		ConsoleListener listener(fVerbosityLevel);
46		UdfBuilder builder(fOutputFile.c_str(), fBlockSize, fDoUdf,
47		                   fUdfVolumeName.c_str(), fUdfRevision, fDoIso, "ISO_VOLUME",
48		                   fSourceDirectory.c_str(), listener, fTruncate);
49		error = builder.InitCheck();
50		if (!error)
51			error = builder.Build();
52	}
53
54	if (error)
55		_PrintHelp();
56
57	RETURN(error);
58}
59
60status_t
61Shell::_ProcessArguments(int argc, char *argv[]) {
62	DEBUG_INIT_ETC("Shell", ("argc: %d", argc));
63
64	// Throw all the arguments into a handy list
65	std::list<std::string> argumentList;
66	for (int i = 1; i < argc; i++)
67		argumentList.push_back(std::string(argv[i]));
68
69	bool foundSourceDirectory = false;
70	bool foundOutputFile = false;
71	bool foundUdfVolumeName = false;
72
73	// Now bust out some processing
74	int argumentCount = argumentList.size();
75	int index = 0;
76	for(std::list<std::string>::iterator i = argumentList.begin();
77	      i != argumentList.end();
78	      	)
79	{
80		std::string &arg = *i;
81		if (arg == "-h" || arg == "--help") {
82			_PrintTitle();
83			RETURN(B_ERROR);
84		} else if (arg == "-v0" || arg == "--quiet") {
85			fVerbosityLevel = VERBOSITY_NONE;
86		} else if (arg == "-v1") {
87			fVerbosityLevel = VERBOSITY_LOW;
88		} else if (arg == "-v2") {
89			fVerbosityLevel = VERBOSITY_MEDIUM;
90		} else if (arg == "-v3") {
91			fVerbosityLevel = VERBOSITY_HIGH;
92		} else if (arg == "-r" || arg == "--revision") {
93			i++;
94			index++;
95			if (*i == "1.50")
96				fUdfRevision = 0x0150;
97			else if (*i == "2.01")
98				fUdfRevision = 0x0201;
99			else {
100				printf("ERROR: invalid UDF revision `%s'; please specify `1.50' "
101				       "or `2.01'\n", i->c_str());
102				RETURN(B_ERROR);
103			}
104		} else if (arg == "-t" || arg == "--no-truncate") {
105			fTruncate = 0;
106		} else {
107			if (index == argumentCount-3) {
108				// Take this argument as the source dir
109				fSourceDirectory = arg;
110				foundSourceDirectory = true;
111			} else if (index == argumentCount-2) {
112				// Take this argument as the output filename
113				fOutputFile = arg;
114				foundOutputFile = true;
115			} else if (index == argumentCount-1) {
116				// Take this argument as the udf volume name
117				fUdfVolumeName = arg;
118				foundUdfVolumeName = true;
119			} else {
120				printf("ERROR: invalid argument `%s'\n", arg.c_str());
121				printf("\n");
122				RETURN(B_ERROR);
123			}
124		}
125		i++;
126		index++;
127	}
128
129	status_t error = B_OK;
130	if (!foundSourceDirectory) {
131		printf("ERROR: no source directory specified\n");
132		error = B_ERROR;
133	}
134	if (!foundOutputFile) {
135		printf("ERROR: no output file specified\n");
136		error = B_ERROR;
137	}
138	if (!foundUdfVolumeName) {
139		printf("ERROR: no volume name specified\n");
140		error = B_ERROR;
141	}
142
143	if (error)
144		printf("\n");
145	RETURN(error);
146}
147
148void
149Shell::_PrintHelp() {
150	printf("usage: makeudfimage [options] <source-directory> <output-file> <udf-volume-name>\n");
151	printf("example: makeudfimage /boot/home/mail mail.udf \"Mail Backup\"\n");
152	printf("\n");
153	printf("VALID OPTIONS:\n");
154	printf("  -h, --help                      Displays this help text.\n");
155	printf("  --quiet                         Turns off console output.\n");
156	printf("  -r, --revision <udf-revision>   Selects the UDF revision to use. Supported\n");
157	printf("                                  revisions are 1.50 and 2.01. Defaults to 2.01.\n");
158	printf("  -t, --no-trunc                  Don't truncate output file if it already\n");
159	printf("                                  exists.\n");
160	printf("\n");
161}
162
163#define MAKEUDFIMAGE_VERSION "1.0.0"
164#ifndef MAKEUDFIMAGE_VERSION
165#	define MAKEUDFIMAGE_VERSION ("development version " __DATE__ ", " __TIME__)
166#endif
167
168void
169Shell::_PrintTitle() {
170	printf("makeudfimage %s\n", MAKEUDFIMAGE_VERSION);
171	printf("Copyright © 2004 Tyler Dauwalder\n");
172	printf("\n");
173}
174