xref: /haiku/src/bin/version.cpp (revision 93a78ecaa45114d68952d08c4778f073515102f2)
1 /*
2  * Copyright 2002-2007, Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Ryan Fleet
7  *		Vasilis Kaoutsis
8  */
9 
10 
11 #include <Application.h>
12 #include <AppFileInfo.h>
13 
14 #include <stdio.h>
15 #include <string.h>
16 
17 
18 void
19 usage()
20 {
21 	printf("usage: version [OPTION] FILENAME [FILENAME2, ...]\n"
22 		"Returns the version of a file.\n\n"
23 		"        -h, --help              this usage message\n"
24 		"        -l, --long              print long version information of FILENAME\n"
25 		"        -n, --numerical         print in numerical mode\n"
26 		"                                (Major miDdle miNor Variety Internal)\n"
27 		"        -s, --system            print system version instead of app version\n"
28 		"        --version               print version information for this command\n");
29 }
30 
31 
32 status_t
33 get_version(const char *filename, version_kind kind, bool longFlag, bool numericalFlag)
34 {
35 	BFile file(filename, O_RDONLY);
36 	if (file.InitCheck() != B_OK) {
37 		printf("Couldn't get file info!\n");
38 		return B_FILE_ERROR;
39 	}
40 
41 	BAppFileInfo info(&file);
42 	if (info.InitCheck() != B_OK) {
43 		printf("Couldn't get file info!\n");
44 		return B_FILE_ERROR;
45 	}
46 
47 	version_info version;
48 	if (info.GetVersionInfo(&version, kind) != B_OK) {
49 		printf("Version unknown!\n");
50 		return B_ERROR;
51 	}
52 
53 	if (longFlag) {
54 		printf("%s\n", version.long_info);
55 		return B_OK;
56 	}
57 
58 	if (numericalFlag) {
59 		printf("%lu ", version.major);
60 		printf("%lu ", version.middle);
61 		printf("%lu ", version.minor);
62 
63 		switch (version.variety) {
64 			case B_DEVELOPMENT_VERSION:
65 				printf("d ");
66 				break;
67 
68 			case B_ALPHA_VERSION:
69 				printf("a ");
70 				break;
71 
72 			case B_BETA_VERSION:
73 				printf("b ");
74 				break;
75 
76 			case B_GAMMA_VERSION:
77 				printf("g ");
78 				break;
79 
80 			case B_GOLDEN_MASTER_VERSION:
81 				printf("gm ");
82 				break;
83 
84 			case B_FINAL_VERSION:
85 				printf("f ");
86 				break;
87 		}
88 
89 		printf("%lu\n", version.internal);
90 		return B_OK;
91 	}
92 
93 	printf("%s\n", version.short_info);
94 	return B_OK;
95 }
96 
97 
98 /*!
99 	determines whether  \a string1 contains at least one or more of the characters
100 	of \a string2 but none of which \a string2 doesn't contain.
101 
102 	examples:
103 	true == ("hel" == "help"); true == ("help" == "help"); true == ("h" == "help");
104 	false == ("held" == "help"); false == ("helped" == "help");
105 */
106 bool
107 str_less_equal(const char *str1, const char *str2)
108 {
109 	char *ptr1 = const_cast<char*>(str1);
110 	char *ptr2 = const_cast<char*>(str2);
111 
112 	while (*ptr1 != '\0') {
113 		if (*ptr1 != *ptr2)
114 			return false;
115 		++ptr1;
116 		++ptr2;
117 	}
118 	return true;
119 }
120 
121 
122 int
123 main(int argc, char *argv[])
124 {
125 	BApplication app("application/x.vnd.Haiku-version");
126 	version_kind kind = B_APP_VERSION_KIND;
127 	bool longFlag = false;
128 	bool numericalFlag = false;
129 	int i;
130 
131 	if (argc < 2) {
132 		usage();
133 		return 0;
134 	}
135 
136 	for (i = 1; i < argc; ++i) {
137 		if (argv[i][0] == '-') {
138 			char *ptr = argv[i];
139 			++ptr;
140 
141 			if (*ptr == '-') {
142 				bool lessEqual = false;
143 				++ptr;
144 
145 				if (*ptr == 'h') {
146 					lessEqual = str_less_equal(ptr, "help");
147 					if (lessEqual) {
148 						usage();
149 						return 0;
150 					}
151 				} else if (*ptr == 'l') {
152 					lessEqual = str_less_equal(ptr, "long");
153 					if (lessEqual)
154 						longFlag = true;
155 				} else if (*ptr == 'n') {
156 					lessEqual = str_less_equal(ptr, "numerical");
157 					if (lessEqual)
158 						numericalFlag = true;
159 				} else if (*ptr == 's') {
160 					lessEqual = str_less_equal(ptr, "system");
161 					if (lessEqual)
162 						kind = B_SYSTEM_VERSION_KIND;
163 				} else if (*ptr == 'v') {
164 					lessEqual = str_less_equal(ptr, "version");
165 					if (lessEqual) {
166 						get_version(argv[0], B_APP_VERSION_KIND, false, false);
167 						return 0;
168 					}
169 				}
170 
171 				if (!lessEqual)
172 					printf("%s unrecognized option `%s'\n", argv[0], argv[i]);
173 			} else {
174 				while (*ptr != '\0') {
175 					if (*ptr == 'h') {
176 						usage();
177 						return 0;
178 					} else if (*ptr == 's')
179 						kind = B_SYSTEM_VERSION_KIND;
180 					else if (*ptr == 'l')
181 						longFlag = true;
182 					else if (*ptr == 'n')
183 						numericalFlag = true;
184 					else {
185 						printf("%s: invalid option -- %c\n", argv[0], *ptr);
186 						return 1;
187 					}
188 
189 					if (argc < 3) {
190 						printf("%s: missing FILENAME(S) \n", argv[0]);
191 						return 1;
192 					}
193 
194 					++ptr;
195 				}
196 			}
197 		}
198 	}
199 
200 	for (i = 1; i < argc; ++i) {
201 		if (argv[i][0] != '-'
202 			&& get_version(argv[i], kind, longFlag, numericalFlag) != B_OK)
203 			return 1;
204 	}
205 
206 	return 0;
207 }
208