blob: a410c7a18b00a67f893aee9b5553920c61eef27e [file] [log] [blame]
hilata198cadb2014-02-15 23:46:19 -06001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Syed Obaid4ae0ce32014-06-17 13:59:20 -05003 * Copyright (c) 2014, Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Syed Obaid4ae0ce32014-06-17 13:59:20 -050024 */
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070025
hilata198cadb2014-02-15 23:46:19 -060026#include "nfdc.hpp"
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070027#include "version.hpp"
28
hilata198cadb2014-02-15 23:46:19 -060029#include <boost/lexical_cast.hpp>
30#include <boost/algorithm/string.hpp>
31#include <boost/algorithm/string/regex_find_format.hpp>
32#include <boost/regex.hpp>
33
34void
35usage(const char* programName)
36{
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070037 std::cout << "Usage:\n" << programName << " [-h] [-V] COMMAND [<Command Options>]\n"
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070038 " -h print usage and exit\n"
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070039 " -V print version and exit\n"
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070040 "\n"
Obaiddca50792014-04-24 18:38:40 -050041 " COMMAND can be one of the following:\n"
Syed Obaid4ae0ce32014-06-17 13:59:20 -050042 " register [-I] [-C] [-c cost] [-e expiration time] [-o origin] name <faceId | faceUri>\n"
Obaiddca50792014-04-24 18:38:40 -050043 " register name to the given faceId or faceUri\n"
44 " -I: unset CHILD_INHERIT flag\n"
45 " -C: set CAPTURE flag\n"
46 " -c: specify cost\n"
Syed Obaid4ae0ce32014-06-17 13:59:20 -050047 " -e: specify expiring time in ms\n"
48 " -o: specify origin\n"
49 " 0 for Local producer applications, 128 for NLSR, 255 for static routes\n"
Syed Obaidf93f9d92014-06-22 13:50:48 -050050 " unregister [-o origin] name <faceId>\n"
Obaiddca50792014-04-24 18:38:40 -050051 " unregister name from the given faceId\n"
52 " create <faceUri> \n"
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070053 " Create a face in one of the following formats:\n"
54 " UDP unicast: udp[4|6]://<remote-IP-or-host>[:<remote-port>]\n"
55 " TCP: tcp[4|6]://<remote-IP-or-host>[:<remote-port>] \n"
Obaiddca50792014-04-24 18:38:40 -050056 " destroy <faceId | faceUri> \n"
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070057 " Destroy a face\n"
58 " set-strategy <name> <strategy> \n"
59 " Set the strategy for a namespace \n"
60 " unset-strategy <name> \n"
61 " Unset the strategy for a namespace \n"
hilata6ee6e072014-04-20 17:10:18 -050062 " add-nexthop [-c <cost>] <name> <faceId | faceUri>\n"
63 " Add a nexthop to a FIB entry\n"
64 " -c: specify cost\n"
65 " remove-nexthop <name> <faceId> \n"
66 " Remove a nexthop from a FIB entry\n"
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070067 << std::endl;
hilata198cadb2014-02-15 23:46:19 -060068}
69
70namespace nfdc {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070071
Syed Obaid4ae0ce32014-06-17 13:59:20 -050072const ndn::time::milliseconds Nfdc::DEFAULT_EXPIRATION_PERIOD = ndn::time::milliseconds(3600000);
73const uint64_t Nfdc::DEFAULT_COST = 0;
74
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070075Nfdc::Nfdc(ndn::Face& face)
Obaiddca50792014-04-24 18:38:40 -050076 : m_flags(ROUTE_FLAG_CHILD_INHERIT)
Syed Obaid4ae0ce32014-06-17 13:59:20 -050077 , m_cost(DEFAULT_COST)
78 , m_origin(ROUTE_ORIGIN_STATIC)
79 , m_expires(DEFAULT_EXPIRATION_PERIOD)
Obaiddca50792014-04-24 18:38:40 -050080 , m_controller(face)
hilata198cadb2014-02-15 23:46:19 -060081{
82}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070083
84Nfdc::~Nfdc()
hilata198cadb2014-02-15 23:46:19 -060085{
86}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070087
hilata198cadb2014-02-15 23:46:19 -060088bool
hilata54e4eaf2014-04-10 23:38:33 -050089Nfdc::dispatch(const std::string& command)
hilata198cadb2014-02-15 23:46:19 -060090{
Obaiddca50792014-04-24 18:38:40 -050091 if (command == "add-nexthop") {
92 if (m_nOptions != 2)
hilata54e4eaf2014-04-10 23:38:33 -050093 return false;
Obaiddca50792014-04-24 18:38:40 -050094 fibAddNextHop();
hilata198cadb2014-02-15 23:46:19 -060095 }
96 else if (command == "remove-nexthop") {
hilata54e4eaf2014-04-10 23:38:33 -050097 if (m_nOptions != 2)
hilata198cadb2014-02-15 23:46:19 -060098 return false;
hilata54e4eaf2014-04-10 23:38:33 -050099 fibRemoveNextHop();
hilata198cadb2014-02-15 23:46:19 -0600100 }
Obaiddca50792014-04-24 18:38:40 -0500101 else if (command == "register") {
102 if (m_nOptions != 2)
103 return false;
104 ribRegisterPrefix();
105 }
106 else if (command == "unregister") {
107 if (m_nOptions != 2)
108 return false;
109 ribUnregisterPrefix();
110 }
hilata198cadb2014-02-15 23:46:19 -0600111 else if (command == "create") {
hilata54e4eaf2014-04-10 23:38:33 -0500112 if (m_nOptions != 1)
hilata198cadb2014-02-15 23:46:19 -0600113 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500114 faceCreate();
hilata198cadb2014-02-15 23:46:19 -0600115 }
116 else if (command == "destroy") {
hilata54e4eaf2014-04-10 23:38:33 -0500117 if (m_nOptions != 1)
hilata198cadb2014-02-15 23:46:19 -0600118 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500119 faceDestroy();
hilata198cadb2014-02-15 23:46:19 -0600120 }
hilata141eaae2014-03-13 19:54:47 -0500121 else if (command == "set-strategy") {
hilata54e4eaf2014-04-10 23:38:33 -0500122 if (m_nOptions != 2)
hilata141eaae2014-03-13 19:54:47 -0500123 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500124 strategyChoiceSet();
hilata141eaae2014-03-13 19:54:47 -0500125 }
126 else if (command == "unset-strategy") {
hilata54e4eaf2014-04-10 23:38:33 -0500127 if (m_nOptions != 1)
hilata141eaae2014-03-13 19:54:47 -0500128 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500129 strategyChoiceUnset();
hilata141eaae2014-03-13 19:54:47 -0500130 }
hilata198cadb2014-02-15 23:46:19 -0600131 else
132 usage(m_programName);
133
134 return true;
135}
hilata198cadb2014-02-15 23:46:19 -0600136
hilata198cadb2014-02-15 23:46:19 -0600137namespace {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700138
139inline bool
hilata198cadb2014-02-15 23:46:19 -0600140isValidUri(const std::string& input)
141{
142 // an extended regex to support the validation of uri structure
143 // boost::regex e("^[a-z0-9]+-?+[a-z0-9]+\\:\\/\\/.*");
144 boost::regex e("^[a-z0-9]+\\:.*");
145 return boost::regex_match(input, e);
146}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700147
hilata198cadb2014-02-15 23:46:19 -0600148} // anonymous namespace
149
150void
Obaiddca50792014-04-24 18:38:40 -0500151Nfdc::fibAddNextHop()
hilata198cadb2014-02-15 23:46:19 -0600152{
Obaiddca50792014-04-24 18:38:40 -0500153 m_name = m_commandLineArguments[0];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700154 ControlParameters parameters;
155 parameters
Obaiddca50792014-04-24 18:38:40 -0500156 .setName(m_name)
157 .setCost(m_cost);
hilata54e4eaf2014-04-10 23:38:33 -0500158
Obaiddca50792014-04-24 18:38:40 -0500159 if (!isValidUri(m_commandLineArguments[1])) {
160 try { //So the uri is not valid, may be a faceId is provided.
161 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
162 }
163 catch (const std::exception& e) {
164 std::cerr << "No valid faceUri or faceId is provided"<< std::endl;
165 return;
166 }
167 parameters.setFaceId(m_faceId);
168 fibAddNextHop(parameters);
hilata54e4eaf2014-04-10 23:38:33 -0500169 }
Obaiddca50792014-04-24 18:38:40 -0500170 else {
171 ControlParameters faceParameters;
172 faceParameters.setUri(m_commandLineArguments[1]);
hilata54e4eaf2014-04-10 23:38:33 -0500173
Obaiddca50792014-04-24 18:38:40 -0500174 m_controller.start<FaceCreateCommand>(faceParameters,
175 bind(&Nfdc::fibAddNextHop, this, _1),
176 bind(&Nfdc::onError, this, _1, _2,
177 "Face creation failed"));
178 }
179}
180
181void
182Nfdc::fibAddNextHop(const ControlParameters& faceCreateResult)
183{
184 ControlParameters ribParameters;
185 ribParameters
186 .setName(m_name)
187 .setCost(m_cost)
188 .setFaceId(faceCreateResult.getFaceId());
189
190 m_controller.start<FibAddNextHopCommand>(ribParameters,
191 bind(&Nfdc::onSuccess, this, _1,
192 "Nexthop insertion succeeded"),
193 bind(&Nfdc::onError, this, _1, _2,
194 "Nexthop insertion failed"));
hilata54e4eaf2014-04-10 23:38:33 -0500195}
196
197void
198Nfdc::fibRemoveNextHop()
199{
Obaiddca50792014-04-24 18:38:40 -0500200 m_name = m_commandLineArguments[0];
201 try {
202 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
203 }
204 catch (const std::exception& e) {
205 std::cerr << "No valid faceUri or faceId is provided"<< std::endl;
206 return;
207 }
hilata54e4eaf2014-04-10 23:38:33 -0500208
209 ControlParameters parameters;
210 parameters
Obaiddca50792014-04-24 18:38:40 -0500211 .setName(m_name)
212 .setFaceId(m_faceId);
hilata54e4eaf2014-04-10 23:38:33 -0500213
Obaiddca50792014-04-24 18:38:40 -0500214 m_controller.start<FibRemoveNextHopCommand>(parameters,
215 bind(&Nfdc::onSuccess, this, _1,
216 "Nexthop removal succeeded"),
217 bind(&Nfdc::onError, this, _1, _2,
218 "Nexthop removal failed"));
219}
220
221void
222Nfdc::ribRegisterPrefix()
223{
224 m_name = m_commandLineArguments[0];
225 ControlParameters parameters;
226 parameters
227 .setName(m_name)
228 .setCost(m_cost)
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500229 .setFlags(m_flags)
230 .setOrigin(m_origin)
231 .setExpirationPeriod(m_expires);
Obaiddca50792014-04-24 18:38:40 -0500232
233 if (!isValidUri(m_commandLineArguments[1])) {
234 try { //So the uri is not valid, may be a faceId is provided.
235 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
236 }
237 catch (const std::exception& e) {
238 std::cerr << "No valid faceUri or faceId is provided"<< std::endl;
239 return;
240 }
241 parameters.setFaceId(m_faceId);
242 ribRegisterPrefix(parameters);
243 }
244 else {
245 ControlParameters faceParameters;
246 faceParameters.setUri(m_commandLineArguments[1]);
247
248 m_controller.start<FaceCreateCommand>(faceParameters,
249 bind(&Nfdc::ribRegisterPrefix, this, _1),
250 bind(&Nfdc::onError, this, _1, _2,
251 "Face creation failed"));
252 }
253}
254
255void
256Nfdc::ribRegisterPrefix(const ControlParameters& faceCreateResult)
257{
258 ControlParameters ribParameters;
259 ribParameters
260 .setName(m_name)
261 .setCost(m_cost)
262 .setFlags(m_flags)
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500263 .setExpirationPeriod(m_expires)
264 .setOrigin(m_origin)
Obaiddca50792014-04-24 18:38:40 -0500265 .setFaceId(faceCreateResult.getFaceId());
266
267 m_controller.start<RibRegisterCommand>(ribParameters,
268 bind(&Nfdc::onSuccess, this, _1,
269 "Successful in name registration"),
270 bind(&Nfdc::onError, this, _1, _2,
271 "Failed in name registration"));
272}
273
274void
275Nfdc::ribUnregisterPrefix()
276{
277 m_name = m_commandLineArguments[0];
278 try {
279 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
280 }
281 catch (const std::exception& e) {
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500282 std::cerr << "No valid faceId is provided" << std::endl;
Obaiddca50792014-04-24 18:38:40 -0500283 return;
284 }
285
286 ControlParameters parameters;
287 parameters
288 .setName(m_name)
Syed Obaidf93f9d92014-06-22 13:50:48 -0500289 .setFaceId(m_faceId)
290 .setOrigin(m_origin);
Obaiddca50792014-04-24 18:38:40 -0500291
292 m_controller.start<RibUnregisterCommand>(parameters,
293 bind(&Nfdc::onSuccess, this, _1,
294 "Successful in unregistering name"),
295 bind(&Nfdc::onError, this, _1, _2,
296 "Failed in unregistering name"));
hilata54e4eaf2014-04-10 23:38:33 -0500297}
298
299void
300Nfdc::faceCreate()
301{
302 if (!isValidUri(m_commandLineArguments[0]))
303 throw Error("invalid uri format");
304
305 ControlParameters parameters;
Obaiddca50792014-04-24 18:38:40 -0500306 parameters.setUri(m_commandLineArguments[0]);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700307
Obaiddca50792014-04-24 18:38:40 -0500308 m_controller.start<FaceCreateCommand>(parameters,
309 bind(&Nfdc::onSuccess, this, _1,
310 "Face creation succeeded"),
311 bind(&Nfdc::onError, this, _1, _2,
312 "Face creation failed"));
hilata198cadb2014-02-15 23:46:19 -0600313}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700314
hilata198cadb2014-02-15 23:46:19 -0600315void
hilata54e4eaf2014-04-10 23:38:33 -0500316Nfdc::faceDestroy()
hilata198cadb2014-02-15 23:46:19 -0600317{
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700318 ControlParameters parameters;
Obaiddca50792014-04-24 18:38:40 -0500319 if (!isValidUri(m_commandLineArguments[0])) {
320 try { //So the uri is not valid, may be a faceId is provided.
321 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[0]);
322 }
323 catch (const std::exception& e) {
324 std::cerr << "No valid faceUri or faceId is provided" << std::endl;
325 return;
326 }
327 parameters.setFaceId(m_faceId);
328 faceDestroy(parameters);
329 }
330 else{
331 ControlParameters faceParameters;
332 faceParameters.setUri(m_commandLineArguments[0]);
333 m_controller.start<FaceCreateCommand>(faceParameters,
334 bind(&Nfdc::faceDestroy, this, _1),
335 bind(&Nfdc::onError, this, _1, _2,
336 "Face destroy failed"));
337 }
338}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700339
Obaiddca50792014-04-24 18:38:40 -0500340void
341Nfdc::faceDestroy(const ControlParameters& faceCreateResult)
342{
343 ControlParameters faceParameters;
344 faceParameters.setFaceId(faceCreateResult.getFaceId());
345
346 m_controller.start<FaceDestroyCommand>(faceParameters,
347 bind(&Nfdc::onSuccess, this, _1,
348 "Face destroy succeeded"),
349 bind(&Nfdc::onError, this, _1, _2,
350 "Face destroy failed"));
hilata198cadb2014-02-15 23:46:19 -0600351}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700352
hilata141eaae2014-03-13 19:54:47 -0500353void
hilata54e4eaf2014-04-10 23:38:33 -0500354Nfdc::strategyChoiceSet()
hilata141eaae2014-03-13 19:54:47 -0500355{
hilata54e4eaf2014-04-10 23:38:33 -0500356 const std::string& name = m_commandLineArguments[0];
357 const std::string& strategy = m_commandLineArguments[1];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700358
359 ControlParameters parameters;
360 parameters
361 .setName(name)
362 .setStrategy(strategy);
363
Obaiddca50792014-04-24 18:38:40 -0500364 m_controller.start<StrategyChoiceSetCommand>(parameters,
365 bind(&Nfdc::onSuccess, this, _1,
366 "Successfully set strategy choice"),
367 bind(&Nfdc::onError, this, _1, _2,
368 "Failed to set strategy choice"));
hilata141eaae2014-03-13 19:54:47 -0500369}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700370
hilata141eaae2014-03-13 19:54:47 -0500371void
hilata54e4eaf2014-04-10 23:38:33 -0500372Nfdc::strategyChoiceUnset()
hilata141eaae2014-03-13 19:54:47 -0500373{
hilata54e4eaf2014-04-10 23:38:33 -0500374 const std::string& name = m_commandLineArguments[0];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700375
376 ControlParameters parameters;
Obaiddca50792014-04-24 18:38:40 -0500377 parameters.setName(name);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700378
Obaiddca50792014-04-24 18:38:40 -0500379 m_controller.start<StrategyChoiceUnsetCommand>(parameters,
380 bind(&Nfdc::onSuccess, this, _1,
381 "Successfully unset strategy choice"),
382 bind(&Nfdc::onError, this, _1, _2,
383 "Failed to unset strategy choice"));
hilata141eaae2014-03-13 19:54:47 -0500384}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700385
hilata198cadb2014-02-15 23:46:19 -0600386void
Obaiddca50792014-04-24 18:38:40 -0500387Nfdc::onSuccess(const ControlParameters& commandSuccessResult, const std::string& message)
hilata198cadb2014-02-15 23:46:19 -0600388{
Obaiddca50792014-04-24 18:38:40 -0500389 std::cout << message << ": " << commandSuccessResult << std::endl;
hilata198cadb2014-02-15 23:46:19 -0600390}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700391
hilata198cadb2014-02-15 23:46:19 -0600392void
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700393Nfdc::onError(uint32_t code, const std::string& error, const std::string& message)
hilata198cadb2014-02-15 23:46:19 -0600394{
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700395 std::ostringstream os;
396 os << message << ": " << error << " (code: " << code << ")";
397 throw Error(os.str());
hilata141eaae2014-03-13 19:54:47 -0500398}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700399
Obaiddca50792014-04-24 18:38:40 -0500400
401
hilata141eaae2014-03-13 19:54:47 -0500402} // namespace nfdc
hilata198cadb2014-02-15 23:46:19 -0600403
404int
405main(int argc, char** argv)
406{
407 ndn::Face face;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700408 nfdc::Nfdc p(face);
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800409
hilata198cadb2014-02-15 23:46:19 -0600410 p.m_programName = argv[0];
hilata54e4eaf2014-04-10 23:38:33 -0500411
Obaiddca50792014-04-24 18:38:40 -0500412 if (argc < 2) {
413 usage(p.m_programName);
414 return 0;
415 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700416
Obaiddca50792014-04-24 18:38:40 -0500417 if (!strcmp(argv[1], "-h")) {
418 usage(p.m_programName);
419 return 0;
420 }
421
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700422 if (!strcmp(argv[1], "-V")) {
423 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
424 return 0;
425 }
426
Junxiao Shi22295032014-04-29 22:57:40 -0700427 ::optind = 2; //start reading options from 2nd argument i.e. Command
Obaiddca50792014-04-24 18:38:40 -0500428 int opt;
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500429 while ((opt = ::getopt(argc, argv, "ICc:e:o:")) != -1) {
Obaiddca50792014-04-24 18:38:40 -0500430 switch (opt) {
431 case 'I':
432 p.m_flags = p.m_flags & ~(nfdc::ROUTE_FLAG_CHILD_INHERIT);
433 break;
434
435 case 'C':
436 p.m_flags = p.m_flags | nfdc::ROUTE_FLAG_CAPTURE;
437 break;
438
439 case 'c':
440 try {
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500441 p.m_cost = boost::lexical_cast<uint64_t>(::optarg);
Obaiddca50792014-04-24 18:38:40 -0500442 }
Junxiao Shi22295032014-04-29 22:57:40 -0700443 catch (boost::bad_lexical_cast&) {
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500444 std::cerr << "Error: cost must be in unsigned integer format" << std::endl;
445 return 1;
446 }
447 break;
448
449 case 'e':
450 uint64_t expires;
451 try {
452 expires = boost::lexical_cast<uint64_t>(::optarg);
453 }
454 catch (boost::bad_lexical_cast&) {
455 std::cerr << "Error: expiration time must be in unsigned integer format" << std::endl;
456 return 1;
457 }
458 p.m_expires = ndn::time::milliseconds(expires);
459 break;
460
461 case 'o':
462 try {
463 p.m_origin = boost::lexical_cast<uint64_t>(::optarg);
464 }
465 catch (boost::bad_lexical_cast&) {
466 std::cerr << "Error: origin must be in unsigned integer format" << std::endl;
hilata198cadb2014-02-15 23:46:19 -0600467 return 1;
Obaiddca50792014-04-24 18:38:40 -0500468 }
469 break;
Junxiao Shi22295032014-04-29 22:57:40 -0700470
Obaiddca50792014-04-24 18:38:40 -0500471 default:
472 usage(p.m_programName);
473 return 1;
hilata198cadb2014-02-15 23:46:19 -0600474 }
475 }
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800476
Junxiao Shi22295032014-04-29 22:57:40 -0700477 if (argc == ::optind) {
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800478 usage(p.m_programName);
479 return 1;
480 }
481
hilata198cadb2014-02-15 23:46:19 -0600482 try {
Junxiao Shi22295032014-04-29 22:57:40 -0700483 p.m_commandLineArguments = argv + ::optind;
484 p.m_nOptions = argc - ::optind;
Obaiddca50792014-04-24 18:38:40 -0500485
486 //argv[1] points to the command, so pass it to the dispatch
487 bool isOk = p.dispatch(argv[1]);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700488 if (!isOk) {
hilata198cadb2014-02-15 23:46:19 -0600489 usage(p.m_programName);
490 return 1;
491 }
hilata198cadb2014-02-15 23:46:19 -0600492 face.processEvents();
493 }
494 catch (const std::exception& e) {
495 std::cerr << "ERROR: " << e.what() << std::endl;
496 return 2;
497 }
498 return 0;
499}