vfs: check userland buffers before reading them.
[haiku.git] / src / bin / package / command_info.cpp
blob301e358ef2f00b919baa9463496d9503289f9afb
1 /*
2 * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include <getopt.h>
8 #include <stdio.h>
9 #include <string.h>
11 #include <Entry.h>
12 #include <package/PackageInfo.h>
14 #include "package.h"
17 using namespace BPackageKit;
20 int
21 command_info(int argc, const char* const* argv)
23 const char* format = "name: %name% version: %version%\n";
25 while (true) {
26 static struct option sLongOptions[] = {
27 { "format", required_argument, 0, 'f' },
28 { "help", no_argument, 0, 'h' },
29 { 0, 0, 0, 0 }
32 opterr = 0; // don't print errors
33 int c = getopt_long(argc, (char**)argv, "f:h", sLongOptions, NULL);
34 if (c == -1)
35 break;
37 switch (c) {
38 case 'f':
39 format = optarg;
40 break;
42 default:
43 print_usage_and_exit(true);
44 break;
48 // One argument should remain -- the package file name.
49 if (optind + 1 != argc)
50 print_usage_and_exit(true);
52 const char* fileName = argv[optind++];
54 // Read the package info from the package file. If it doesn't look like a
55 // package file, assume it is a package info file.
56 BPackageInfo info;
57 if (BString(fileName).EndsWith(".hpkg")) {
58 status_t error = info.ReadFromPackageFile(fileName);
59 if (error != B_OK) {
60 fprintf(stderr, "Error: Failed to read package file \"%s\": %s\n",
61 fileName, strerror(error));
62 return 1;
64 } else {
65 status_t error = info.ReadFromConfigFile(BEntry(fileName));
66 if (error != B_OK) {
67 fprintf(stderr, "Error: Failed to read package info file \"%s\": "
68 "%s\n", fileName, strerror(error));
69 return 1;
73 // parse format string and produce output
74 BString output;
75 while (*format != '\0') {
76 char c = *format++;
77 switch (c) {
78 case '%':
80 const char* start = format;
81 while (*format != '\0' && *format != '%')
82 format++;
83 if (*format != '%') {
84 fprintf(stderr, "Error: Unexpected at end of the format "
85 "string. Expected \"%%\".\n");
86 return 1;
89 if (format == start) {
90 output << '%';
91 } else {
92 BString variable(start, format - start);
93 if (variable == "fileName") {
94 output << info.CanonicalFileName();
95 } else if (variable == "name") {
96 output << info.Name();
97 } else if (variable == "version") {
98 output << info.Version().ToString();
99 } else {
100 fprintf(stderr, "Error: Unsupported placeholder \"%s\" "
101 "in format string.\n", variable.String());
102 return 1;
106 format++;
107 break;
110 case '\\':
111 c = *format++;
112 if (c == '\0') {
113 fprintf(stderr, "Error: \"\\\" at the end of the format "
114 "string.\n");
115 return 1;
117 switch (c) {
118 case 'n':
119 c = '\n';
120 break;
121 case 't':
122 c = '\t';
123 break;
125 // fall through
127 default:
128 output << c;
129 break;
133 fputs(output.String(), stdout);
135 return 0;