blob: 29178fff0167a57fe165d810727a8eb22de5b33d [file] [log] [blame]
Steve Kondik95027ea2017-06-14 17:22:58 -07001//
2// vncflinger - Copyright (C) 2017 Steve Kondik
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16//
Steve Kondik5c8655c2017-06-19 00:28:47 -070017#include <getopt.h>
Steve Kondik95027ea2017-06-14 17:22:58 -070018
Steve Kondik46798992017-06-15 23:58:54 -070019#include <csignal>
Steve Kondik5c8655c2017-06-19 00:28:47 -070020#include <iostream>
Steve Kondik46798992017-06-15 23:58:54 -070021
Steve Kondik3db07472017-06-19 22:13:45 -070022#include <binder/IServiceManager.h>
23
Steve Kondik55db0532017-06-12 11:27:18 -070024#include "VNCFlinger.h"
Steve Kondik3db07472017-06-19 22:13:45 -070025#include "VNCService.h"
Steve Kondik55db0532017-06-12 11:27:18 -070026
27using namespace android;
28
Steve Kondik5c8655c2017-06-19 00:28:47 -070029static sp<VNCFlinger> gVNC;
30
Steve Kondik66bedf32017-06-20 09:17:35 -070031static const char* const shortOpts = "4:6:p:cs:l:vh";
Steve Kondik5c8655c2017-06-19 00:28:47 -070032static const option longOpts[] = {
33 {"listen", 1, nullptr, '4'},
34 {"listen6", 1, nullptr, '6'},
35 {"port", 1, nullptr, 'p'},
36 {"password", 1, nullptr, 's'},
Steve Kondik66bedf32017-06-20 09:17:35 -070037 {"clear-password", 0, nullptr, 'c'},
Steve Kondik59104ea2017-06-20 08:30:07 -070038 {"scale", 1, nullptr, 'l'},
Steve Kondik5c8655c2017-06-19 00:28:47 -070039 {"version", 0, nullptr, 'v'},
40 {"help", 0, nullptr, 'h'},
41};
Steve Kondik46798992017-06-15 23:58:54 -070042
Steve Kondik59104ea2017-06-20 08:30:07 -070043static void onSignal(int signal) {
44 ALOGV("Shutting down on signal %d", signal);
Steve Kondik5c8655c2017-06-19 00:28:47 -070045 gVNC->stop();
46}
47
48static void printVersion() {
49 std::cout << "VNCFlinger-" << VNCFLINGER_VERSION << std::endl;
50 exit(0);
51}
52
53static void printHelp() {
54 std::cout << "Usage: vncflinger [OPTIONS]\n\n"
55 << " -4 <addr> IPv4 address to listen (default: localhost)\n"
56 << " -6 <addr> IPv6 address to listen (default: localhost)\n"
57 << " -p <num> Port to listen on (default: 5900)\n"
58 << " -s <pass> Store server password\n"
59 << " -c Clear server password\n"
Steve Kondik59104ea2017-06-20 08:30:07 -070060 << " -l <scale> Scaling value (default: 1.0)\n"
Steve Kondik5c8655c2017-06-19 00:28:47 -070061 << " -v Show server version\n"
62 << " -h Show help\n\n";
63 exit(1);
64}
65
66static void parseArgs(int argc, char** argv) {
67 String8 arg;
68
69 while (true) {
70 const auto opt = getopt_long(argc, argv, shortOpts, longOpts, nullptr);
71
72 if (opt < 0) {
73 break;
74 }
75
76 switch (opt) {
77 case 's':
78 arg = optarg;
79 if (gVNC->setPassword(arg) != OK) {
80 std::cerr << "Failed to set password\n";
81 exit(1);
82 }
83 exit(0);
84
85 case 'c':
86 if (gVNC->clearPassword() != OK) {
87 std::cerr << "Failed to clear password\n";
88 exit(1);
89 }
90 exit(0);
91
92 case '4':
93 arg = optarg;
Steve Kondik3db07472017-06-19 22:13:45 -070094 if (gVNC->setV4Address(arg) != OK) {
Steve Kondik5c8655c2017-06-19 00:28:47 -070095 std::cerr << "Failed to set IPv4 address\n";
96 exit(1);
97 }
98 break;
99
100 case '6':
101 arg = optarg;
Steve Kondik3db07472017-06-19 22:13:45 -0700102 if (gVNC->setV6Address(arg) != OK) {
Steve Kondik5c8655c2017-06-19 00:28:47 -0700103 std::cerr << "Failed to set IPv6 address\n";
104 exit(1);
105 }
106 break;
107
108 case 'p':
Steve Kondik5c8655c2017-06-19 00:28:47 -0700109 if (gVNC->setPort(std::stoi(optarg)) != OK) {
110 std::cerr << "Failed to set port\n";
111 exit(1);
112 }
113 break;
114
Steve Kondik59104ea2017-06-20 08:30:07 -0700115 case 'l':
116 if (gVNC->setScale(std::stof(optarg)) != OK) {
117 std::cerr << "Invalid scaling value (must be between 0.0 and 2.0)\n";
118 exit(1);
119 }
120 break;
121
Steve Kondik5c8655c2017-06-19 00:28:47 -0700122 case 'v':
123 printVersion();
124 break;
125
126 case 'h':
127 case '?':
128 default:
129 printHelp();
130 break;
131 }
132 }
Steve Kondik46798992017-06-15 23:58:54 -0700133}
134
Steve Kondik2c9d0cf2017-06-15 23:39:29 -0700135int main(int argc, char** argv) {
Steve Kondik46798992017-06-15 23:58:54 -0700136 std::signal(SIGINT, onSignal);
137 std::signal(SIGHUP, onSignal);
138
Steve Kondik5c8655c2017-06-19 00:28:47 -0700139 gVNC = new VNCFlinger();
140
141 parseArgs(argc, argv);
142
Steve Kondik3db07472017-06-19 22:13:45 -0700143 // binder interface
144 defaultServiceManager()->addService(String16("vnc"), new VNCService(gVNC));
145
Steve Kondik5c8655c2017-06-19 00:28:47 -0700146 gVNC->start();
Steve Kondik59104ea2017-06-20 08:30:07 -0700147 gVNC.clear();
Steve Kondik55db0532017-06-12 11:27:18 -0700148}