]> cygwin.com Git - cygwin-apps/cygutils.git/blame - src/mkshortcut/mkshortcut.c
Add new -R/--raw option to readshortcut
[cygwin-apps/cygutils.git] / src / mkshortcut / mkshortcut.c
CommitLineData
c4453a3d 1/* mkshortcut.c -- create a Windows shortcut
0bb67178 2 *
0bb67178
CW
3 * Copyright (c) 2002 Joshua Daniel Franklin
4 *
3a076f8e
CW
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
0bb67178
CW
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
3a076f8e 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0bb67178
CW
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
3a076f8e 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
0bb67178 17 *
3a076f8e 18 * See the COPYING file for full license information.
0bb67178
CW
19 *
20 * Exit values
21 * 1: user error (syntax error)
22 * 2: system error (out of memory, etc.)
23 * 3: windows error (interface failed)
c4453a3d
CW
24 *
25 * Compile with: gcc -o prog.exe mkshortcut.c -lpopt -lole32 -luuid
7ab0751f 26 * (You'd need to uncomment the moved to common.h lines.)
0bb67178
CW
27 *
28 */
c4453a3d 29
0bb67178 30#if HAVE_CONFIG_H
fe3a7d70 31# include "config.h"
b96d6602 32#endif
0bb67178 33#include "common.h"
5f56ef9c
CW
34
35#define NOCOMATTRIBUTE
36
37#include <shlobj.h>
38#include <olectlid.h>
0bb67178
CW
39/* moved to common.h */
40/*
5f56ef9c 41#include <stdio.h>
c4453a3d 42#include <popt.h>
0bb67178 43*/
d2d984ab 44#include <sys/cygwin.h>
0bb67178 45
b96d6602 46static const char versionID[] = PACKAGE_VERSION;
0bb67178 47static const char revID[] =
7ab0751f 48 "$Id$";
0bb67178 49static const char copyrightID[] =
7ab0751f 50 "Copyright (c) 2002\nJoshua Daniel Franklin. All rights reserved.\nLicensed under GPL v2.0\n";
5f56ef9c 51
fe3a7d70
CW
52typedef struct optvals_s
53{
c4453a3d
CW
54 int icon_flag;
55 int unix_flag;
56 int windows_flag;
57 int allusers_flag;
58 int desktop_flag;
59 int smprograms_flag;
6d007d60 60 int show_flag;
c4453a3d 61 int offset;
fe3a7d70
CW
62 char *name_arg;
63 char *desc_arg;
64 char *dir_name_arg;
65 char *argument_arg;
66 char *target_arg;
67 char *icon_name_arg;
c4453a3d 68} optvals;
5f56ef9c 69
a4905427 70static int mkshortcut (optvals opts);
fe3a7d70
CW
71static void printTopDescription (FILE * f, char *name);
72static void printBottomDescription (FILE * f, char *name);
73static const char *getVersion ();
a4905427
CW
74static void usage (FILE * f, char *name);
75static void help (FILE * f, char *name);
76static void version (FILE * f, char *name);
77static void license (FILE * f, char *name);
c4453a3d
CW
78
79static char *program_name;
a4905427 80static poptContext optCon;
c4453a3d
CW
81
82int
83main (int argc, const char **argv)
7ab0751f 84{
fe3a7d70 85 const char **rest;
c4453a3d
CW
86 int rc;
87 int ec = 0;
88 optvals opts;
89
90 const char *tmp_str;
91 int icon_offset_flag;
92 char icon_name[MAX_PATH];
fe3a7d70 93 const char *arg;
c4453a3d
CW
94
95 struct poptOption helpOptionsTable[] = {
fe3a7d70
CW
96 {"help", 'h', POPT_ARG_NONE, NULL, '?',
97 "Show this help message", NULL},
98 {"usage", '\0', POPT_ARG_NONE, NULL, 'u',
99 "Display brief usage message", NULL},
100 {"version", 'v', POPT_ARG_NONE, NULL, 'v',
101 "Display version information", NULL},
102 {"license", '\0', POPT_ARG_NONE, NULL, 'l',
103 "Display licensing information", NULL},
104 {NULL, '\0', 0, NULL, 0, NULL, NULL}
c4453a3d
CW
105 };
106
107 struct poptOption generalOptionsTable[] = {
fe3a7d70
CW
108 {"arguments", 'a', POPT_ARG_STRING, NULL, 'a',
109 "Use arguments ARGS", "ARGS"},
110 {"desc", 'd', POPT_ARG_STRING, NULL, 'd',
111 "Text for description/tooltip (defaults to POSIX path of TARGET)",
112 "DESC"},
113 {"icon", 'i', POPT_ARG_STRING, NULL, 'i',
114 "Icon file for link to use", "ICONFILE"},
115 {"iconoffset", 'j', POPT_ARG_INT, &(opts.offset), 'j',
116 "Offset of icon in icon file (default is 0)", NULL},
117 {"name", 'n', POPT_ARG_STRING, NULL, 'n',
118 "Name for link (defaults to TARGET)", "NAME"},
119 {"show", 's', POPT_ARG_STRING, NULL, 's',
120 "Window to show: normal, minimized, maximized", "norm|min|max"},
121 {"workingdir", 'w', POPT_ARG_STRING, NULL, 'w',
122 "Set working directory (defaults to directory path of TARGET)", "PATH"},
123 {"allusers", 'A', POPT_ARG_VAL, &(opts.allusers_flag), 1,
124 "Use 'All Users' instead of current user for -D,-P", NULL},
125 {"desktop", 'D', POPT_ARG_VAL, &(opts.desktop_flag), 1,
126 "Create link relative to 'Desktop' directory", NULL},
127 {"smprograms", 'P', POPT_ARG_VAL, &(opts.smprograms_flag), 1,
128 "Create link relative to Start Menu 'Programs' directory", NULL},
129 {NULL, '\0', 0, NULL, 0, NULL, NULL}
c4453a3d 130 };
fe3a7d70 131
c4453a3d 132 struct poptOption opt[] = {
fe3a7d70
CW
133 {NULL, '\0', POPT_ARG_INCLUDE_TABLE, generalOptionsTable, 0,
134 "General options", NULL},
135 {NULL, '\0', POPT_ARG_INCLUDE_TABLE, helpOptionsTable, 0,
136 "Help options", NULL},
137 {NULL, '\0', 0, NULL, 0, NULL, NULL}
c4453a3d
CW
138 };
139
140 tmp_str = strrchr (argv[0], '/');
fe3a7d70
CW
141 if (tmp_str == NULL)
142 {
143 tmp_str = strrchr (argv[0], '\\');
144 }
145 if (tmp_str == NULL)
146 {
147 tmp_str = argv[0];
148 }
149 else
150 {
151 tmp_str++;
152 }
153 if ((program_name = strdup (tmp_str)) == NULL)
154 {
155 fprintf (stderr, "%s: memory allocation error\n", argv[0]);
156 exit (2);
157 }
c4453a3d
CW
158
159 icon_offset_flag = 0;
160
161 opts.offset = 0;
162 opts.icon_flag = 0;
163 opts.unix_flag = 0;
164 opts.windows_flag = 0;
165 opts.allusers_flag = 0;
166 opts.desktop_flag = 0;
167 opts.smprograms_flag = 0;
6d007d60 168 opts.show_flag = SW_SHOWNORMAL;
c4453a3d
CW
169 opts.target_arg = NULL;
170 opts.argument_arg = NULL;
171 opts.name_arg = NULL;
08cb7edc 172 opts.desc_arg = NULL;
b2682e03 173 opts.dir_name_arg = NULL;
c4453a3d
CW
174 opts.icon_name_arg = NULL;
175
176 /* Parse options */
fe3a7d70
CW
177 optCon = poptGetContext (NULL, argc, argv, opt, 0);
178 poptSetOtherOptionHelp (optCon, "[OPTION]* TARGET");
179 while ((rc = poptGetNextOpt (optCon)) > 0)
180 {
181 switch (rc)
182 {
183 case '?':
a4905427 184 help (stdout, program_name);
fe3a7d70
CW
185 goto exit;
186 case 'u':
a4905427 187 usage (stdout, program_name);
fe3a7d70
CW
188 goto exit;
189 case 'v':
a4905427 190 version (stdout, program_name);
fe3a7d70
CW
191 goto exit;
192 case 'l':
a4905427 193 license (stdout, program_name);
fe3a7d70
CW
194 goto exit;
195 case 'd':
196 if (arg = poptGetOptArg (optCon))
197 {
198 if ((opts.desc_arg = strdup (arg)) == NULL)
199 {
200 fprintf (stderr, "%s: memory allocation error\n",
201 program_name);
202 ec = 2;
203 goto exit;
204 }
205 }
206 break;
207 case 'i':
208 opts.icon_flag = 1;
209 if (arg = poptGetOptArg (optCon))
210 {
211 cygwin_conv_to_full_win32_path (arg, icon_name);
212 if ((opts.icon_name_arg = strdup (icon_name)) == NULL)
213 {
214 fprintf (stderr, "%s: memory allocation error\n",
215 program_name);
216 ec = 2;
217 goto exit;
218 }
219 }
220 break;
221 case 'j':
222 icon_offset_flag = 1;
223 break;
224 case 'n':
225 if (arg = poptGetOptArg (optCon))
226 {
227 if ((opts.name_arg = strdup (arg)) == NULL)
228 {
229 fprintf (stderr, "%s: memory allocation error\n",
230 program_name);
231 ec = 2;
232 goto exit;
233 }
234 }
235 break;
236 case 's':
237 if (arg = poptGetOptArg (optCon))
238 {
239 if (strcmp (arg, "min") == 0)
240 {
241 opts.show_flag = SW_SHOWMINNOACTIVE;
242 }
243 else if (strcmp (arg, "max") == 0)
244 {
245 opts.show_flag = SW_SHOWMAXIMIZED;
246 }
247 else if (strcmp (arg, "norm") == 0)
248 {
249 opts.show_flag = SW_SHOWNORMAL;
250 }
251 else
252 {
253 fprintf (stderr, "%s: %s not valid for show window\n",
254 program_name, arg);
255 ec = 2;
256 goto exit;
257 }
258 }
259 break;
260 case 'w':
261 if (arg = poptGetOptArg (optCon))
262 {
263 if ((opts.dir_name_arg = strdup (arg)) == NULL)
264 {
265 fprintf (stderr, "%s: memory allocation error\n",
266 program_name);
267 ec = 2;
268 goto exit;
269 }
270 }
271 break;
272 case 'a':
273 if (arg = poptGetOptArg (optCon))
274 {
275 if ((opts.argument_arg = strdup (arg)) == NULL)
276 {
277 fprintf (stderr, "%s: memory allocation error\n",
278 program_name);
279 ec = 2;
280 goto exit;
281 }
282 }
283 break;
284 // case 'A'
285 // case 'D'
286 // case 'P' all handled by popt itself
287 }
288 }
289
290 if (icon_offset_flag & !opts.icon_flag)
291 {
292 fprintf (stderr,
293 "%s: --iconoffset|-j only valid in conjuction with --icon|-i\n",
294 program_name);
a4905427 295 usage (stderr, program_name);
fe3a7d70 296 ec = 1;
c4453a3d 297 goto exit;
7ab0751f 298 }
fe3a7d70
CW
299
300 if (opts.smprograms_flag && opts.desktop_flag)
301 {
302 fprintf (stderr,
303 "%s: --smprograms|-P not valid in conjuction with --desktop|-D\n",
304 program_name);
a4905427 305 usage (stderr, program_name);
fe3a7d70
CW
306 ec = 1;
307 goto exit;
308 }
309
310 if (rc < -1)
311 {
312 fprintf (stderr, "%s: bad argument %s: %s\n",
313 program_name, poptBadOption (optCon, POPT_BADOPTION_NOALIAS),
314 poptStrerror (rc));
315 ec = 1;
316 goto exit;
317 }
318
319 rest = poptGetArgs (optCon);
320
321 if (rest && *rest)
322 {
323 if ((opts.target_arg = strdup (*rest)) == NULL)
324 {
325 fprintf (stderr, "%s: memory allocation error\n", program_name);
326 ec = 2;
327 goto exit;
328 }
329 rest++;
330 if (rest && *rest)
331 {
332 fprintf (stderr, "%s: Too many arguments: ", program_name);
333 while (*rest)
334 fprintf (stderr, "%s ", *rest++);
335 fprintf (stderr, "\n");
a4905427 336 usage (stderr, program_name);
fe3a7d70
CW
337 ec = 1;
338 }
339 else
340 {
341 // THE MEAT GOES HERE
a4905427 342 ec = mkshortcut (opts);
fe3a7d70
CW
343 }
344 }
345 else
346 {
347 fprintf (stderr, "%s: TARGET not specified\n", program_name);
a4905427 348 usage (stderr, program_name);
fe3a7d70 349 ec = 1;
08cb7edc 350 }
c4453a3d
CW
351
352exit:
fe3a7d70
CW
353 poptFreeContext (optCon);
354 if (opts.target_arg)
355 {
356 free (opts.target_arg);
357 }
358 if (opts.name_arg)
359 {
360 free (opts.name_arg);
361 }
362 if (opts.desc_arg)
363 {
364 free (opts.desc_arg);
365 }
366 if (opts.dir_name_arg)
367 {
368 free (opts.dir_name_arg);
369 }
370 if (opts.argument_arg)
371 {
372 free (opts.argument_arg);
373 }
374 if (opts.icon_name_arg)
375 {
376 free (opts.icon_name_arg);
377 }
378 free (program_name);
379 return (ec);
7ab0751f
CW
380}
381
fe3a7d70 382int
a4905427 383mkshortcut (optvals opts)
5f56ef9c 384{
7ab0751f
CW
385 char link_name[MAX_PATH];
386 char exe_name[MAX_PATH];
387 char dir_name[MAX_PATH];
08cb7edc 388 char desc[MAX_PATH];
c4453a3d
CW
389 char *buf_str, *tmp_str;
390 int tmp;
7ab0751f
CW
391
392 /* For OLE interface */
5f56ef9c
CW
393 LPITEMIDLIST id;
394 HRESULT hres;
7ab0751f
CW
395 IShellLink *shell_link;
396 IPersistFile *persist_file;
5f56ef9c
CW
397 WCHAR widepath[MAX_PATH];
398
7ab0751f 399 buf_str = (char *) malloc (PATH_MAX);
fe3a7d70
CW
400 if (buf_str == NULL)
401 {
402 fprintf (stderr, "%s: out of memory\n", program_name);
403 return (2);
404 }
5f56ef9c 405
7ab0751f 406 /* If there's a colon in the TARGET, it should be a URL */
c4453a3d 407 if (strchr (opts.target_arg, ':') != NULL)
7ab0751f
CW
408 {
409 /* Nope, somebody's trying a W32 path */
fe3a7d70
CW
410 if (opts.target_arg[1] == ':')
411 {
412 free (buf_str);
413 fprintf (stderr, "%s: all paths must be in POSIX format\n",
414 program_name);
a4905427 415 usage (stderr, program_name);
fe3a7d70
CW
416 return (1);
417 }
c4453a3d 418 strcpy (exe_name, opts.target_arg);
fe3a7d70 419 dir_name[0] = '\0'; /* No working dir for URL */
7ab0751f
CW
420 }
421 /* Convert TARGET to win32 path */
5f56ef9c 422 else
7ab0751f 423 {
c4453a3d 424 strcpy (buf_str, opts.target_arg);
7ab0751f 425 cygwin_conv_to_full_win32_path (buf_str, exe_name);
5f56ef9c 426
b2682e03
CW
427 /* Get a working dir from 'w' option */
428 if (opts.dir_name_arg != NULL)
429 {
430 if (strchr (opts.dir_name_arg, ':') != NULL)
431 {
08cb7edc 432 free (buf_str);
fe3a7d70
CW
433 fprintf (stderr, "%s: all paths must be in POSIX format\n",
434 program_name);
a4905427 435 usage (stderr, program_name);
fe3a7d70 436 return (1);
b2682e03
CW
437 }
438 cygwin_conv_to_win32_path (opts.dir_name_arg, dir_name);
439 }
7ab0751f 440 /* Get a working dir from the exepath */
b2682e03
CW
441 else
442 {
443 tmp_str = strrchr (exe_name, '\\');
444 tmp = strlen (exe_name) - strlen (tmp_str);
445 strncpy (dir_name, exe_name, tmp);
446 dir_name[tmp] = '\0';
447 }
7ab0751f 448 }
5f56ef9c 449
7ab0751f 450 /* Generate a name for the link if not given */
c4453a3d 451 if (opts.name_arg == NULL)
5f56ef9c 452 {
7ab0751f 453 /* Strip trailing /'s if any */
c4453a3d 454 strcpy (buf_str, opts.target_arg);
7ab0751f
CW
455 tmp_str = buf_str;
456 tmp = strlen (buf_str) - 1;
457 while (strrchr (buf_str, '/') == (buf_str + tmp))
fe3a7d70
CW
458 {
459 buf_str[tmp] = '\0';
460 tmp--;
461 }
7ab0751f
CW
462 /* Get basename */
463 while (*buf_str)
fe3a7d70
CW
464 {
465 if (*buf_str == '/')
466 tmp_str = buf_str + 1;
467 buf_str++;
468 }
7ab0751f 469 strcpy (link_name, tmp_str);
fe3a7d70 470 }
7ab0751f
CW
471 /* User specified a name, so check it and convert */
472 else
5f56ef9c 473 {
c4453a3d 474 if (opts.desktop_flag || opts.smprograms_flag)
fe3a7d70
CW
475 {
476 /* Cannot have absolute path relative to Desktop/SM Programs */
477 if (opts.name_arg[0] == '/')
478 {
479 free (buf_str);
480 fprintf (stderr,
481 "%s: absolute pathnames not allowed with -D/-P\n",
482 program_name);
a4905427 483 usage (stderr, program_name);
fe3a7d70
CW
484 return (1);
485 }
486 }
7ab0751f 487 /* Sigh. Another W32 path */
fe3a7d70
CW
488 if (strchr (opts.name_arg, ':') != NULL)
489 {
490 free (buf_str);
491 fprintf (stderr, "%s: all paths must be in POSIX format\n",
492 program_name);
a4905427 493 usage (stderr, program_name);
fe3a7d70
CW
494 return (1);
495 }
c4453a3d 496 cygwin_conv_to_win32_path (opts.name_arg, link_name);
fe3a7d70 497 }
7ab0751f
CW
498
499 /* Add suffix to link name if necessary */
500 if (strlen (link_name) > 4)
5f56ef9c 501 {
7ab0751f
CW
502 tmp = strlen (link_name) - 4;
503 if (strncmp (link_name + tmp, ".lnk", 4) != 0)
fe3a7d70 504 strcat (link_name, ".lnk");
5f56ef9c 505 }
7ab0751f
CW
506 else
507 strcat (link_name, ".lnk");
5f56ef9c 508
7ab0751f 509 /* Prepend relative path if necessary */
c4453a3d 510 if (opts.desktop_flag)
7ab0751f
CW
511 {
512 strcpy (buf_str, link_name);
c4453a3d 513 if (!opts.allusers_flag)
fe3a7d70 514 SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOPDIRECTORY, &id);
7ab0751f 515 else
fe3a7d70 516 SHGetSpecialFolderLocation (NULL, CSIDL_COMMON_DESKTOPDIRECTORY, &id);
7ab0751f
CW
517 SHGetPathFromIDList (id, link_name);
518 /* Make sure Win95 without "All Users" has output */
519 if (strlen (link_name) == 0)
fe3a7d70
CW
520 {
521 SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOPDIRECTORY, &id);
522 SHGetPathFromIDList (id, link_name);
523 }
7ab0751f
CW
524 strcat (link_name, "\\");
525 strcat (link_name, buf_str);
5f56ef9c 526 }
5f56ef9c 527
c4453a3d 528 if (opts.smprograms_flag)
7ab0751f
CW
529 {
530 strcpy (buf_str, link_name);
c4453a3d 531 if (!opts.allusers_flag)
fe3a7d70 532 SHGetSpecialFolderLocation (NULL, CSIDL_PROGRAMS, &id);
7ab0751f 533 else
fe3a7d70 534 SHGetSpecialFolderLocation (NULL, CSIDL_COMMON_PROGRAMS, &id);
7ab0751f
CW
535 SHGetPathFromIDList (id, link_name);
536 /* Make sure Win95 without "All Users" has output */
537 if (strlen (link_name) == 0)
fe3a7d70
CW
538 {
539 SHGetSpecialFolderLocation (NULL, CSIDL_PROGRAMS, &id);
540 SHGetPathFromIDList (id, link_name);
541 }
7ab0751f
CW
542 strcat (link_name, "\\");
543 strcat (link_name, buf_str);
5f56ef9c 544 }
5f56ef9c 545
08cb7edc
CW
546 /* Setup description text */
547 if (opts.desc_arg != NULL)
548 {
549 strncpy (desc, opts.desc_arg, MAX_PATH);
550
551 /* There won't be a null terminated if strlen(desc_arg)>MAX_PATH */
88041160 552 desc[MAX_PATH - 1] = '\0';
08cb7edc
CW
553 }
554 else
555 {
556 /* Put the POSIX path in the "Description", just to be nice */
557 cygwin_conv_to_full_posix_path (exe_name, desc);
558 }
559
7ab0751f
CW
560 /* Beginning of Windows interface */
561 hres = OleInitialize (NULL);
562 if (hres != S_FALSE && hres != S_OK)
fe3a7d70 563 {
08cb7edc 564 free (buf_str);
fe3a7d70
CW
565 fprintf (stderr, "%s: Could not initialize OLE interface\n",
566 program_name);
c4453a3d 567 return (3);
7ab0751f 568 }
5f56ef9c 569
7ab0751f
CW
570 hres =
571 CoCreateInstance (&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
fe3a7d70 572 &IID_IShellLink, (void **) &shell_link);
7ab0751f 573 if (SUCCEEDED (hres))
5f56ef9c 574 {
7ab0751f 575 hres =
fe3a7d70
CW
576 shell_link->lpVtbl->QueryInterface (shell_link, &IID_IPersistFile,
577 (void **) &persist_file);
7ab0751f 578 if (SUCCEEDED (hres))
fe3a7d70
CW
579 {
580 shell_link->lpVtbl->SetPath (shell_link, exe_name);
581 shell_link->lpVtbl->SetDescription (shell_link, desc);
582 shell_link->lpVtbl->SetWorkingDirectory (shell_link, dir_name);
583 if (opts.argument_arg)
584 shell_link->lpVtbl->SetArguments (shell_link, opts.argument_arg);
585 if (opts.icon_flag)
586 shell_link->lpVtbl->SetIconLocation (shell_link,
587 opts.icon_name_arg,
588 opts.offset);
6d007d60 589 if (opts.show_flag != SW_SHOWNORMAL)
fe3a7d70
CW
590 shell_link->lpVtbl->SetShowCmd (shell_link, opts.show_flag);
591
592
593 /* Make link name Unicode-compliant */
594 hres =
595 MultiByteToWideChar (CP_ACP, 0, link_name, -1, widepath,
596 MAX_PATH);
597 if (!SUCCEEDED (hres))
598 {
599 free (buf_str);
600 fprintf (stderr, "%s: Unicode translation failed%d\n",
601 program_name, hres);
602 return (3);
603 }
604 hres = persist_file->lpVtbl->Save (persist_file, widepath, TRUE);
605 if (!SUCCEEDED (hres))
606 {
607 free (buf_str);
608 fprintf (stderr,
609 "%s: Saving \"%s\" failed; does the target directory exist?\n",
610 program_name, link_name);
611 return (3);
612 }
613 persist_file->lpVtbl->Release (persist_file);
614 shell_link->lpVtbl->Release (shell_link);
d2d984ab
CW
615
616 /* If we are creating shortcut for all users, ensure it is readable by all users */
617 if (opts.allusers_flag)
618 {
619 char *posixpath = (char *) cygwin_create_path (
620 CCP_WIN_W_TO_POSIX | CCP_ABSOLUTE, widepath);
621 if (posixpath && *posixpath)
622 {
623 struct stat statbuf;
624 if (stat(posixpath, &statbuf))
625 {
626 fprintf (stderr,
627 "%s: stat \"%s\" failed\n",
628 program_name, posixpath);
629 }
630 else if (chmod(posixpath, statbuf.st_mode|S_IRUSR|S_IRGRP|S_IROTH))
631 {
632 fprintf (stderr,
633 "%s: chmod \"%s\" failed\n",
634 program_name, posixpath);
635 }
636 }
637 free(posixpath);
638 }
639
3d86489d 640 return (0);
fe3a7d70 641 }
7ab0751f 642 else
fe3a7d70
CW
643 {
644 free (buf_str);
645 fprintf (stderr, "%s: QueryInterface failed\n", program_name);
646 return (3);
647 }
5f56ef9c 648 }
7ab0751f 649 else
b96d6602 650 {
08cb7edc 651 free (buf_str);
c4453a3d
CW
652 fprintf (stderr, "%s: CoCreateInstance failed\n", program_name);
653 return (3);
5f56ef9c 654 }
c4453a3d
CW
655}
656
fe3a7d70
CW
657static const char *
658getVersion ()
c4453a3d 659{
b96d6602 660 return versionID;
c4453a3d
CW
661}
662
fe3a7d70
CW
663static void
664printTopDescription (FILE * f, char *name)
c4453a3d
CW
665{
666 char s[20];
fe3a7d70
CW
667 fprintf (f, "%s is part of cygutils version %s\n", name, getVersion ());
668 fprintf (f, " create a Windows shortcut\n\n");
c4453a3d 669}
fe3a7d70
CW
670static void
671printBottomDescription (FILE * f, char *name)
c4453a3d 672{
fe3a7d70
CW
673 fprintf (f,
674 "\nNOTE: All filename arguments must be in unix (POSIX) format\n");
c4453a3d 675}
fe3a7d70
CW
676
677static
678printLicense (FILE * f, char *name)
c4453a3d 679{
fe3a7d70 680 fprintf (f,
3a076f8e
CW
681 "This program is free software: you can redistribute it and/or modify\n"
682 "it under the terms of the GNU General Public License as published by\n"
683 "the Free Software Foundation, either version 3 of the License, or\n"
684 "(at your option) any later version.\n\n"
685 "This program is distributed in the hope that it will be useful,\n"
686 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
687 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
688 "GNU General Public License for more details.\n\n"
689 "You should have received a copy of the GNU General Public License\n"
690 "along with this program. If not, see <http://www.gnu.org/licenses/>.\n\n"
691 "See the COPYING file for full license information.\n");
c4453a3d 692}
3a076f8e 693
fe3a7d70 694static void
a4905427 695usage (FILE * f, char *name)
c4453a3d 696{
fe3a7d70 697 poptPrintUsage (optCon, f, 0);
c4453a3d 698}
7ab0751f 699
fe3a7d70 700static void
a4905427 701help (FILE * f, char *name)
c4453a3d 702{
fe3a7d70
CW
703 printTopDescription (f, name);
704 poptPrintHelp (optCon, f, 0);
705 printBottomDescription (f, name);
c4453a3d
CW
706}
707
fe3a7d70 708static void
a4905427 709version (FILE * f, char *name)
c4453a3d 710{
fe3a7d70
CW
711 printTopDescription (f, name);
712 fprintf (f, copyrightID);
5f56ef9c 713}
c4453a3d 714
fe3a7d70 715static void
a4905427 716license (FILE * f, char *name)
c4453a3d 717{
fe3a7d70
CW
718 printTopDescription (f, name);
719 printLicense (f, name);
720}
This page took 0.109507 seconds and 5 git commands to generate.