Backport of pre-connect Hyper-V code
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-utils / args.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol client.
3  * Arguments Parsing
4  *
5  * Copyright 2009-2011 Jay Sorg
6  * Copyright 2011 Vic Lee
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include "config.h"
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <freerdp/settings.h>
26 #include <freerdp/utils/print.h>
27 #include <freerdp/utils/memory.h>
28 #include <freerdp/utils/args.h>
29
30 /**
31  * Parse command-line arguments and update rdpSettings members accordingly.
32  * @param settings pointer to rdpSettings struct to be updated.
33  * @param argc number of arguments available.
34  * @param argv string array of the arguments.
35  * @param plugin_callback function to be called when a plugin needs to be loaded.
36  * @param plugin_user_data pointer to be passed to the plugin_callback function.
37  * @param ui_callback function to be called when a UI-specific argument is being processed.
38  * @param ui_user_data pointer to be passed to the ui_callback function.
39  * @return number of arguments that were parsed, or FREERDP_ARGS_PARSE_RESULT on failure or --version/--help
40  */
41 int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
42         ProcessPluginArgs plugin_callback, void* plugin_user_data,
43         ProcessUIArgs ui_callback, void* ui_user_data)
44 {
45         int t;
46         char* p;
47         int i, j;
48         int index = 1;
49         int num_extensions = 0;
50         RDP_PLUGIN_DATA* plugin_data;
51
52         while (index < argc)
53         {
54                 if ((strcmp("-h", argv[index]) == 0 ) || (strcmp("--help", argv[index]) == 0 ))
55                 {
56                         printf("\n"
57                                 "FreeRDP - A Free Remote Desktop Protocol Client\n"
58                                 "See http://www.freerdp.com for more information\n"
59                                 "\n"
60                                 "Usage: %s [options] server:port\n"
61                                 "  -0: connect to console session\n"
62                                 "  -a: set color depth in bit, default is 16\n"
63                                 "  -c: initial working directory\n"
64                                 "  -D: hide window decorations\n"
65                                 "  -T: window title\n"
66                                 "  -d: domain\n"
67                                 "  -f: fullscreen mode\n"
68                                 "  -g: set geometry, using format WxH or X%% or 'workarea', default is 1024x768\n"
69                                 "  -h: print this help\n"
70                                 "  -k: set keyboard layout ID\n"
71                                 "  -K: do not interfere with window manager bindings\n"
72                                 "  -m: don't send mouse motion events\n"
73                                 "  -n: hostname\n"
74                                 "  -o: console audio\n"
75                                 "  -p: password\n"
76                                 "  -s: set startup-shell\n"
77                                 "  -t: alternative port number, default is 3389\n"
78                                 "  -u: username\n"
79                                 "  -x: performance flags (m[odem], b[roadband] or l[an])\n"
80                                 "  -X: embed into another window with a given XID.\n"
81                                 "  -z: enable compression\n"
82                                 "  --app: RemoteApp connection. This implies -g workarea\n"
83                                 "  --ext: load an extension\n"
84                                 "  --no-auth: disable authentication\n"
85                                 "  --no-fastpath: disable fast-path\n"
86                                 "  --gdi: graphics rendering (hw, sw)\n"
87                                 "  --no-osb: disable offscreen bitmaps\n"
88                                 "  --no-bmp-cache: disable bitmap cache\n"
89                                 "  --plugin: load a virtual channel plugin\n"
90                                 "  --rfx: enable RemoteFX\n"
91                                 "  --rfx-mode: RemoteFX operational flags (v[ideo], i[mage]), default is video\n"
92                                 "  --nsc: enable NSCodec (experimental)\n"
93                                 "  --disable-wallpaper: disables wallpaper\n"
94                                 "  --composition: enable desktop composition\n"
95                                 "  --disable-full-window-drag: disables full window drag\n"
96                                 "  --disable-menu-animations: disables menu animations\n"
97                                 "  --disable-theming: disables theming\n"
98                                 "  --no-nego: disable negotiation of security layer and enforce highest enabled security protocol\n"
99                                 "  --no-rdp: disable Standard RDP encryption\n"
100                                 "  --no-tls: disable TLS encryption\n"
101                                 "  --no-nla: disable network level authentication\n"
102                                 "  --ntlm: force NTLM authentication protocol version (1 or 2)\n"
103                                 "  --ignore-certificate: ignore verification of logon certificate\n"
104                                 "  --sec: force protocol security (rdp, tls or nla)\n"
105                                 "  --secure-checksum: use salted checksums with Standard RDP encryption\n"
106                                 "  --pcid: preconnection id\n"
107                                 "  --pcb: preconnection blob\n"
108                                 "  --version: print version information\n"
109                                 "\n", argv[0]);
110                         return FREERDP_ARGS_PARSE_HELP; //TODO: What is the correct return
111                 }
112                 else if (strcmp("-a", argv[index]) == 0)
113                 {
114                         index++;
115                         if (index == argc)
116                         {
117                                 printf("missing color depth\n");
118                                 return FREERDP_ARGS_PARSE_FAILURE;
119                         }
120                         settings->color_depth = atoi(argv[index]);
121                 }
122                 else if (strcmp("-u", argv[index]) == 0)
123                 {
124                         index++;
125                         if (index == argc)
126                         {
127                                 printf("missing username\n");
128                                 return FREERDP_ARGS_PARSE_FAILURE;
129                         }
130                         settings->username = xstrdup(argv[index]);
131                 }
132                 else if (strcmp("-p", argv[index]) == 0)
133                 {
134                         index++;
135                         if (index == argc)
136                         {
137                                 printf("missing password\n");
138                                 return FREERDP_ARGS_PARSE_FAILURE;
139                         }
140                         settings->password = xstrdup(argv[index]);
141                         settings->autologon = 1;
142
143                         /*
144                          * Overwrite original password which could be revealed by a simple "ps aux" command.
145                          * This approach won't hide the password length, but it is better than nothing.
146                          */
147
148                         memset(argv[index], '*', strlen(argv[index]));
149                 }
150                 else if (strcmp("-d", argv[index]) == 0)
151                 {
152                         index++;
153                         if (index == argc)
154                         {
155                                 printf("missing domain\n");
156                                 return FREERDP_ARGS_PARSE_FAILURE;
157                         }
158                         settings->domain = xstrdup(argv[index]);
159                 }
160                 else if (strcmp("-s", argv[index]) == 0)
161                 {
162                         index++;
163                         if (index == argc)
164                         {
165                                 printf("missing shell\n");
166                                 return FREERDP_ARGS_PARSE_FAILURE;
167                         }
168                         settings->shell = xstrdup(argv[index]);
169                 }
170                 else if (strcmp("-c", argv[index]) == 0)
171                 {
172                         index++;
173                         if (index == argc)
174                         {
175                                 printf("missing directory\n");
176                                 return FREERDP_ARGS_PARSE_FAILURE;
177                         }
178                         settings->directory = xstrdup(argv[index]);
179                 }
180                 else if (strcmp("-g", argv[index]) == 0)
181                 {
182                         index++;
183                         if (index == argc)
184                         {
185                                 printf("missing dimensions\n");
186                                 return FREERDP_ARGS_PARSE_FAILURE;
187                         }
188
189                         if (strncmp("workarea", argv[index], 1) == 0)
190                         {
191                                 settings->workarea = true;
192                         }
193                         else
194                         {
195                                 settings->width = (uint16) strtol(argv[index], &p, 10);
196
197                                 if (*p == 'x')
198                                 {
199                                         settings->height = (uint16) strtol(p + 1, &p, 10);
200                                 }
201                                 if (*p == '%')
202                                 {
203                                         settings->percent_screen = settings->width;
204                                         if (settings->percent_screen <= 0 || settings->percent_screen > 100)
205                                         {
206                                                 printf("invalid geometry percentage\n");
207                                                 return FREERDP_ARGS_PARSE_FAILURE;
208                                         }
209                                 }
210                                 else
211                                 {
212                                         if (ui_callback != NULL)
213                                                 ui_callback(settings, "-g", p, ui_user_data);
214                                 }
215                         }
216                 }
217                 else if (strcmp("-f", argv[index]) == 0)
218                 {
219                         settings->fullscreen = true;
220                 }
221                 else if (strcmp("-D", argv[index]) == 0)
222                 {
223                         settings->decorations = false;
224                 }
225                 else if (strcmp("-T", argv[index]) == 0)
226                 {
227                         index++;
228                         if (index == argc)
229                         {
230                                 printf("missing window title\n");
231                                 return FREERDP_ARGS_PARSE_FAILURE;
232                         }
233
234                         settings->window_title = xstrdup(argv[index]);
235                 }
236                 else if (strcmp("-t", argv[index]) == 0)
237                 {
238                         index++;
239                         if (index == argc)
240                         {
241                                 printf("missing port number\n");
242                                 return FREERDP_ARGS_PARSE_FAILURE;
243                         }
244                         settings->port = atoi(argv[index]);
245                 }
246                 else if (strcmp("-k", argv[index]) == 0)
247                 {
248                         index++;
249                         if (index == argc)
250                         {
251                                 printf("missing keyboard layout id\n");
252                                 return FREERDP_ARGS_PARSE_FAILURE;
253                         }
254                         sscanf(argv[index], "%X", &(settings->kbd_layout));
255                 }
256                 else if (strcmp("-K", argv[index]) == 0)
257                 {
258                         settings->grab_keyboard = false;
259                 }
260                 else if (strcmp("-n", argv[index]) == 0)
261                 {
262                         index++;
263                         if (index == argc)
264                         {
265                                 printf("missing client hostname\n");
266                                 return FREERDP_ARGS_PARSE_FAILURE;
267                         }
268                         strncpy(settings->client_hostname, argv[index], sizeof(settings->client_hostname) - 1);
269                         settings->client_hostname[sizeof(settings->client_hostname) - 1] = 0;
270                 }
271                 else if (strcmp("-o", argv[index]) == 0)
272                 {
273                         settings->console_audio = true;
274                 }
275                 else if (strcmp("-0", argv[index]) == 0)
276                 {
277                         settings->console_session = true;
278                 }
279                 else if (strcmp("-z", argv[index]) == 0)
280                 {
281                         settings->compression = true;
282                 }
283                 else if (strcmp("--ntlm", argv[index]) == 0)
284                 {
285                         index++;
286
287                         settings->ntlm_version = atoi(argv[index]);
288
289                         if (settings->ntlm_version != 2)
290                                 settings->ntlm_version = 1;
291                 }
292                 else if (strcmp("--no-glyph-cache", argv[index]) == 0)
293                 {
294                         settings->glyph_cache = false;
295                 }
296                 else if (strcmp("--no-osb", argv[index]) == 0)
297                 {
298                         settings->offscreen_bitmap_cache = false;
299                 }
300                 else if (strcmp("--no-bmp-cache", argv[index]) == 0)
301                 {
302                         settings->bitmap_cache = false;
303                 }
304                 else if (strcmp("--no-auth", argv[index]) == 0)
305                 {
306                         settings->authentication = false;
307                 }
308                 else if (strcmp("--ignore-certificate", argv[index]) == 0)
309                 {
310                         settings->ignore_certificate = true;
311                 }
312                 else if (strcmp("--certificate-name", argv[index]) == 0)
313                 {
314                         index++;
315                         if (index == argc)
316                         {
317                                 printf("missing certificate name\n");
318                                 return FREERDP_ARGS_PARSE_FAILURE;
319                         }
320
321                         settings->certificate_name = xstrdup(argv[index]);
322                 }
323                 else if (strcmp("--no-fastpath", argv[index]) == 0)
324                 {
325                         settings->fastpath_input = false;
326                         settings->fastpath_output = false;
327                 }
328                 else if (strcmp("--gdi", argv[index]) == 0)
329                 {
330                         index++;
331                         if (index == argc)
332                         {
333                                 printf("missing GDI backend\n");
334                                 return FREERDP_ARGS_PARSE_FAILURE;
335                         }
336                         if (strncmp("sw", argv[index], 1) == 0) /* software */
337                         {
338                                 settings->sw_gdi = true;
339                         }
340                         else if (strncmp("hw", argv[index], 1) == 0) /* hardware */
341                         {
342                                 settings->sw_gdi = false;
343                         }
344                         else
345                         {
346                                 printf("unknown GDI backend\n");
347                                 return FREERDP_ARGS_PARSE_FAILURE;
348                         }
349                 }
350                 else if (strcmp("--rfx", argv[index]) == 0)
351                 {
352                         settings->rfx_codec = true;
353                         settings->fastpath_output = true;
354                         settings->color_depth = 32;
355                         settings->frame_acknowledge = false;
356                         settings->performance_flags = PERF_FLAG_NONE;
357                         settings->large_pointer = true;
358                 }
359                 else if (strcmp("--rfx-mode", argv[index]) == 0)
360                 {
361                         index++;
362                         if (index == argc)
363                         {
364                                 printf("missing RemoteFX mode flag\n");
365                                 return FREERDP_ARGS_PARSE_FAILURE;
366                         }
367                         if (argv[index][0] == 'v') /* video */
368                         {
369                                 settings->rfx_codec_mode = 0x00;
370                         }
371                         else if (argv[index][0] == 'i') /* image */
372                         {
373                                 settings->rfx_codec_mode = 0x02;
374                         }
375                         else
376                         {
377                                 printf("unknown RemoteFX mode flag\n");
378                                 return FREERDP_ARGS_PARSE_FAILURE;
379                         }
380                 }
381                 else if (strcmp("--nsc", argv[index]) == 0)
382                 {
383                         settings->ns_codec = true;
384                 }
385                 else if (strcmp("--dump-rfx", argv[index]) == 0)
386                 {
387                         index++;
388                         if (index == argc)
389                         {
390                                 printf("missing file name\n");
391                                 return FREERDP_ARGS_PARSE_FAILURE;
392                         }
393                         settings->dump_rfx_file = xstrdup(argv[index]);
394                         settings->dump_rfx = true;
395                 }
396                 else if (strcmp("--play-rfx", argv[index]) == 0)
397                 {
398                         index++;
399                         if (index == argc)
400                         {
401                                 printf("missing file name\n");
402                                 return FREERDP_ARGS_PARSE_FAILURE;
403                         }
404                         settings->play_rfx_file = xstrdup(argv[index]);
405                         settings->play_rfx = true;
406                 }
407                 else if (strcmp("--fonts", argv[index]) == 0)
408                 {
409                         settings->smooth_fonts = true;
410                 }
411                 else if (strcmp("--disable-wallpaper", argv[index]) == 0)
412                 {
413                         settings->disable_wallpaper = true;
414                 }
415                 else if (strcmp("--disable-full-window-drag", argv[index]) == 0)
416                 {
417                         settings->disable_full_window_drag = true;
418                 }
419                 else if (strcmp("--disable-menu-animations", argv[index]) == 0)
420                 {
421                         settings->disable_menu_animations = true;
422                 }
423                 else if (strcmp("--disable-theming", argv[index]) == 0)
424                 {
425                         settings->disable_theming = true;
426                 }
427                 else if (strcmp("--composition", argv[index]) == 0)
428                 {
429                         settings->desktop_composition = true;
430                 }
431                 else if (strcmp("--no-motion", argv[index]) == 0)
432                 {
433                         settings->mouse_motion = false;
434                 }
435                 else if (strcmp("--app", argv[index]) == 0)
436                 {
437                         settings->remote_app = true;
438                         settings->rail_langbar_supported = true;
439                         settings->workarea = true;
440                         settings->performance_flags = PERF_DISABLE_WALLPAPER | PERF_DISABLE_FULLWINDOWDRAG;
441                 }
442                 else if (strcmp("-x", argv[index]) == 0)
443                 {
444                         index++;
445                         if (index == argc)
446                         {
447                                 printf("missing performance flag\n");
448                                 return FREERDP_ARGS_PARSE_FAILURE;
449                         }
450                         if (argv[index][0] == 'm') /* modem */
451                         {
452                                 settings->performance_flags = PERF_DISABLE_WALLPAPER |
453                                         PERF_DISABLE_FULLWINDOWDRAG | PERF_DISABLE_MENUANIMATIONS |
454                                         PERF_DISABLE_THEMING;
455
456                                 settings->connection_type = CONNECTION_TYPE_MODEM;
457                         }
458                         else if (argv[index][0] == 'b') /* broadband */
459                         {
460                                 settings->performance_flags = PERF_DISABLE_WALLPAPER;
461                                 settings->connection_type = CONNECTION_TYPE_BROADBAND_HIGH;
462                         }
463                         else if (argv[index][0] == 'l') /* lan */
464                         {
465                                 settings->performance_flags = PERF_FLAG_NONE;
466                                 settings->connection_type = CONNECTION_TYPE_LAN;
467                         }
468                         else
469                         {
470                                 settings->performance_flags = strtol(argv[index], 0, 16);
471                         }
472                 }
473                 else if (strcmp("-X", argv[index]) == 0)
474                 {
475                         index++;
476
477                         if (index == argc)
478                         {
479                                 printf("missing parent window XID\n");
480                                 return FREERDP_ARGS_PARSE_FAILURE;
481                         }
482
483                         settings->parent_window_xid = strtoul(argv[index], NULL, 16);
484
485                         if (settings->parent_window_xid == 0)
486                         {
487                                 printf("invalid parent window XID\n");
488                                 return FREERDP_ARGS_PARSE_FAILURE;
489                         }
490                 }
491                 else if (strcmp("--no-rdp", argv[index]) == 0)
492                 {
493                         settings->rdp_security = false;
494                 }
495                 else if (strcmp("--no-tls", argv[index]) == 0)
496                 {
497                         settings->tls_security = false;
498                 }
499                 else if (strcmp("--no-nla", argv[index]) == 0)
500                 {
501                         settings->nla_security = false;
502                 }
503                 else if (strcmp("--sec", argv[index]) == 0)
504                 {
505                         index++;
506                         if (index == argc)
507                         {
508                                 printf("missing protocol security\n");
509                                 return FREERDP_ARGS_PARSE_FAILURE;
510                         }
511                         if (strncmp("rdp", argv[index], 1) == 0) /* Standard RDP */
512                         {
513                                 settings->rdp_security = true;
514                                 settings->tls_security = false;
515                                 settings->nla_security = false;
516                                 settings->encryption = true;
517                                 settings->encryption_method = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS;
518                                 settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
519                         }
520                         else if (strncmp("tls", argv[index], 1) == 0) /* TLS */
521                         {
522                                 settings->rdp_security = false;
523                                 settings->tls_security = true;
524                                 settings->nla_security = false;
525                         }
526                         else if (strncmp("nla", argv[index], 1) == 0) /* NLA */
527                         {
528                                 settings->rdp_security = false;
529                                 settings->tls_security = false;
530                                 settings->nla_security = true;
531                         }
532                         else
533                         {
534                                 printf("unknown protocol security\n");
535                                 return FREERDP_ARGS_PARSE_FAILURE;
536                         }
537                 }
538                 else if (strcmp("--no-nego", argv[index]) == 0)
539                 {
540                         settings->security_layer_negotiation = false;
541                 }
542                 else if (strcmp("--plugin", argv[index]) == 0)
543                 {
544                         index++;
545                         t = index;
546                         if (index == argc)
547                         {
548                                 printf("missing plugin name\n");
549                                 return FREERDP_ARGS_PARSE_FAILURE;
550                         }
551                         plugin_data = NULL;
552                         if (index < argc - 1 && strcmp("--data", argv[index + 1]) == 0)
553                         {
554                                 index += 2;
555                                 i = 0;
556                                 while (index < argc && strcmp("--", argv[index]) != 0)
557                                 {
558                                         if (plugin_data == NULL)
559                                                 plugin_data = (RDP_PLUGIN_DATA*) xmalloc(sizeof(RDP_PLUGIN_DATA) * (i + 2));
560                                         else
561                                                 plugin_data = (RDP_PLUGIN_DATA*) xrealloc(plugin_data, sizeof(RDP_PLUGIN_DATA) * (i + 2));
562
563                                         plugin_data[i].size = sizeof(RDP_PLUGIN_DATA);
564                                         plugin_data[i].data[0] = NULL;
565                                         plugin_data[i].data[1] = NULL;
566                                         plugin_data[i].data[2] = NULL;
567                                         plugin_data[i].data[3] = NULL;
568                                         plugin_data[i + 1].size = 0;
569
570                                         for (j = 0, p = argv[index]; j < 4 && p != NULL; j++)
571                                         {
572                                                 if (*p == '\'')
573                                                 {
574                                                         plugin_data[i].data[j] = p + 1;
575                                                         p = strchr(p + 1, '\'');
576                                                         if (p)
577                                                                 *p++ = 0;
578                                                 }
579                                                 else
580                                                         plugin_data[i].data[j] = p;
581
582                                                 p = strchr(p, ':');
583                                                 if (p != NULL)
584                                                         *p++ = 0;
585                                         }
586                                         index++;
587                                         i++;
588                                 }
589                         }
590
591                         if (plugin_callback != NULL)
592                         {
593                                 if (!plugin_callback(settings, argv[t], plugin_data, plugin_user_data))
594                                         return FREERDP_ARGS_PARSE_FAILURE;
595                         }
596                 }
597                 else if (strcmp("--ext", argv[index]) == 0)
598                 {
599                         index++;
600                         if (index == argc)
601                         {
602                                 printf("missing extension name\n");
603                                 return FREERDP_ARGS_PARSE_FAILURE;
604                         }
605                         if (num_extensions >= sizeof(settings->extensions) / sizeof(struct rdp_ext_set))
606                         {
607                                 printf("maximum extensions reached\n");
608                                 return FREERDP_ARGS_PARSE_FAILURE;
609                         }
610                         snprintf(settings->extensions[num_extensions].name,
611                                 sizeof(settings->extensions[num_extensions].name),
612                                 "%s", argv[index]);
613                         settings->extensions[num_extensions].data = NULL;
614                         if (index < argc - 1 && strcmp("--data", argv[index + 1]) == 0)
615                         {
616                                 index += 2;
617                                 settings->extensions[num_extensions].data = argv[index];
618                                 i = 0;
619                                 while (index < argc && strcmp("--", argv[index]) != 0)
620                                 {
621                                         index++;
622                                         i++;
623                                 }
624                         }
625                         num_extensions++;
626                 }
627                 else if (strcmp("--secure-checksum", argv[index]) == 0)
628                 {
629                         settings->secure_checksum = true;
630                 }
631                 else if (strcmp("--pcid", argv[index]) == 0)
632                 {
633                         index++;
634                         if (index == argc)
635                         {
636                                 printf("missing preconnection id value\n");
637                                 return -1;
638                         }
639                         settings->send_preconnection_pdu = true;
640                         settings->preconnection_id = atoi(argv[index]);
641                 }
642                 else if (strcmp("--pcb", argv[index]) == 0)
643                 {
644                         index++;
645                         if (index == argc)
646                         {
647                                 printf("missing preconnection blob value\n");
648                                 return -1;
649                         }
650                         settings->send_preconnection_pdu = true;
651                         settings->preconnection_blob = xstrdup(argv[index]);
652                 }
653                 else if (strcmp("--version", argv[index]) == 0)
654                 {
655                         printf("This is FreeRDP version %s\n", FREERDP_VERSION_FULL);
656                         return FREERDP_ARGS_PARSE_VERSION;
657                 }
658                 else if (argv[index][0] != '-')
659                 {
660                         if (argv[index][0] == '[' && (p = strchr(argv[index], ']'))
661                                 && (p[1] == 0 || (p[1] == ':' && !strchr(p + 2, ':'))))
662                         {
663                                 /* Either "[...]" or "[...]:..." with at most one : after the brackets */
664                                 settings->hostname = xstrdup(argv[index] + 1);
665                                 if ((p = strchr((char*)settings->hostname, ']')))
666                                 {
667                                         *p = 0;
668                                         if (p[1] == ':')
669                                                 settings->port = atoi(p + 2);
670                                 }
671                         }
672                         else
673                         {
674                                 /* Port number is cut off and used if exactly one : in the string */
675                                 settings->hostname = xstrdup(argv[index]);
676                                 if ((p = strchr((char*)settings->hostname, ':')) && !strchr(p + 1, ':'))
677                                 {
678                                         *p = 0;
679                                         settings->port = atoi(p + 1);
680                                 }
681                         }
682                         /* server is the last argument for the current session. arguments
683                            followed will be parsed for the next session. */
684                         index++;
685
686                         if (settings->smooth_fonts)
687                                 settings->performance_flags |= PERF_ENABLE_FONT_SMOOTHING;
688
689                         if (settings->desktop_composition)
690                                 settings->performance_flags |= PERF_ENABLE_DESKTOP_COMPOSITION;
691
692                         if (settings->disable_wallpaper)
693                                 settings->performance_flags |= PERF_DISABLE_WALLPAPER;
694
695                         if (settings->disable_full_window_drag)
696                                 settings->performance_flags |= PERF_DISABLE_FULLWINDOWDRAG;
697
698                         if (settings->disable_menu_animations)
699                                 settings->performance_flags |= PERF_DISABLE_MENUANIMATIONS;
700
701                         if (settings->disable_theming)
702                                 settings->performance_flags |= PERF_DISABLE_THEMING;
703
704                         return index;
705                 }
706                 else
707                 {
708                         if (ui_callback != NULL)
709                         {
710                                 t = ui_callback(settings, argv[index], (index + 1 < argc && argv[index + 1][0] != '-' ?
711                                         argv[index + 1] : NULL), ui_user_data);
712                                 if (t == 0)
713                                 {
714                                         printf("invalid option: %s\n", argv[index]);
715                                         return FREERDP_ARGS_PARSE_FAILURE;
716                                 }
717                                 index += t - 1;
718                         }
719                 }
720                 index++;
721         }
722         printf("missing server name\n");
723         return FREERDP_ARGS_PARSE_FAILURE;
724 }