s3:net: use dcerpc_spoolss_X() functions
[samba.git] / source3 / utils / net_g_lock.c
1 /*
2  * Samba Unix/Linux SMB client library
3  * Interface to the g_lock facility
4  * Copyright (C) Volker Lendecke 2009
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
20 #include "includes.h"
21 #include "net.h"
22 #include "g_lock.h"
23
24 static bool net_g_lock_init(TALLOC_CTX *mem_ctx,
25                             struct tevent_context **pev,
26                             struct messaging_context **pmsg,
27                             struct g_lock_ctx **pg_ctx)
28 {
29         struct tevent_context *ev = NULL;
30         struct messaging_context *msg = NULL;
31         struct g_lock_ctx *g_ctx = NULL;
32
33         ev = tevent_context_init(mem_ctx);
34         if (ev == NULL) {
35                 d_fprintf(stderr, "ERROR: could not init event context\n");
36                 goto fail;
37         }
38         msg = messaging_init(mem_ctx, procid_self(), ev);
39         if (msg == NULL) {
40                 d_fprintf(stderr, "ERROR: could not init messaging context\n");
41                 goto fail;
42         }
43         g_ctx = g_lock_ctx_init(mem_ctx, msg);
44         if (g_ctx == NULL) {
45                 d_fprintf(stderr, "ERROR: could not init g_lock context\n");
46                 goto fail;
47         }
48
49         *pev = ev;
50         *pmsg = msg;
51         *pg_ctx = g_ctx;
52         return true;
53 fail:
54         TALLOC_FREE(g_ctx);
55         TALLOC_FREE(msg);
56         TALLOC_FREE(ev);
57         return false;
58 }
59
60 struct net_g_lock_do_state {
61         const char *cmd;
62         int result;
63 };
64
65 static void net_g_lock_do_fn(void *private_data)
66 {
67         struct net_g_lock_do_state *state =
68                 (struct net_g_lock_do_state *)private_data;
69         state->result = system(state->cmd);
70 }
71
72 static int net_g_lock_do(struct net_context *c, int argc, const char **argv)
73 {
74         struct net_g_lock_do_state state;
75         const char *name, *cmd;
76         int timeout;
77         NTSTATUS status;
78
79         if (argc != 3) {
80                 d_printf("Usage: net g_lock do <lockname> <timeout> "
81                          "<command>\n");
82                 return -1;
83         }
84         name = argv[0];
85         timeout = atoi(argv[1]);
86         cmd = argv[2];
87
88         state.cmd = cmd;
89         state.result = -1;
90
91         status = g_lock_do(name, G_LOCK_WRITE,
92                            timeval_set(timeout / 1000, timeout % 1000),
93                            procid_self(), net_g_lock_do_fn, &state);
94         if (!NT_STATUS_IS_OK(status)) {
95                 d_fprintf(stderr, "ERROR: g_lock_do failed: %s\n",
96                           nt_errstr(status));
97                 goto done;
98         }
99         if (state.result == -1) {
100                 d_fprintf(stderr, "ERROR: system() returned %s\n",
101                           strerror(errno));
102                 goto done;
103         }
104         d_fprintf(stderr, "command returned %d\n", state.result);
105
106 done:
107         return state.result;
108 }
109
110 static int net_g_lock_dump_fn(struct server_id pid, enum g_lock_type lock_type,
111                               void *private_data)
112 {
113         char *pidstr;
114
115         pidstr = procid_str(talloc_tos(), &pid);
116         d_printf("%s: %s (%s)\n", pidstr,
117                  (lock_type & 1) ? "WRITE" : "READ",
118                  (lock_type & G_LOCK_PENDING) ? "pending" : "holder");
119         TALLOC_FREE(pidstr);
120         return 0;
121 }
122
123 static int net_g_lock_dump(struct net_context *c, int argc, const char **argv)
124 {
125         struct tevent_context *ev = NULL;
126         struct messaging_context *msg = NULL;
127         struct g_lock_ctx *g_ctx = NULL;
128         NTSTATUS status;
129         int ret = -1;
130
131         if (argc != 1) {
132                 d_printf("Usage: net g_lock dump <lockname>\n");
133                 return -1;
134         }
135
136         if (!net_g_lock_init(talloc_tos(), &ev, &msg, &g_ctx)) {
137                 goto done;
138         }
139
140         status = g_lock_dump(g_ctx, argv[0], net_g_lock_dump_fn, NULL);
141
142         ret = 0;
143 done:
144         TALLOC_FREE(g_ctx);
145         TALLOC_FREE(msg);
146         TALLOC_FREE(ev);
147         return ret;
148 }
149
150 static int net_g_lock_locks_fn(const char *name, void *private_data)
151 {
152         d_printf("%s\n", name);
153         return 0;
154 }
155
156 static int net_g_lock_locks(struct net_context *c, int argc, const char **argv)
157 {
158         struct tevent_context *ev = NULL;
159         struct messaging_context *msg = NULL;
160         struct g_lock_ctx *g_ctx = NULL;
161         int ret = -1;
162
163         if (argc != 0) {
164                 d_printf("Usage: net g_lock locks\n");
165                 return -1;
166         }
167
168         if (!net_g_lock_init(talloc_tos(), &ev, &msg, &g_ctx)) {
169                 goto done;
170         }
171
172         ret = g_lock_locks(g_ctx, net_g_lock_locks_fn, NULL);
173 done:
174         TALLOC_FREE(g_ctx);
175         TALLOC_FREE(msg);
176         TALLOC_FREE(ev);
177         return ret;
178 }
179
180 int net_g_lock(struct net_context *c, int argc, const char **argv)
181 {
182         struct functable func[] = {
183                 {
184                         "do",
185                         net_g_lock_do,
186                         NET_TRANSPORT_LOCAL,
187                         N_("Execute a shell command under a lock"),
188                         N_("net g_lock do <lock name> <timeout> <command>\n")
189                 },
190                 {
191                         "locks",
192                         net_g_lock_locks,
193                         NET_TRANSPORT_LOCAL,
194                         N_("List all locknames"),
195                         N_("net g_lock locks\n")
196                 },
197                 {
198                         "dump",
199                         net_g_lock_dump,
200                         NET_TRANSPORT_LOCAL,
201                         N_("Dump a g_lock locking table"),
202                         N_("net g_lock dump <lock name>\n")
203                 },
204                 {NULL, NULL, 0, NULL, NULL}
205         };
206
207         return net_run_function(c, argc, argv, "net g_lock", func);
208 }