ole32: Fix some leaks (coverity).
[wine] / programs / hostname / hostname.c
1 /*
2  * Hostname display utility
3  *
4  * Copyright 2008 Andrew Riedi
5  * Copyright 2010-2011 Andrew Nguyen
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include "config.h"
23 #include "wine/port.h"
24
25 #include <stdarg.h>
26 #if defined(__MINGW32__) || defined (_MSC_VER)
27 #include <winsock2.h>
28 #elif defined(HAVE_UNISTD_H)
29 #include <unistd.h>
30 #endif
31
32 #include <windef.h>
33 #include <winbase.h>
34 #include <wincon.h>
35 #include <winnls.h>
36 #include <winuser.h>
37
38 #include <wine/unicode.h>
39
40 #include "hostname.h"
41
42 static int hostname_vprintfW(const WCHAR *msg, va_list va_args)
43 {
44     int wlen;
45     DWORD count, ret;
46     WCHAR msg_buffer[8192];
47
48     wlen = vsprintfW(msg_buffer, msg, va_args);
49
50     ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), msg_buffer, wlen, &count, NULL);
51     if (!ret)
52     {
53         DWORD len;
54         char *msgA;
55
56         /* On Windows WriteConsoleW() fails if the output is redirected. So fall
57          * back to WriteFile(), assuming the console encoding is still the right
58          * one in that case.
59          */
60         len = WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen,
61             NULL, 0, NULL, NULL);
62         msgA = HeapAlloc(GetProcessHeap(), 0, len);
63         if (!msgA)
64             return 0;
65
66         WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen, msgA, len,
67             NULL, NULL);
68         WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE);
69         HeapFree(GetProcessHeap(), 0, msgA);
70     }
71
72     return count;
73 }
74
75 static int hostname_printfW(const WCHAR *msg, ...)
76 {
77     va_list va_args;
78     int len;
79
80     va_start(va_args, msg);
81     len = hostname_vprintfW(msg, va_args);
82     va_end(va_args);
83
84     return len;
85 }
86
87 static int hostname_message_printfW(int msg, ...)
88 {
89     va_list va_args;
90     WCHAR msg_buffer[8192];
91     int len;
92
93     LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
94         sizeof(msg_buffer)/sizeof(WCHAR));
95
96     va_start(va_args, msg);
97     len = hostname_vprintfW(msg_buffer, va_args);
98     va_end(va_args);
99
100     return len;
101 }
102
103 static int hostname_message(int msg)
104 {
105     static const WCHAR formatW[] = {'%','s',0};
106     WCHAR msg_buffer[8192];
107
108     LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
109         sizeof(msg_buffer)/sizeof(WCHAR));
110
111     return hostname_printfW(formatW, msg_buffer);
112 }
113
114 static void display_computer_name(void)
115 {
116     static const WCHAR fmtW[] = {'%','s','\r','\n',0};
117
118     char nameA[256];
119     WCHAR nameW[256];
120
121     gethostname(nameA, sizeof(nameA));
122     MultiByteToWideChar(CP_UNIXCP, 0, nameA, sizeof(nameA), nameW, sizeof(nameW)/sizeof(WCHAR));
123
124     hostname_printfW(fmtW, nameW);
125 }
126
127 int wmain(int argc, WCHAR *argv[])
128 {
129     if (argc > 1)
130     {
131         static const WCHAR slashHelpW[] = {'/','?',0};
132
133         unsigned int i;
134
135         if (!strncmpW(argv[1], slashHelpW, sizeof(slashHelpW)/sizeof(WCHAR) - 1))
136         {
137             hostname_message(STRING_USAGE);
138             return 1;
139         }
140
141         for (i = 1; i < argc; i++)
142         {
143             if (argv[i][0] == '-')
144             {
145                 switch (argv[i][1])
146                 {
147                     case 's':
148                         /* Ignore the option and continue processing. */
149                         break;
150                     case '?':
151                         hostname_message(STRING_USAGE);
152                         return 1;
153                     default:
154                         hostname_message_printfW(STRING_INVALID_OPTION, argv[i][1]);
155                         hostname_message(STRING_USAGE);
156                         return 1;
157                 }
158             }
159             else
160             {
161                 hostname_message(STRING_CANNOT_SET_HOSTNAME);
162                 hostname_message(STRING_USAGE);
163                 return 1;
164             }
165         }
166     }
167
168     display_computer_name();
169
170     return 0;
171 }