tcp: Fix 64 bit build with debugging features enabled.
[haiku.git] / src / bin / settype.cpp
blob41047341e7b1a14b5c63f79931aaf53fc83120dd
1 /*
2 * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
3 * Distributed under the terms of the MIT License.
4 */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
10 #include <AppFileInfo.h>
11 #include <Mime.h>
13 static const char *kCommandName = "settype";
15 static int kArgc;
16 static const char *const *kArgv;
18 // usage
19 const char *kUsage =
20 "Usage: %s <options> <file> ...\n"
21 "\n"
22 "Sets the MIME type, signature, and/or preferred application of one or more\n"
23 "files.\n"
24 "\n"
25 "Options:\n"
26 " -h, --help\n"
27 " - Print this help text and exit.\n"
28 " -preferredAppSig <signature>\n"
29 " - Set the preferred application of the given files to\n"
30 " <signature>.\n"
31 " -s <signature>\n"
32 " - Set the application signature of the given files to\n"
33 " <signature>.\n"
34 " -t <type>\n"
35 " - Set the MIME type of the given files to <type>.\n"
38 // print_usage
39 static void
40 print_usage(bool error)
42 // get command name
43 const char *commandName = NULL;
44 if (kArgc > 0) {
45 if (const char *lastSlash = strchr(kArgv[0], '/'))
46 commandName = lastSlash + 1;
47 else
48 commandName = kArgv[0];
51 if (!commandName || strlen(commandName) == 0)
52 commandName = kCommandName;
54 // print usage
55 fprintf((error ? stderr : stdout), kUsage, commandName, commandName,
56 commandName);
59 // print_usage_and_exit
60 static void
61 print_usage_and_exit(bool error)
63 print_usage(error);
64 exit(error ? 1 : 0);
67 // next_arg
68 static const char *
69 next_arg(int &argi, bool optional = false)
71 if (argi >= kArgc) {
72 if (!optional)
73 print_usage_and_exit(true);
74 return NULL;
77 return kArgv[argi++];
80 // check_mime_type
81 static void
82 check_mime_type(const char *type)
84 // check type
85 if (type) {
86 if (!BMimeType::IsValid(type)) {
87 fprintf(stderr, "\"%s\" is no valid MIME type.\n", type);
89 exit(1);
94 // main
95 int
96 main(int argc, const char *const *argv)
98 kArgc = argc;
99 kArgv = argv;
101 // parameters
102 const char **files = new const char*[argc];
103 int fileCount = 0;
104 const char *type = NULL;
105 const char *signature = NULL;
106 const char *preferredApp = NULL;
108 // parse the arguments
109 for (int argi = 1; argi < argc; ) {
110 const char *arg = argv[argi++];
111 if (arg[0] == '-') {
112 if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
113 print_usage_and_exit(false);
115 } else if (strcmp(arg, "-preferredAppSig") == 0) {
116 preferredApp = next_arg(argi);
118 } else if (strcmp(arg, "-s") == 0) {
119 signature = next_arg(argi);
121 } else if (strcmp(arg, "-t") == 0) {
122 type = next_arg(argi);
124 } else {
125 fprintf(stderr, "Error: Invalid option: \"%s\"\n", arg);
126 print_usage_and_exit(true);
128 } else {
129 // file
130 files[fileCount++] = arg;
134 // check parameters
135 if (!preferredApp && !signature && !type) {
136 fprintf(stderr, "Error: At least one option of \"-preferredAppSig\", "
137 "\"-s\", and \"-t\" must be given.\n");
138 print_usage_and_exit(true);
141 if (fileCount == 0) {
142 fprintf(stderr, "Error: No file specified.\n");
143 print_usage_and_exit(true);
146 // check for valid MIME types
147 check_mime_type(preferredApp);
148 check_mime_type(type);
149 check_mime_type(signature);
151 // iterate through the files
152 for (int i = 0; i < fileCount; i++) {
153 const char *fileName = files[i];
155 // check, whether the file exists
156 BEntry entry;
157 status_t error = entry.SetTo(fileName, false);
158 if (error != B_OK) {
159 fprintf(stderr, "Error: Can't access file \"%s\": %s\n",
160 fileName, strerror(error));
162 exit(1);
165 if (!entry.Exists()) {
166 fprintf(stderr, "Error: \"%s\": No such file or directory.\n",
167 fileName);
169 exit(1);
172 // ... and has the right type
173 if (signature && !entry.IsFile()) {
174 fprintf(stderr, "Error: \"%s\" is not a file. Signatures can only "
175 "be set for executable files.\n", fileName);
177 exit(1);
180 // open the file
181 BFile file;
182 BNode _node;
183 BNode &node = (signature ? file : _node);
184 error = (signature ? file.SetTo(fileName, B_READ_WRITE)
185 : node.SetTo(fileName));
186 if (error != B_OK) {
187 fprintf(stderr, "Error: Failed to open file \"%s\": %s\n",
188 fileName, strerror(error));
190 exit(1);
193 // prepare an node/app info object
194 BAppFileInfo appInfo;
195 BNodeInfo _nodeInfo;
196 BNodeInfo &nodeInfo = (signature ? appInfo : _nodeInfo);
197 error = (signature ? appInfo.SetTo(&file) : nodeInfo.SetTo(&node));
198 if (error != B_OK) {
199 fprintf(stderr, "Error: Failed to open file \"%s\": %s\n",
200 fileName, strerror(error));
202 exit(1);
205 // set preferred app
206 if (preferredApp) {
207 error = nodeInfo.SetPreferredApp(preferredApp);
208 if (error != B_OK) {
209 fprintf(stderr, "Error: Failed to set the preferred "
210 "application of file \"%s\": %s\n", fileName,
211 strerror(error));
213 exit(1);
217 // set type
218 if (type) {
219 error = nodeInfo.SetType(type);
220 if (error != B_OK) {
221 fprintf(stderr, "Error: Failed to set the MIME type of file "
222 "\"%s\": %s\n", fileName, strerror(error));
224 exit(1);
228 // set signature
229 if (signature) {
230 error = appInfo.SetSignature(signature);
231 if (error != B_OK) {
232 fprintf(stderr, "Error: Failed to set the signature of file "
233 "\"%s\": %s\n", fileName, strerror(error));
235 exit(1);
240 return 0;