net: Rename functable3 to functable, get rid of old functables
[kai/samba.git] / source3 / utils / net_rpc_service.c
1 /*
2    Samba Unix/Linux SMB client library
3    Distributed SMB/CIFS Server Management Utility
4    Copyright (C) Gerald (Jerry) Carter          2005
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18
19 #include "includes.h"
20 #include "utils/net.h"
21
22
23 struct svc_state_msg {
24         uint32 flag;
25         const char *message;
26 };
27
28 static struct svc_state_msg state_msg_table[] = {
29         { SVCCTL_STOPPED,            "stopped" },
30         { SVCCTL_START_PENDING,      "start pending" },
31         { SVCCTL_STOP_PENDING,       "stop pending" },
32         { SVCCTL_RUNNING,            "running" },
33         { SVCCTL_CONTINUE_PENDING,   "resume pending" },
34         { SVCCTL_PAUSE_PENDING,      "pause pending" },
35         { SVCCTL_PAUSED,             "paused" },
36         { 0,                          NULL }
37 };
38
39
40 /********************************************************************
41 ********************************************************************/
42 const char *svc_status_string( uint32 state )
43 {
44         fstring msg;
45         int i;
46
47         fstr_sprintf( msg, "Unknown State [%d]", state );
48
49         for ( i=0; state_msg_table[i].message; i++ ) {
50                 if ( state_msg_table[i].flag == state ) {
51                         fstrcpy( msg, state_msg_table[i].message );
52                         break;
53                 }
54         }
55
56         return talloc_strdup(talloc_tos(), msg);
57 }
58
59 /********************************************************************
60 ********************************************************************/
61
62 static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd,
63                                 TALLOC_CTX *mem_ctx,
64                                 POLICY_HND *hSCM,
65                                 const char *service,
66                                 uint32 *state )
67 {
68         POLICY_HND hService;
69         SERVICE_STATUS service_status;
70         WERROR result = WERR_GENERAL_FAILURE;
71         NTSTATUS status;
72
73         /* now cycle until the status is actually 'watch_state' */
74
75         status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
76                                             hSCM,
77                                             service,
78                                             SC_RIGHT_SVC_QUERY_STATUS,
79                                             &hService,
80                                             &result);
81         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
82                 d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
83                 return result;
84         }
85
86         status = rpccli_svcctl_QueryServiceStatus(pipe_hnd, mem_ctx,
87                                                   &hService,
88                                                   &service_status,
89                                                   &result);
90
91         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
92                 *state = service_status.state;
93         }
94
95         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
96
97         return result;
98 }
99
100 /********************************************************************
101 ********************************************************************/
102
103 static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd,
104                                 TALLOC_CTX *mem_ctx,
105                                 POLICY_HND *hSCM,
106                                 const char *service,
107                                 uint32 watch_state,
108                                 uint32 *final_state )
109 {
110         uint32 i;
111         uint32 state = 0;
112         WERROR result = WERR_GENERAL_FAILURE;
113
114
115         i = 0;
116         while ( (state != watch_state ) && i<30 ) {
117                 /* get the status */
118
119                 result = query_service_state(pipe_hnd, mem_ctx, hSCM, service, &state  );
120                 if ( !W_ERROR_IS_OK(result) ) {
121                         break;
122                 }
123
124                 d_printf(".");
125                 i++;
126                 sys_usleep( 100 );
127         }
128         d_printf("\n");
129
130         *final_state = state;
131
132         return result;
133 }
134
135 /********************************************************************
136 ********************************************************************/
137
138 static WERROR control_service(struct rpc_pipe_client *pipe_hnd,
139                                 TALLOC_CTX *mem_ctx,
140                                 POLICY_HND *hSCM,
141                                 const char *service,
142                                 uint32 control,
143                                 uint32 watch_state )
144 {
145         POLICY_HND hService;
146         WERROR result = WERR_GENERAL_FAILURE;
147         NTSTATUS status;
148         SERVICE_STATUS service_status;
149         uint32 state = 0;
150
151         /* Open the Service */
152
153         status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
154                                             hSCM,
155                                             service,
156                                             (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE),
157                                             &hService,
158                                             &result);
159
160         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
161                 d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
162                 goto done;
163         }
164
165         /* get the status */
166
167         status = rpccli_svcctl_ControlService(pipe_hnd, mem_ctx,
168                                               &hService,
169                                               control,
170                                               &service_status,
171                                               &result);
172
173         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
174                 d_fprintf(stderr, "Control service request failed.  [%s]\n", dos_errstr(result));
175                 goto done;
176         }
177
178         /* loop -- checking the state until we are where we want to be */
179
180         result = watch_service_state(pipe_hnd, mem_ctx, hSCM, service, watch_state, &state );
181
182         d_printf("%s service is %s.\n", service, svc_status_string(state));
183
184 done:
185         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
186
187         return result;
188 }
189
190 /********************************************************************
191 ********************************************************************/
192
193 static NTSTATUS rpc_service_list_internal(struct net_context *c,
194                                         const DOM_SID *domain_sid,
195                                         const char *domain_name,
196                                         struct cli_state *cli,
197                                         struct rpc_pipe_client *pipe_hnd,
198                                         TALLOC_CTX *mem_ctx,
199                                         int argc,
200                                         const char **argv )
201 {
202         POLICY_HND hSCM;
203         ENUM_SERVICES_STATUS *services;
204         WERROR result = WERR_GENERAL_FAILURE;
205         NTSTATUS status;
206         fstring servicename;
207         fstring displayname;
208         uint32 num_services = 0;
209         int i;
210
211         if (argc != 0 ) {
212                 d_printf("Usage: net rpc service list\n");
213                 return NT_STATUS_OK;
214         }
215
216         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
217                                               pipe_hnd->srv_name_slash,
218                                               NULL,
219                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
220                                               &hSCM,
221                                               &result);
222         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
223                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
224                 return werror_to_ntstatus(result);
225         }
226
227         result = rpccli_svcctl_enumerate_services(pipe_hnd, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32,
228                 SVCCTL_STATE_ALL, &num_services, &services );
229
230         if ( !W_ERROR_IS_OK(result) ) {
231                 d_fprintf(stderr, "Failed to enumerate services.  [%s]\n", dos_errstr(result));
232                 goto done;
233         }
234
235         if ( num_services == 0 )
236                 d_printf("No services returned\n");
237
238         for ( i=0; i<num_services; i++ ) {
239                 rpcstr_pull( servicename, services[i].servicename.buffer, sizeof(servicename), -1, STR_TERMINATE );
240                 rpcstr_pull( displayname, services[i].displayname.buffer, sizeof(displayname), -1, STR_TERMINATE );
241
242                 d_printf("%-20s    \"%s\"\n", servicename, displayname);
243         }
244
245 done:
246         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
247
248         return werror_to_ntstatus(result);
249 }
250
251 /********************************************************************
252 ********************************************************************/
253
254 static NTSTATUS rpc_service_status_internal(struct net_context *c,
255                                                 const DOM_SID *domain_sid,
256                                                 const char *domain_name,
257                                                 struct cli_state *cli,
258                                                 struct rpc_pipe_client *pipe_hnd,
259                                                 TALLOC_CTX *mem_ctx,
260                                                 int argc,
261                                                 const char **argv )
262 {
263         POLICY_HND hSCM, hService;
264         WERROR result = WERR_GENERAL_FAILURE;
265         NTSTATUS status;
266         SERVICE_STATUS service_status;
267         SERVICE_CONFIG config;
268         fstring ascii_string;
269
270         if (argc != 1 ) {
271                 d_printf("Usage: net rpc service status <service>\n");
272                 return NT_STATUS_OK;
273         }
274
275         /* Open the Service Control Manager */
276         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
277                                               pipe_hnd->srv_name_slash,
278                                               NULL,
279                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
280                                               &hSCM,
281                                               &result);
282         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
283                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
284                 return werror_to_ntstatus(result);
285         }
286
287         /* Open the Service */
288
289         status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
290                                             &hSCM,
291                                             argv[0],
292                                             (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG),
293                                             &hService,
294                                             &result);
295
296         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
297                 d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
298                 goto done;
299         }
300
301         /* get the status */
302
303         status = rpccli_svcctl_QueryServiceStatus(pipe_hnd, mem_ctx,
304                                                   &hService,
305                                                   &service_status,
306                                                   &result);
307
308         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
309                 d_fprintf(stderr, "Query status request failed.  [%s]\n", dos_errstr(result));
310                 goto done;
311         }
312
313         d_printf("%s service is %s.\n", argv[0], svc_status_string(service_status.state));
314
315         /* get the config */
316
317         result = rpccli_svcctl_query_config(pipe_hnd, mem_ctx, &hService, &config  );
318         if ( !W_ERROR_IS_OK(result) ) {
319                 d_fprintf(stderr, "Query config request failed.  [%s]\n", dos_errstr(result));
320                 goto done;
321         }
322
323         /* print out the configuration information for the service */
324
325         d_printf("Configuration details:\n");
326         d_printf("\tControls Accepted    = 0x%x\n", service_status.controls_accepted);
327         d_printf("\tService Type         = 0x%x\n", config.service_type);
328         d_printf("\tStart Type           = 0x%x\n", config.start_type);
329         d_printf("\tError Control        = 0x%x\n", config.error_control);
330         d_printf("\tTag ID               = 0x%x\n", config.tag_id);
331
332         if ( config.executablepath ) {
333                 rpcstr_pull( ascii_string, config.executablepath->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
334                 d_printf("\tExecutable Path      = %s\n", ascii_string);
335         }
336
337         if ( config.loadordergroup ) {
338                 rpcstr_pull( ascii_string, config.loadordergroup->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
339                 d_printf("\tLoad Order Group     = %s\n", ascii_string);
340         }
341
342         if ( config.dependencies ) {
343                 rpcstr_pull( ascii_string, config.dependencies->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
344                 d_printf("\tDependencies         = %s\n", ascii_string);
345         }
346
347         if ( config.startname ) {
348                 rpcstr_pull( ascii_string, config.startname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
349                 d_printf("\tStart Name           = %s\n", ascii_string);
350         }
351
352         if ( config.displayname ) {
353                 rpcstr_pull( ascii_string, config.displayname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
354                 d_printf("\tDisplay Name         = %s\n", ascii_string);
355         }
356
357 done:
358         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
359         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
360
361         return werror_to_ntstatus(result);
362 }
363
364 /********************************************************************
365 ********************************************************************/
366
367 static NTSTATUS rpc_service_stop_internal(struct net_context *c,
368                                         const DOM_SID *domain_sid,
369                                         const char *domain_name,
370                                         struct cli_state *cli,
371                                         struct rpc_pipe_client *pipe_hnd,
372                                         TALLOC_CTX *mem_ctx,
373                                         int argc,
374                                         const char **argv )
375 {
376         POLICY_HND hSCM;
377         WERROR result = WERR_GENERAL_FAILURE;
378         NTSTATUS status;
379         fstring servicename;
380
381         if (argc != 1 ) {
382                 d_printf("Usage: net rpc service status <service>\n");
383                 return NT_STATUS_OK;
384         }
385
386         fstrcpy( servicename, argv[0] );
387
388         /* Open the Service Control Manager */
389         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
390                                               pipe_hnd->srv_name_slash,
391                                               NULL,
392                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
393                                               &hSCM,
394                                               &result);
395         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
396                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
397                 return werror_to_ntstatus(result);
398         }
399
400         result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
401                 SVCCTL_CONTROL_STOP, SVCCTL_STOPPED );
402
403         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
404
405         return werror_to_ntstatus(result);
406 }
407
408 /********************************************************************
409 ********************************************************************/
410
411 static NTSTATUS rpc_service_pause_internal(struct net_context *c,
412                                         const DOM_SID *domain_sid,
413                                         const char *domain_name,
414                                         struct cli_state *cli,
415                                         struct rpc_pipe_client *pipe_hnd,
416                                         TALLOC_CTX *mem_ctx,
417                                         int argc,
418                                         const char **argv )
419 {
420         POLICY_HND hSCM;
421         WERROR result = WERR_GENERAL_FAILURE;
422         NTSTATUS status;
423         fstring servicename;
424
425         if (argc != 1 ) {
426                 d_printf("Usage: net rpc service status <service>\n");
427                 return NT_STATUS_OK;
428         }
429
430         fstrcpy( servicename, argv[0] );
431
432         /* Open the Service Control Manager */
433         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
434                                               pipe_hnd->srv_name_slash,
435                                               NULL,
436                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
437                                               &hSCM,
438                                               &result);
439         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
440                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
441                 return werror_to_ntstatus(result);
442         }
443
444         result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
445                 SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED );
446
447         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
448
449         return werror_to_ntstatus(result);
450 }
451
452 /********************************************************************
453 ********************************************************************/
454
455 static NTSTATUS rpc_service_resume_internal(struct net_context *c,
456                                         const DOM_SID *domain_sid,
457                                         const char *domain_name,
458                                         struct cli_state *cli,
459                                         struct rpc_pipe_client *pipe_hnd,
460                                         TALLOC_CTX *mem_ctx,
461                                         int argc,
462                                         const char **argv )
463 {
464         POLICY_HND hSCM;
465         WERROR result = WERR_GENERAL_FAILURE;
466         NTSTATUS status;
467         fstring servicename;
468
469         if (argc != 1 ) {
470                 d_printf("Usage: net rpc service status <service>\n");
471                 return NT_STATUS_OK;
472         }
473
474         fstrcpy( servicename, argv[0] );
475
476         /* Open the Service Control Manager */
477         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
478                                               pipe_hnd->srv_name_slash,
479                                               NULL,
480                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
481                                               &hSCM,
482                                               &result);
483         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
484                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
485                 return werror_to_ntstatus(result);
486         }
487
488         result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
489                 SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
490
491         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
492
493         return werror_to_ntstatus(result);
494 }
495
496 /********************************************************************
497 ********************************************************************/
498
499 static NTSTATUS rpc_service_start_internal(struct net_context *c,
500                                         const DOM_SID *domain_sid,
501                                         const char *domain_name,
502                                         struct cli_state *cli,
503                                         struct rpc_pipe_client *pipe_hnd,
504                                         TALLOC_CTX *mem_ctx,
505                                         int argc,
506                                         const char **argv )
507 {
508         POLICY_HND hSCM, hService;
509         WERROR result = WERR_GENERAL_FAILURE;
510         NTSTATUS status;
511         uint32 state = 0;
512
513         if (argc != 1 ) {
514                 d_printf("Usage: net rpc service status <service>\n");
515                 return NT_STATUS_OK;
516         }
517
518         /* Open the Service Control Manager */
519         status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx,
520                                               pipe_hnd->srv_name_slash,
521                                               NULL,
522                                               SC_RIGHT_MGR_ENUMERATE_SERVICE,
523                                               &hSCM,
524                                               &result);
525         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
526                 d_fprintf(stderr, "Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
527                 return werror_to_ntstatus(result);
528         }
529
530         /* Open the Service */
531
532         status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx,
533                                             &hSCM,
534                                             argv[0],
535                                             SC_RIGHT_SVC_START,
536                                             &hService,
537                                             &result);
538
539         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
540                 d_fprintf(stderr, "Failed to open service.  [%s]\n", dos_errstr(result));
541                 goto done;
542         }
543
544         /* get the status */
545
546         status = rpccli_svcctl_StartServiceW(pipe_hnd, mem_ctx,
547                                              &hService,
548                                              0,
549                                              NULL,
550                                              &result);
551
552         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) {
553                 d_fprintf(stderr, "Query status request failed.  [%s]\n", dos_errstr(result));
554                 goto done;
555         }
556
557         result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, argv[0], SVCCTL_RUNNING, &state  );
558
559         if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
560                 d_printf("Successfully started service: %s\n", argv[0] );
561         else
562                 d_fprintf(stderr, "Failed to start service: %s [%s]\n", argv[0], dos_errstr(result) );
563
564 done:
565         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL);
566         rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL);
567
568         return werror_to_ntstatus(result);
569 }
570
571 /********************************************************************
572 ********************************************************************/
573
574 static int rpc_service_list(struct net_context *c, int argc, const char **argv )
575 {
576         if (c->display_usage) {
577                 d_printf("Usage:\n"
578                          "net rpc service list\n"
579                          "    View configured Win32 services\n");
580                 return 0;
581         }
582
583         return run_rpc_command(c, NULL, PI_SVCCTL, 0,
584                 rpc_service_list_internal, argc, argv );
585 }
586
587 /********************************************************************
588 ********************************************************************/
589
590 static int rpc_service_start(struct net_context *c, int argc, const char **argv )
591 {
592         if (c->display_usage) {
593                 d_printf("Usage:\n"
594                          "net rpc service start <service>\n"
595                          "    Start a Win32 service\n");
596                 return 0;
597         }
598
599         return run_rpc_command(c, NULL, PI_SVCCTL, 0,
600                 rpc_service_start_internal, argc, argv );
601 }
602
603 /********************************************************************
604 ********************************************************************/
605
606 static int rpc_service_stop(struct net_context *c, int argc, const char **argv )
607 {
608         if (c->display_usage) {
609                 d_printf("Usage:\n"
610                          "net rpc service stop <service>\n"
611                          "    Stop a Win32 service\n");
612                 return 0;
613         }
614
615         return run_rpc_command(c, NULL, PI_SVCCTL, 0,
616                 rpc_service_stop_internal, argc, argv );
617 }
618
619 /********************************************************************
620 ********************************************************************/
621
622 static int rpc_service_resume(struct net_context *c, int argc, const char **argv )
623 {
624         if (c->display_usage) {
625                 d_printf("Usage:\n"
626                          "net rpc service resume <service>\n"
627                          "    Resume a Win32 service\n");
628                 return 0;
629         }
630
631         return run_rpc_command(c, NULL, PI_SVCCTL, 0,
632                 rpc_service_resume_internal, argc, argv );
633 }
634
635 /********************************************************************
636 ********************************************************************/
637
638 static int rpc_service_pause(struct net_context *c, int argc, const char **argv )
639 {
640         if (c->display_usage) {
641                 d_printf("Usage:\n"
642                          "net rpc service pause <service>\n"
643                          "    Pause a Win32 service\n");
644                 return 0;
645         }
646
647         return run_rpc_command(c, NULL, PI_SVCCTL, 0,
648                 rpc_service_pause_internal, argc, argv );
649 }
650
651 /********************************************************************
652 ********************************************************************/
653
654 static int rpc_service_status(struct net_context *c, int argc, const char **argv )
655 {
656         if (c->display_usage) {
657                 d_printf("Usage:\n"
658                          "net rpc service status <service>\n"
659                          "     Show the current status of a service\n");
660                 return 0;
661         }
662
663         return run_rpc_command(c, NULL, PI_SVCCTL, 0,
664                 rpc_service_status_internal, argc, argv );
665 }
666
667 /********************************************************************
668 ********************************************************************/
669
670 int net_rpc_service(struct net_context *c, int argc, const char **argv)
671 {
672         struct functable func[] = {
673                 {
674                         "list",
675                         rpc_service_list,
676                         NET_TRANSPORT_RPC,
677                         "View configured Win32 services",
678                         "net rpc service list\n"
679                         "    View configured Win32 services"
680                 },
681                 {
682                         "start",
683                         rpc_service_start,
684                         NET_TRANSPORT_RPC,
685                         "Start a service",
686                         "net rpc service start\n"
687                         "    Start a service"
688                 },
689                 {
690                         "stop",
691                         rpc_service_stop,
692                         NET_TRANSPORT_RPC,
693                         "Stop a service",
694                         "net rpc service stop\n"
695                         "    Stop a service"
696                 },
697                 {
698                         "pause",
699                         rpc_service_pause,
700                         NET_TRANSPORT_RPC,
701                         "Pause a service",
702                         "net rpc service pause\n"
703                         "    Pause a service"
704                 },
705                 {
706                         "resume",
707                         rpc_service_resume,
708                         NET_TRANSPORT_RPC,
709                         "Resume a paused service",
710                         "net rpc service resume\n"
711                         "    Resume a service"
712                 },
713                 {
714                         "status",
715                         rpc_service_status,
716                         NET_TRANSPORT_RPC,
717                         "View current status of a service",
718                         "net rpc service status\n"
719                         "    View current status of a service"
720                 },
721                 {NULL, NULL, 0, NULL, NULL}
722         };
723
724         return net_run_function(c, argc, argv, "net rpc service",func);
725 }