2 Unix SMB/CIFS implementation.
3 test suite for spoolss rpc operations
5 Copyright (C) Guenther Deschner 2009-2010
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program 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
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 /****************************************************************************
22 ****************************************************************************/
28 /****************************************************************************
29 ****************************************************************************/
31 static BOOL test_OpenPrinter(struct torture_context *tctx,
33 LPPRINTER_DEFAULTS defaults,
36 torture_comment(tctx, "Testing OpenPrinter(%s)", printername);
38 if (!OpenPrinter(printername, handle, defaults)) {
40 sprintf(tmp, "failed to open printer %s, error was: 0x%08x\n",
41 printername, GetLastError());
42 torture_fail(tctx, tmp);
48 /****************************************************************************
49 ****************************************************************************/
51 static BOOL test_ClosePrinter(struct torture_context *tctx,
54 torture_comment(tctx, "Testing ClosePrinter");
56 if (!ClosePrinter(handle)) {
58 sprintf(tmp, "failed to close printer, error was: %s\n",
59 errstr(GetLastError()));
60 torture_fail(tctx, tmp);
67 /****************************************************************************
68 ****************************************************************************/
70 static BOOL test_EnumPrinters(struct torture_context *tctx,
73 DWORD levels[] = { 1, 2, 5 };
74 DWORD success[] = { 1, 1, 1 };
76 DWORD flags = PRINTER_ENUM_NAME;
79 for (i=0; i < ARRAY_SIZE(levels); i++) {
86 torture_comment(tctx, "Testing EnumPrinters level %d", levels[i]);
88 EnumPrinters(flags, servername, levels[i], NULL, 0, &needed, &returned);
90 if (err == ERROR_INSUFFICIENT_BUFFER) {
92 buffer = malloc(needed);
93 torture_assert(tctx, buffer, "malloc failed");
94 if (!EnumPrinters(flags, servername, levels[i], buffer, needed, &needed, &returned)) {
99 sprintf(tmp, "EnumPrinters failed level %d on [%s] (buffer size = %d), error: %s\n",
100 levels[i], servername, needed, errstr(err));
102 torture_fail(tctx, tmp);
104 torture_warning(tctx, tmp);
109 print_printer_info_bylevel(levels[i], buffer, returned);
119 /****************************************************************************
120 ****************************************************************************/
122 static BOOL test_EnumDrivers(struct torture_context *tctx,
126 DWORD levels[] = { 1, 2, 3, 4, 5, 6 };
127 DWORD success[] = { 1, 1, 1, 1, 1, 1 };
129 LPBYTE buffer = NULL;
131 for (i=0; i < ARRAY_SIZE(levels); i++) {
138 torture_comment(tctx, "Testing EnumPrinterDrivers level %d", levels[i]);
140 EnumPrinterDrivers(servername, architecture, levels[i], NULL, 0, &needed, &returned);
141 err = GetLastError();
142 if (err == ERROR_INSUFFICIENT_BUFFER) {
144 buffer = malloc(needed);
145 torture_assert(tctx, buffer, "malloc failed");
146 if (!EnumPrinterDrivers(servername, architecture, levels[i], buffer, needed, &needed, &returned)) {
147 err = GetLastError();
151 sprintf(tmp, "EnumPrinterDrivers failed level %d on [%s] (buffer size = %d), error: %s\n",
152 levels[i], servername, needed, errstr(err));
154 torture_fail(tctx, tmp);
156 torture_warning(tctx, tmp);
161 print_driver_info_bylevel(levels[i], buffer, returned);
171 /****************************************************************************
172 ****************************************************************************/
174 static BOOL test_GetForm(struct torture_context *tctx,
179 DWORD levels[] = { 1, 2 };
180 DWORD success[] = { 1, 0 };
182 LPBYTE buffer = NULL;
184 for (i=0; i < ARRAY_SIZE(levels); i++) {
190 torture_comment(tctx, "Testing GetForm(%s) level %d", formname, levels[i]);
192 GetForm(handle, formname, levels[i], NULL, 0, &needed);
193 err = GetLastError();
194 if (err == ERROR_INSUFFICIENT_BUFFER) {
196 buffer = malloc(needed);
197 torture_assert(tctx, buffer, "malloc failed");
198 if (!GetForm(handle, formname, levels[i], buffer, needed, &needed)) {
199 err = GetLastError();
203 sprintf(tmp, "GetForm failed level %d on [%s] (buffer size = %d), error: %s\n",
204 levels[i], servername, needed, errstr(err));
206 torture_fail(tctx, tmp);
208 torture_warning(tctx, tmp);
219 /****************************************************************************
220 ****************************************************************************/
222 static BOOL test_EnumForms(struct torture_context *tctx,
226 DWORD levels[] = { 1, 2 };
227 DWORD success[] = { 1, 0 };
229 LPBYTE buffer = NULL;
231 for (i=0; i < ARRAY_SIZE(levels); i++) {
238 torture_comment(tctx, "Testing EnumForms level %d", levels[i]);
240 EnumForms(handle, levels[i], NULL, 0, &needed, &returned);
241 err = GetLastError();
242 if (err == ERROR_INSUFFICIENT_BUFFER) {
244 buffer = malloc(needed);
245 torture_assert(tctx, buffer, "malloc failed");
246 if (!EnumForms(handle, levels[i], buffer, needed, &needed, &returned)) {
247 err = GetLastError();
251 sprintf(tmp, "EnumForms failed level %d on [%s] (buffer size = %d), error: %s\n",
252 levels[i], servername, needed, errstr(err));
254 torture_fail(tctx, tmp);
256 torture_warning(tctx, tmp);
267 /****************************************************************************
268 ****************************************************************************/
270 static BOOL test_EnumPorts(struct torture_context *tctx,
273 DWORD levels[] = { 1, 2 };
274 DWORD success[] = { 1, 1 };
276 LPBYTE buffer = NULL;
278 for (i=0; i < ARRAY_SIZE(levels); i++) {
285 torture_comment(tctx, "Testing EnumPorts level %d", levels[i]);
287 EnumPorts(servername, levels[i], NULL, 0, &needed, &returned);
288 err = GetLastError();
289 if (err == ERROR_INSUFFICIENT_BUFFER) {
291 buffer = malloc(needed);
292 torture_assert(tctx, buffer, "malloc failed");
293 if (!EnumPorts(servername, levels[i], buffer, needed, &needed, &returned)) {
294 err = GetLastError();
298 sprintf(tmp, "EnumPorts failed level %d on [%s] (buffer size = %d), error: %s\n",
299 levels[i], servername, needed, errstr(err));
301 torture_fail(tctx, tmp);
303 torture_warning(tctx, tmp);
314 /****************************************************************************
315 ****************************************************************************/
317 static BOOL test_EnumMonitors(struct torture_context *tctx,
320 DWORD levels[] = { 1, 2 };
321 DWORD success[] = { 1, 1 };
323 LPBYTE buffer = NULL;
325 for (i=0; i < ARRAY_SIZE(levels); i++) {
332 torture_comment(tctx, "Testing EnumMonitors level %d", levels[i]);
334 EnumMonitors(servername, levels[i], NULL, 0, &needed, &returned);
335 err = GetLastError();
336 if (err == ERROR_INSUFFICIENT_BUFFER) {
338 buffer = malloc(needed);
339 torture_assert(tctx, buffer, "malloc failed");
340 if (!EnumMonitors(servername, levels[i], buffer, needed, &needed, &returned)) {
341 err = GetLastError();
345 sprintf(tmp, "EnumMonitors failed level %d on [%s] (buffer size = %d), error: %s\n",
346 levels[i], servername, needed, errstr(err));
348 torture_fail(tctx, tmp);
350 torture_warning(tctx, tmp);
361 /****************************************************************************
362 ****************************************************************************/
364 static BOOL test_EnumPrintProcessors(struct torture_context *tctx,
368 DWORD levels[] = { 1 };
369 DWORD success[] = { 1 };
371 LPBYTE buffer = NULL;
373 for (i=0; i < ARRAY_SIZE(levels); i++) {
380 torture_comment(tctx, "Testing EnumPrintProcessors level %d", levels[i]);
382 EnumPrintProcessors(servername, architecture, levels[i], NULL, 0, &needed, &returned);
383 err = GetLastError();
384 if (err == ERROR_INSUFFICIENT_BUFFER) {
386 buffer = malloc(needed);
387 torture_assert(tctx, buffer, "malloc failed");
388 if (!EnumPrintProcessors(servername, architecture, levels[i], buffer, needed, &needed, &returned)) {
389 err = GetLastError();
393 sprintf(tmp, "EnumPrintProcessors failed level %d on [%s] (buffer size = %d), error: %s\n",
394 levels[i], servername, needed, errstr(err));
396 torture_fail(tctx, tmp);
398 torture_warning(tctx, tmp);
409 /****************************************************************************
410 ****************************************************************************/
412 static BOOL test_EnumPrintProcessorDatatypes(struct torture_context *tctx,
415 DWORD levels[] = { 1 };
416 DWORD success[] = { 1 };
418 LPBYTE buffer = NULL;
420 for (i=0; i < ARRAY_SIZE(levels); i++) {
427 torture_comment(tctx, "Testing EnumPrintProcessorDatatypes level %d", levels[i]);
429 EnumPrintProcessorDatatypes(servername, "winprint", levels[i], NULL, 0, &needed, &returned);
430 err = GetLastError();
431 if (err == ERROR_INSUFFICIENT_BUFFER) {
433 buffer = malloc(needed);
434 torture_assert(tctx, buffer, "malloc failed");
435 if (!EnumPrintProcessorDatatypes(servername, "winprint", levels[i], buffer, needed, &needed, &returned)) {
436 err = GetLastError();
440 sprintf(tmp, "EnumPrintProcessorDatatypes failed level %d on [%s] (buffer size = %d), error: %s\n",
441 levels[i], servername, needed, errstr(err));
443 torture_fail(tctx, tmp);
445 torture_warning(tctx, tmp);
456 /****************************************************************************
457 ****************************************************************************/
459 static BOOL test_EnumPrinterKey(struct torture_context *tctx,
469 torture_comment(tctx, "Testing EnumPrinterKey(%s)", key);
471 err = EnumPrinterKey(handle, key, NULL, 0, &needed);
472 if (err == ERROR_MORE_DATA) {
473 buffer = (LPTSTR)malloc(needed);
474 torture_assert(tctx, buffer, "malloc failed");
475 err = EnumPrinterKey(handle, key, buffer, needed, &needed);
478 sprintf(tmp, "EnumPrinterKey(%s) failed on [%s] (buffer size = %d), error: %s\n",
479 key, servername, needed, errstr(err));
480 torture_fail(tctx, tmp);
484 print_printer_keys(buffer);
492 /****************************************************************************
493 ****************************************************************************/
495 static BOOL test_GetPrinter(struct torture_context *tctx,
499 DWORD levels[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
500 DWORD success[] = { 1, 1, 1, 1, 1, 1, 1, 1 };
502 LPBYTE buffer = NULL;
504 for (i=0; i < ARRAY_SIZE(levels); i++) {
510 torture_comment(tctx, "Testing GetPrinter level %d", levels[i]);
512 GetPrinter(handle, levels[i], NULL, 0, &needed);
513 err = GetLastError();
514 if (err == ERROR_INSUFFICIENT_BUFFER) {
516 buffer = malloc(needed);
517 torture_assert(tctx, buffer, "malloc failed");
518 if (!GetPrinter(handle, levels[i], buffer, needed, &needed)) {
519 err = GetLastError();
523 sprintf(tmp, "GetPrinter failed level %d on [%s] (buffer size = %d), error: %s\n",
524 levels[i], printername, needed, errstr(err));
526 torture_fail(tctx, tmp);
528 torture_warning(tctx, tmp);
533 print_printer_info_bylevel(levels[i], buffer, 1);
543 /****************************************************************************
544 ****************************************************************************/
546 static BOOL test_GetPrinterDriver(struct torture_context *tctx,
551 DWORD levels[] = { 1, 2, 3, 4, 5, 6, 8 };
552 DWORD success[] = { 1, 1, 1, 1, 1, 1, 1 };
554 LPBYTE buffer = NULL;
556 for (i=0; i < ARRAY_SIZE(levels); i++) {
562 torture_comment(tctx, "Testing GetPrinterDriver level %d", levels[i]);
564 GetPrinterDriver(handle, architecture, levels[i], NULL, 0, &needed);
565 err = GetLastError();
566 if (err == ERROR_INSUFFICIENT_BUFFER) {
568 buffer = malloc(needed);
569 torture_assert(tctx, buffer, "malloc failed");
570 if (!GetPrinterDriver(handle, architecture, levels[i], buffer, needed, &needed)) {
571 err = GetLastError();
575 sprintf(tmp, "GetPrinterDriver failed level %d on [%s] (buffer size = %d), error: %s\n",
576 levels[i], printername, needed, errstr(err));
578 torture_fail(tctx, tmp);
580 torture_warning(tctx, tmp);
585 print_driver_info_bylevel(levels[i], buffer, 1);
596 /****************************************************************************
597 ****************************************************************************/
599 static BOOL test_EnumJobs(struct torture_context *tctx,
603 DWORD levels[] = { 1, 2, 3, 4 };
604 DWORD success[] = { 1, 1, 1, 1 };
606 LPBYTE buffer = NULL;
608 for (i=0; i < ARRAY_SIZE(levels); i++) {
615 torture_comment(tctx, "Testing EnumJobs level %d", levels[i]);
617 EnumJobs(handle, 0, 100, levels[i], NULL, 0, &needed, &returned);
618 err = GetLastError();
619 if (err == ERROR_INSUFFICIENT_BUFFER) {
621 buffer = malloc(needed);
622 torture_assert(tctx, buffer, "malloc failed");
623 if (!EnumJobs(handle, 0, 100, levels[i], buffer, needed, &needed, &returned)) {
624 err = GetLastError();
628 sprintf(tmp, "EnumJobs failed level %d on [%s] (buffer size = %d), error: %s\n",
629 levels[i], printername, needed, errstr(err));
631 torture_fail(tctx, tmp);
633 torture_warning(tctx, tmp);
644 /****************************************************************************
645 ****************************************************************************/
647 static BOOL test_EnumPrinterDataEx(struct torture_context *tctx,
654 LPBYTE buffer = NULL;
660 torture_comment(tctx, "Testing EnumPrinterDataEx(%s)", keyname);
662 err = EnumPrinterDataEx(handle, keyname, NULL, 0, &needed, &returned);
663 if (err == ERROR_MORE_DATA) {
664 buffer = malloc(needed);
665 torture_assert(tctx, buffer, "malloc failed");
666 err = EnumPrinterDataEx(handle, keyname, buffer, needed, &needed, &returned);
669 sprintf(tmp, "EnumPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
670 keyname, servername, needed, errstr(err));
671 torture_fail(tctx, tmp);
676 LPPRINTER_ENUM_VALUES v = (LPPRINTER_ENUM_VALUES)buffer;
677 for (i=0; i < returned; i++) {
678 print_printer_enum_values(&v[i]);
683 *returned_p = returned;
696 /****************************************************************************
697 ****************************************************************************/
699 static BOOL test_OnePrinter(struct torture_context *tctx,
702 LPPRINTER_DEFAULTS defaults)
707 torture_comment(tctx, "Testing Printer %s", printername);
709 ret &= test_OpenPrinter(tctx, printername, defaults, &handle);
710 ret &= test_GetPrinter(tctx, printername, handle);
711 ret &= test_GetPrinterDriver(tctx, printername, architecture, handle);
712 ret &= test_EnumForms(tctx, printername, handle);
713 ret &= test_EnumJobs(tctx, printername, handle);
714 ret &= test_EnumPrinterKey(tctx, printername, handle, "");
715 ret &= test_EnumPrinterKey(tctx, printername, handle, "PrinterDriverData");
716 ret &= test_EnumPrinterDataEx(tctx, printername, "PrinterDriverData", handle, NULL, NULL);
717 ret &= test_ClosePrinter(tctx, handle);
722 /****************************************************************************
723 ****************************************************************************/
725 static BOOL test_EachPrinter(struct torture_context *tctx,
728 LPPRINTER_DEFAULTS defaults)
735 DWORD flags = PRINTER_ENUM_NAME;
736 PPRINTER_INFO_1 buffer = NULL;
739 torture_comment(tctx, "Testing EnumPrinters level %d", 1);
741 EnumPrinters(flags, servername, 1, NULL, 0, &needed, &returned);
742 err = GetLastError();
743 if (err == ERROR_INSUFFICIENT_BUFFER) {
745 buffer = (PPRINTER_INFO_1)malloc(needed);
746 torture_assert(tctx, buffer, "malloc failed");
747 if (!EnumPrinters(flags, servername, 1, (LPBYTE)buffer, needed, &needed, &returned)) {
748 err = GetLastError();
752 sprintf(tmp, "EnumPrinters failed level %d on [%s] (buffer size = %d), error: %s\n",
753 1, servername, needed, errstr(err));
754 torture_fail(tctx, tmp);
757 for (i=0; i < returned; i++) {
758 ret &= test_OnePrinter(tctx, buffer[i].pName, architecture, defaults);
766 /****************************************************************************
767 ****************************************************************************/
769 static BOOL test_GetPrintProcessorDirectory(struct torture_context *tctx,
773 DWORD levels[] = { 1 };
774 DWORD success[] = { 1 };
776 LPBYTE buffer = NULL;
778 for (i=0; i < ARRAY_SIZE(levels); i++) {
784 torture_comment(tctx, "Testing GetPrintProcessorDirectory level %d", levels[i]);
786 GetPrintProcessorDirectory(servername, architecture, levels[i], NULL, 0, &needed);
787 err = GetLastError();
788 if (err == ERROR_INSUFFICIENT_BUFFER) {
790 buffer = malloc(needed);
791 torture_assert(tctx, buffer, "malloc failed");
792 if (!GetPrintProcessorDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
793 err = GetLastError();
797 sprintf(tmp, "GetPrintProcessorDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
798 levels[i], servername, needed, errstr(err));
800 torture_fail(tctx, tmp);
802 torture_warning(tctx, tmp);
813 /****************************************************************************
814 ****************************************************************************/
816 static BOOL test_GetPrinterDriverDirectory(struct torture_context *tctx,
820 DWORD levels[] = { 1 };
821 DWORD success[] = { 1 };
823 LPBYTE buffer = NULL;
825 for (i=0; i < ARRAY_SIZE(levels); i++) {
831 torture_comment(tctx, "Testing GetPrinterDriverDirectory level %d", levels[i]);
833 GetPrinterDriverDirectory(servername, architecture, levels[i], NULL, 0, &needed);
834 err = GetLastError();
835 if (err == ERROR_INSUFFICIENT_BUFFER) {
837 buffer = malloc(needed);
838 torture_assert(tctx, buffer, "malloc failed");
839 if (!GetPrinterDriverDirectory(servername, architecture, levels[i], buffer, needed, &needed)) {
840 err = GetLastError();
844 sprintf(tmp, "GetPrinterDriverDirectory failed level %d on [%s] (buffer size = %d), error: %s\n",
845 levels[i], servername, needed, errstr(err));
847 torture_fail(tctx, tmp);
849 torture_warning(tctx, tmp);
860 /****************************************************************************
861 ****************************************************************************/
863 static BOOL test_GetPrinterData(struct torture_context *tctx,
871 LPBYTE buffer = NULL;
877 torture_comment(tctx, "Testing GetPrinterData(%s)", valuename);
879 err = GetPrinterData(handle, valuename, &type, NULL, 0, &needed);
880 if (err == ERROR_MORE_DATA) {
881 buffer = (LPBYTE)malloc(needed);
882 torture_assert(tctx, buffer, "malloc failed");
883 err = GetPrinterData(handle, valuename, &type, buffer, needed, &needed);
886 sprintf(tmp, "GetPrinterData(%s) failed on [%s] (buffer size = %d), error: %s\n",
887 valuename, servername, needed, errstr(err));
888 torture_fail(tctx, tmp);
892 print_printer_data("PrinterDriverData", valuename, needed, buffer, type);
912 /****************************************************************************
913 ****************************************************************************/
915 static BOOL test_GetPrinterDataEx(struct torture_context *tctx,
924 LPBYTE buffer = NULL;
930 torture_comment(tctx, "Testing GetPrinterDataEx(%s - %s)", keyname, valuename);
932 err = GetPrinterDataEx(handle, keyname, valuename, &type, NULL, 0, &needed);
933 if (err == ERROR_MORE_DATA) {
934 buffer = (LPBYTE)malloc(needed);
935 torture_assert(tctx, buffer, "malloc failed");
936 err = GetPrinterDataEx(handle, keyname, valuename, &type, buffer, needed, &needed);
939 sprintf(tmp, "GetPrinterDataEx(%s) failed on [%s] (buffer size = %d), error: %s\n",
940 valuename, servername, needed, errstr(err));
941 torture_fail(tctx, tmp);
945 print_printer_data(keyname, valuename, needed, buffer, type);
965 /****************************************************************************
966 ****************************************************************************/
968 static BOOL test_PrinterData(struct torture_context *tctx,
975 LPBYTE buffer, buffer_ex;
977 LPSTR valuenames[] = {
978 SPLREG_DEFAULT_SPOOL_DIRECTORY,
979 SPLREG_MAJOR_VERSION,
980 SPLREG_MINOR_VERSION,
982 SPLREG_DNS_MACHINE_NAME,
987 for (i=0; i < ARRAY_SIZE(valuenames); i++) {
988 ret &= test_GetPrinterData(tctx, servername, valuenames[i], handle, &type, &buffer, &size);
989 ret &= test_GetPrinterDataEx(tctx, servername, "random", valuenames[i], handle, &type_ex, &buffer_ex, &size_ex);
990 torture_assert_int_equal(tctx, type, type_ex, "type mismatch");
991 torture_assert_int_equal(tctx, size, size_ex, "size mismatch");
992 torture_assert_mem_equal(tctx, buffer, buffer_ex, size, "buffer mismatch");
1000 /****************************************************************************
1001 ****************************************************************************/
1003 int main(int argc, char *argv[])
1007 LPSTR architecture = "Windows NT x86";
1008 HANDLE server_handle;
1009 PRINTER_DEFAULTS defaults_admin, defaults_use;
1010 struct torture_context *tctx;
1013 fprintf(stderr, "usage: %s <servername> [print]\n", argv[0]);
1017 tctx = malloc(sizeof(struct torture_context));
1019 fprintf(stderr, "out of memory\n");
1022 memset(tctx, '\0', sizeof(*tctx));
1024 servername = argv[1];
1027 if (strcmp(argv[2], "print") == 0) {
1032 defaults_admin.pDatatype = NULL;
1033 defaults_admin.pDevMode = NULL;
1034 defaults_admin.DesiredAccess = PRINTER_ACCESS_ADMINISTER;
1036 defaults_use.pDatatype = NULL;
1037 defaults_use.pDevMode = NULL;
1038 defaults_use.DesiredAccess = PRINTER_ACCESS_USE;
1040 ret &= test_EnumPrinters(tctx, servername);
1041 ret &= test_EnumDrivers(tctx, servername, architecture);
1042 ret &= test_OpenPrinter(tctx, servername, NULL, &server_handle);
1043 /* ret &= test_EnumPrinterKey(tctx, servername, server_handle, ""); */
1044 ret &= test_PrinterData(tctx, servername, server_handle);
1045 ret &= test_EnumForms(tctx, servername, server_handle);
1046 ret &= test_ClosePrinter(tctx, server_handle);
1047 ret &= test_EnumPorts(tctx, servername);
1048 ret &= test_EnumMonitors(tctx, servername);
1049 ret &= test_EnumPrintProcessors(tctx, servername, architecture);
1050 ret &= test_EnumPrintProcessorDatatypes(tctx, servername);
1051 ret &= test_GetPrintProcessorDirectory(tctx, servername, architecture);
1052 ret &= test_GetPrinterDriverDirectory(tctx, servername, architecture);
1053 ret &= test_EachPrinter(tctx, servername, architecture, NULL);
1056 if (tctx->last_reason) {
1057 fprintf(stderr, "failed: %s\n", tctx->last_reason);
1063 printf("%s run successfully\n", argv[0]);