1 using System;
2 using System.Collections;
3 using System.IO;
4 using System.Net.Http;
5 using System.Windows.API;
6
7 void PrintUsage()
8 {
9 Console.Out() << "Usage: rfc [options] RFCNUMBER..." << endl();
10 Console.Out() << "Fetch RFC document from rfc-editor.org, and show it in browser." << endl();
11 Console.Out() << "Options:" << endl();
12 Console.Out() << "--help | -h:" << endl();
13 Console.Out() << " Print help and exit." << endl();
14 Console.Out() << "--verbose | -v:" << endl();
15 Console.Out() << " Be verbose." << endl();
16 }
17
18 int main(int argc, const char** argv)
19 {
20 try
21 {
22 bool verbose = false;
23 List<string> rfcs;
24 for (int i = 1; i < argc; ++i;)
25 {
26 string arg = argv[i];
27 if (arg.StartsWith("--"))
28 {
29 if (arg == "--help")
30 {
31 PrintUsage();
32 return 1;
33 }
34 else if (arg == "--verbose")
35 {
36 verbose = true;
37 }
38 else
39 {
40 throw Exception("unknown option '" + arg + "'");
41 }
42 }
43 else if (arg.StartsWith("-"))
44 {
45 string options = arg.Substring(1);
46 for (char o : options)
47 {
48 switch (o)
49 {
50 case 'h': PrintUsage(); return 1;
51 case 'v': verbose = true; break;
52 default: throw Exception("unknown option '-" + string(o) + "'"); break;
53 }
54 }
55 }
56 else
57 {
58 rfcs.Add(arg);
59 }
60 }
61 if (rfcs.IsEmpty())
62 {
63 throw Exception("no RFC numbers given");
64 }
65 StreamWriter* log = null;
66 if (verbose)
67 {
68 log = &Console.Out();
69 }
70 for (const string& rfc : rfcs)
71 {
72 UriReference baseAddress = "https://www.rfc-editor.org/";
73 HttpClient client(baseAddress, log);
74 UriReference rfcUri("/rfc/rfc" + rfc + ".html");
75 HttpHeaderCollection headers;
76 SharedPtr<ByteStream> body;
77 HttpStatus status = client.Get(rfcUri, headers, body);
78 if (status.StatusCode() != statusSuccessOK)
79 {
80 throw Exception(status.ToString());
81 }
82 string fileName = "rfc" + rfc + ".html";
83 StreamWriter writer = File.CreateText(fileName);
84 body->CopyTo(*writer.ContainedStream());
85 if (verbose)
86 {
87 Console.Out() << "==> " << fileName << endl();
88 }
89 if (verbose)
90 {
91 Console.Out() << "starting browser..." << endl();
92 }
93 ShellExecute(fileName);
94 if (verbose)
95 {
96 Console.Out() << "done." << endl();
97 }
98 }
99 }
100 catch (const Exception& ex)
101 {
102 Console.Error() << ex.Message() << endl();
103 return 1;
104 }
105 return 0;
106 }