vfs: check userland buffers before reading them.
[haiku.git] / src / bin / alert.cpp
blobd6382ba8cbb6a36c1ba8e06a7bd0488141928dff
1 /*
2 * Copyright 2002-2006, Haiku Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Mathew Hounsell
7 * Vasilis Kaoutsis, kaoutsis@sch.gr
8 */
11 #include <Alert.h>
12 #include <Application.h>
14 #include <stdio.h>
15 #include <string.h>
18 const char* kSignature = "application/x-vnd.Haiku.cmd-alert";
20 const char* kButtonDefault = "OK";
22 const int32 kErrorInitFail = 127;
23 const int32 kErrorArgumentsFail = 126;
26 class AlertApplication : public BApplication {
27 public:
28 AlertApplication();
29 virtual ~AlertApplication() { }
31 virtual void ReadyToRun();
32 virtual void ArgvReceived(int32 argc, char** argv);
34 bool GoodArguments() const { return fOk; }
35 int32 ChoiceNumber() const { return fChoiceNumber; }
36 char const* ChoiceText() const { return fChoiceText; }
38 private:
39 void _SetChoice(int32 buttonIndex);
40 void _Usage() const;
42 private:
43 bool fOk;
44 bool fModal;
45 alert_type fIcon;
46 char* fArgumentText;
47 char* fArgumentButton0;
48 char* fArgumentButton1;
49 char* fArgumentButton2;
50 char* fChoiceText;
51 int32 fChoiceNumber;
55 AlertApplication::AlertApplication()
56 : BApplication(kSignature),
57 fOk(false),
58 fModal(false),
59 fIcon(B_INFO_ALERT),
60 fArgumentText(NULL),
61 fArgumentButton0(NULL),
62 fArgumentButton1(NULL),
63 fArgumentButton2(NULL),
64 fChoiceText(NULL),
65 fChoiceNumber(0)
70 /*!
71 Invoked when the application receives a B_ARGV_RECEIVED message.
72 The message is sent when command line arguments are used in launching the
73 app from the shell. The function isn't called if there were no command
74 line arguments.
76 void
77 AlertApplication::ArgvReceived(int32 argc, char** argv)
79 // Now there is at least one
80 // command line argument option.
82 const uint32 kArgCount = argc - 1;
83 uint32 index = 1;
84 bool iconFlag = false;
86 // Look for valid '--' options.
87 for (; index <= kArgCount; ++index) {
88 if (argv[index][0] == '-' && argv[index][1] == '-') {
89 const char* option = argv[index] + 2;
91 if (!strcmp(option, "modal"))
92 fModal = true;
93 else if (!strcmp(option, "empty") && !iconFlag) {
94 fIcon = B_EMPTY_ALERT;
95 iconFlag = true;
96 } else if (!strcmp(option, "info") && !iconFlag) {
97 fIcon = B_INFO_ALERT;
98 iconFlag = true;
99 } else if (!strcmp(option, "idea") && !iconFlag) {
100 fIcon = B_IDEA_ALERT;
101 iconFlag = true;
102 } else if (!strcmp(option, "warning") && !iconFlag) {
103 fIcon = B_WARNING_ALERT;
104 iconFlag = true;
105 } else if (!strcmp(option, "stop") && !iconFlag) {
106 fIcon = B_STOP_ALERT;
107 iconFlag = true;
108 } else {
109 // Unrecognized '--' opition.
110 fprintf(stdout, "Unrecognized option %s\n", argv[index]);
111 return;
113 } else {
114 // Option doesn't start with '--'
115 break;
118 if (index == kArgCount) {
119 // User provides arguments that all begins with '--',
120 // so none can be considered as text argument.
121 fprintf(stdout, "Missing the text argument!\n");
122 return;
126 fArgumentText = strdup(argv[index]);
127 // First argument that start without --,
128 // so grub it as the text argument.
130 if (index == kArgCount) {
131 // No more text argument. Give Button0
132 // the default label.
133 fArgumentButton0 = strdup(kButtonDefault);
134 fOk = true;
135 return;
138 if (index < kArgCount) {
139 // There is another argument,
140 // so let that be the Button0 label.
141 fArgumentButton0 = strdup(argv[++index]);
144 if (index < kArgCount) {
145 // There is another argument,
146 // so let that be the Button1 label.
147 fArgumentButton1 = strdup(argv[++index]);
150 if (index < kArgCount) {
151 // There is another argument,
152 // so let that be the Button2 label.
153 fArgumentButton2 = strdup(argv[++index]);
156 // Ignore all other arguments if they exist,
157 // since they are useless.
159 fOk = true;
163 void
164 AlertApplication::_SetChoice(int32 buttonIndex)
166 fChoiceNumber = buttonIndex;
167 switch (fChoiceNumber) {
168 case 0:
169 fChoiceText = fArgumentButton0;
170 break;
172 case 1:
173 fChoiceText = fArgumentButton1;
174 break;
176 case 2:
177 fChoiceText = fArgumentButton2;
178 break;
183 void
184 AlertApplication::_Usage() const
186 fprintf(stderr,
187 "usage: alert [ <type> ] [ --modal ] [ --help ] text [ button1 [ button2 [ button3 ]]]\n"
188 "<type> is --empty | --info | --idea | --warning | --stop\n"
189 "--modal makes the alert system modal and shows it in all workspaces.\n"
190 "If any button argument is given, exit status is button number (starting with 0)\n"
191 "and 'alert' will print the title of the button pressed to stdout.\n");
196 Is called when the app receives a B_READY_TO_RUN message. The message
197 is sent automatically during the Run() function, and is sent after the
198 initial B_REFS_RECEIVED and B_ARGV_RECEIVED messages (if any) have been
199 handled.
201 void
202 AlertApplication::ReadyToRun()
204 if (GoodArguments()) {
205 BAlert* alert = new BAlert("alert", fArgumentText,
206 fArgumentButton0, fArgumentButton1, fArgumentButton2,
207 B_WIDTH_AS_USUAL, fIcon);
209 if (fModal)
210 alert->SetFeel(B_MODAL_ALL_WINDOW_FEEL);
212 _SetChoice(alert->Go());
213 } else
214 _Usage();
216 Quit();
220 // #pragma mark -
224 main(int argc, char** argv)
226 AlertApplication app;
227 if (app.InitCheck() != B_OK)
228 return kErrorInitFail;
230 app.Run();
231 if (!app.GoodArguments())
232 return kErrorArgumentsFail;
234 fprintf(stdout, "%s\n", app.ChoiceText());
235 return app.ChoiceNumber();