1 /*
2  *  This parses the command line arguments. It was seperated from main.c by
3  *  Justin Dearing <jdeari01@longisland.poly.edu>.
4  */
5 
6 /*
7  *  LibVNCServer (C) 2001 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
8  *  Original OSXvnc (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
9  *  Original Xvnc (C) 1999 AT&T Laboratories Cambridge.
10  *  All Rights Reserved.
11  *
12  *  see GPL (latest version) for full details
13  */
14 
15 #include <rfb/rfb.h>
16 
17 extern int rfbStringToAddr(char *str, in_addr_t *iface);
18 
19 void
rfbUsage(void)20 rfbUsage(void)
21 {
22     rfbProtocolExtension* extension;
23 
24     fprintf(stderr, "-rfbport port          TCP port for RFB protocol\n");
25 #ifdef LIBVNCSERVER_IPv6
26     fprintf(stderr, "-rfbportv6 port        TCP6 port for RFB protocol\n");
27 #endif
28     fprintf(stderr, "-rfbwait time          max time in ms to wait for RFB client\n");
29     fprintf(stderr, "-rfbauth passwd-file   use authentication on RFB protocol\n"
30                     "                       (use 'storepasswd' to create a password file)\n");
31     fprintf(stderr, "-rfbversion 3.x        Set the version of the RFB we choose to advertise\n");
32     fprintf(stderr, "-permitfiletransfer    permit file transfer support\n");
33     fprintf(stderr, "-passwd plain-password use authentication \n"
34                     "                       (use plain-password as password, USE AT YOUR RISK)\n");
35     fprintf(stderr, "-deferupdate time      time in ms to defer updates "
36                                                              "(default 40)\n");
37     fprintf(stderr, "-deferptrupdate time   time in ms to defer pointer updates"
38                                                            " (default none)\n");
39     fprintf(stderr, "-desktop name          VNC desktop name (default \"LibVNCServer\")\n");
40     fprintf(stderr, "-alwaysshared          always treat new clients as shared\n");
41     fprintf(stderr, "-nevershared           never treat new clients as shared\n");
42     fprintf(stderr, "-dontdisconnect        don't disconnect existing clients when a "
43                                                              "new non-shared\n"
44                     "                       connection comes in (refuse new connection "
45                                                                 "instead)\n");
46     fprintf(stderr, "-httpdir dir-path      enable http server using dir-path home\n");
47     fprintf(stderr, "-httpport portnum      use portnum for http connection\n");
48 #ifdef LIBVNCSERVER_IPv6
49     fprintf(stderr, "-httpportv6 portnum    use portnum for IPv6 http connection\n");
50 #endif
51     fprintf(stderr, "-enablehttpproxy       enable http proxy support\n");
52     fprintf(stderr, "-progressive height    enable progressive updating for slow links\n");
53     fprintf(stderr, "-listen ipaddr         listen for connections only on network interface with\n");
54     fprintf(stderr, "                       addr ipaddr. '-listen localhost' and hostname work too.\n");
55 #ifdef LIBVNCSERVER_IPv6
56     fprintf(stderr, "-listenv6 ipv6addr     listen for IPv6 connections only on network interface with\n");
57     fprintf(stderr, "                       addr ipv6addr. '-listen localhost' and hostname work too.\n");
58 #endif
59 
60     for(extension=rfbGetExtensionIterator();extension;extension=extension->next)
61 	if(extension->usage)
62 		extension->usage();
63     rfbReleaseExtensionIterator();
64 }
65 
66 /* purges COUNT arguments from ARGV at POSITION and decrements ARGC.
67    POSITION points to the first non purged argument afterwards. */
rfbPurgeArguments(int * argc,int * position,int count,char * argv[])68 void rfbPurgeArguments(int* argc,int* position,int count,char *argv[])
69 {
70   int amount=(*argc)-(*position)-count;
71   if(amount)
72     memmove(argv+(*position),argv+(*position)+count,sizeof(char*)*amount);
73   (*argc)-=count;
74 }
75 
76 rfbBool
rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int * argc,char * argv[])77 rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[])
78 {
79     int i,i1;
80 
81     if(!argc) return TRUE;
82 
83     for (i = i1 = 1; i < *argc;) {
84         if (strcmp(argv[i], "-help") == 0) {
85 	    rfbUsage();
86 	    return FALSE;
87 	} else if (strcmp(argv[i], "-rfbport") == 0) { /* -rfbport port */
88             if (i + 1 >= *argc) {
89 		rfbUsage();
90 		return FALSE;
91 	    }
92 	    rfbScreen->port = atoi(argv[++i]);
93 #ifdef LIBVNCSERVER_IPv6
94 	} else if (strcmp(argv[i], "-rfbportv6") == 0) { /* -rfbportv6 port */
95             if (i + 1 >= *argc) {
96 		rfbUsage();
97 		return FALSE;
98 	    }
99 	    rfbScreen->ipv6port = atoi(argv[++i]);
100 #endif
101         } else if (strcmp(argv[i], "-rfbwait") == 0) {  /* -rfbwait ms */
102             if (i + 1 >= *argc) {
103 		rfbUsage();
104 		return FALSE;
105 	    }
106 	    rfbScreen->maxClientWait = atoi(argv[++i]);
107         } else if (strcmp(argv[i], "-rfbauth") == 0) {  /* -rfbauth passwd-file */
108             if (i + 1 >= *argc) {
109 		rfbUsage();
110 		return FALSE;
111 	    }
112             rfbScreen->authPasswdData = argv[++i];
113 
114         } else if (strcmp(argv[i], "-permitfiletransfer") == 0) {  /* -permitfiletransfer  */
115             rfbScreen->permitFileTransfer = TRUE;
116         } else if (strcmp(argv[i], "-rfbversion") == 0) {  /* -rfbversion 3.6  */
117             if (i + 1 >= *argc) {
118 		rfbUsage();
119 		return FALSE;
120 	    }
121 	    sscanf(argv[++i],"%d.%d", &rfbScreen->protocolMajorVersion, &rfbScreen->protocolMinorVersion);
122 	} else if (strcmp(argv[i], "-passwd") == 0) {  /* -passwd password */
123 	    char **passwds = malloc(sizeof(char**)*2);
124 	    if (i + 1 >= *argc) {
125 		rfbUsage();
126 		return FALSE;
127 	    }
128 	    passwds[0] = argv[++i];
129 	    passwds[1] = NULL;
130 	    rfbScreen->authPasswdData = (void*)passwds;
131 	    rfbScreen->passwordCheck = rfbCheckPasswordByList;
132         } else if (strcmp(argv[i], "-deferupdate") == 0) {  /* -deferupdate milliseconds */
133             if (i + 1 >= *argc) {
134 		rfbUsage();
135 		return FALSE;
136 	    }
137             rfbScreen->deferUpdateTime = atoi(argv[++i]);
138         } else if (strcmp(argv[i], "-deferptrupdate") == 0) {  /* -deferptrupdate milliseconds */
139             if (i + 1 >= *argc) {
140 		rfbUsage();
141 		return FALSE;
142 	    }
143             rfbScreen->deferPtrUpdateTime = atoi(argv[++i]);
144         } else if (strcmp(argv[i], "-desktop") == 0) {  /* -desktop desktop-name */
145             if (i + 1 >= *argc) {
146 		rfbUsage();
147 		return FALSE;
148 	    }
149             rfbScreen->desktopName = argv[++i];
150         } else if (strcmp(argv[i], "-alwaysshared") == 0) {
151 	    rfbScreen->alwaysShared = TRUE;
152         } else if (strcmp(argv[i], "-nevershared") == 0) {
153             rfbScreen->neverShared = TRUE;
154         } else if (strcmp(argv[i], "-dontdisconnect") == 0) {
155             rfbScreen->dontDisconnect = TRUE;
156         } else if (strcmp(argv[i], "-httpdir") == 0) {  /* -httpdir directory-path */
157             if (i + 1 >= *argc) {
158 		rfbUsage();
159 		return FALSE;
160 	    }
161             rfbScreen->httpDir = argv[++i];
162         } else if (strcmp(argv[i], "-httpport") == 0) {  /* -httpport portnum */
163             if (i + 1 >= *argc) {
164 		rfbUsage();
165 		return FALSE;
166 	    }
167             rfbScreen->httpPort = atoi(argv[++i]);
168 #ifdef LIBVNCSERVER_IPv6
169 	} else if (strcmp(argv[i], "-httpportv6") == 0) {  /* -httpportv6 portnum */
170             if (i + 1 >= *argc) {
171 		rfbUsage();
172 		return FALSE;
173 	    }
174             rfbScreen->http6Port = atoi(argv[++i]);
175 #endif
176         } else if (strcmp(argv[i], "-enablehttpproxy") == 0) {
177             rfbScreen->httpEnableProxyConnect = TRUE;
178         } else if (strcmp(argv[i], "-progressive") == 0) {  /* -httpport portnum */
179             if (i + 1 >= *argc) {
180 		rfbUsage();
181 		return FALSE;
182 	    }
183             rfbScreen->progressiveSliceHeight = atoi(argv[++i]);
184         } else if (strcmp(argv[i], "-listen") == 0) {  /* -listen ipaddr */
185             if (i + 1 >= *argc) {
186 		rfbUsage();
187 		return FALSE;
188 	    }
189             if (! rfbStringToAddr(argv[++i], &(rfbScreen->listenInterface))) {
190                 return FALSE;
191             }
192 #ifdef LIBVNCSERVER_IPv6
193 	} else if (strcmp(argv[i], "-listenv6") == 0) {  /* -listenv6 ipv6addr */
194             if (i + 1 >= *argc) {
195 		rfbUsage();
196 		return FALSE;
197 	    }
198 	    rfbScreen->listen6Interface = argv[++i];
199 #endif
200 #ifdef LIBVNCSERVER_WITH_WEBSOCKETS
201         } else if (strcmp(argv[i], "-sslkeyfile") == 0) {  /* -sslkeyfile sslkeyfile */
202             if (i + 1 >= *argc) {
203 		rfbUsage();
204 		return FALSE;
205 	    }
206             rfbScreen->sslkeyfile = argv[++i];
207         } else if (strcmp(argv[i], "-sslcertfile") == 0) {  /* -sslcertfile sslcertfile */
208             if (i + 1 >= *argc) {
209 		rfbUsage();
210 		return FALSE;
211 	    }
212             rfbScreen->sslcertfile = argv[++i];
213 #endif
214         } else {
215 	    rfbProtocolExtension* extension;
216 	    int handled=0;
217 
218 	    for(extension=rfbGetExtensionIterator();handled==0 && extension;
219 			extension=extension->next)
220 		if(extension->processArgument)
221 			handled = extension->processArgument(*argc - i, argv + i);
222 	    rfbReleaseExtensionIterator();
223 
224 	    if(handled==0) {
225 		i++;
226 		i1=i;
227 		continue;
228 	    }
229 	    i+=handled-1;
230 	}
231 	/* we just remove the processed arguments from the list */
232 	rfbPurgeArguments(argc,&i1,i-i1+1,argv);
233 	i=i1;
234     }
235     return TRUE;
236 }
237 
238 rfbBool
rfbProcessSizeArguments(int * width,int * height,int * bpp,int * argc,char * argv[])239 rfbProcessSizeArguments(int* width,int* height,int* bpp,int* argc, char *argv[])
240 {
241     int i,i1;
242 
243     if(!argc) return TRUE;
244     for (i = i1 = 1; i < *argc-1;) {
245         if (strcmp(argv[i], "-bpp") == 0) {
246                *bpp = atoi(argv[++i]);
247         } else if (strcmp(argv[i], "-width") == 0) {
248                *width = atoi(argv[++i]);
249         } else if (strcmp(argv[i], "-height") == 0) {
250                *height = atoi(argv[++i]);
251         } else {
252 	    i++;
253 	    i1=i;
254 	    continue;
255 	}
256 	rfbPurgeArguments(argc,&i1,i-i1,argv);
257 	i=i1;
258     }
259     return TRUE;
260 }
261 
262