s3:utils: let smbstatus report anonymous signing/encryption explicitly
[samba.git] / source3 / utils / async-tracker.c
1 /*
2  * Copyright (C) 2011, Nokia <ivan.frade@nokia.com>
3  * Copyright (C) 2015, Noel Power <nopower@suse.com>
4  * Copyright (C) 2016, Ralph Boehme <slow@samba.org.>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library 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 GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA  02110-1301, USA.
20  */
21
22 #include "includes.h"
23 #include "lib/util/debug.h"
24 #include "lib/cmdline/cmdline.h"
25 #include "param.h"
26 /*
27  * glib uses TRUE and FALSE which was redefined by "includes.h" to be
28  * unusable, undefine so glib can establish its own working
29  * replacement.
30  */
31 #undef TRUE
32 #undef FALSE
33 #include <glib.h>
34 #include <libtracker-sparql/tracker-sparql.h>
35 #include "lib/tevent_glib_glue.h"
36
37 enum loop_type {TEVENT_LOOP, GLIB_LOOP};
38
39 struct test_state {
40         enum loop_type loop_type;
41         TrackerSparqlConnection *connection;
42         GCancellable *cancellable;
43         GTimer *timer;
44         GMainLoop *loop;
45         struct tevent_context *ev;
46         struct tevent_glib_glue *glue;
47 };
48
49 static void cleanup(struct test_state *state)
50 {
51         g_cancellable_cancel(state->cancellable);
52         g_object_unref(state->cancellable);
53         g_timer_destroy(state->timer);
54         if (state->connection != NULL) {
55                 g_object_unref(state->connection);
56                 state->connection = NULL;
57         }
58         if (state->loop_type == GLIB_LOOP) {
59                 g_main_loop_quit(state->loop);
60         } else {
61                 samba_tevent_glib_glue_quit(state->glue);
62         }
63 }
64
65 static void cursor_cb(GObject      *object,
66                       GAsyncResult *res,
67                       gpointer      user_data)
68 {
69         struct test_state *state = talloc_get_type_abort(
70                 user_data, struct test_state);
71         TrackerSparqlCursor *cursor = NULL;
72         GError *error = NULL;
73         gboolean more_results;
74         static gint i = 0;
75
76         cursor = TRACKER_SPARQL_CURSOR(object);
77         more_results = tracker_sparql_cursor_next_finish(cursor,
78                                                          res,
79                                                          &error);
80         if (error) {
81                 g_critical("Could not run cursor next: %s", error->message);
82
83                 if (cursor != NULL) {
84                         g_object_unref(cursor);
85                 }
86
87                 g_error_free(error);
88                 cleanup(state);
89                 return;
90         }
91
92         if (!more_results) {
93                 g_print("\n");
94                 g_print("\nAsync cursor next took: %.6f (for all %d results)\n",
95                         g_timer_elapsed (state->timer, NULL), i);
96
97                 g_object_unref(cursor);
98                 cleanup(state);
99                 return;
100         }
101
102         if (i++ < 5) {
103                 int num_cols = tracker_sparql_cursor_get_n_columns(cursor);
104                 int col;
105
106                 if (i == 1) {
107                         g_print("Printing first 5 results:\n");
108                 }
109                 for (col = 0; col < num_cols; col++) {
110                         g_print(" %s ", tracker_sparql_cursor_get_string(
111                                         cursor, col, NULL));
112                         if (col == num_cols -1 ) {
113                                 g_print("\n");
114                         }
115                 }
116
117                 if (i == 5) {
118                         g_print("  ...\n");
119                         g_print("  Printing nothing for remaining results\n");
120                 }
121         }
122
123         tracker_sparql_cursor_next_async(cursor,
124                                          state->cancellable,
125                                          cursor_cb,
126                                          state);
127 }
128
129 static void query_cb(GObject      *object,
130                      GAsyncResult *res,
131                      gpointer      user_data)
132 {
133         struct test_state *state = talloc_get_type_abort(
134                 user_data, struct test_state);
135         TrackerSparqlCursor *cursor = NULL;
136         GError *error = NULL;
137
138         g_print("Async query took: %.6f\n", g_timer_elapsed(state->timer, NULL));
139
140         cursor = tracker_sparql_connection_query_finish(
141                         TRACKER_SPARQL_CONNECTION(object),
142                         res,
143                         &error);
144         if (error) {
145                 g_critical("Could not run query: %s", error->message);
146
147                 if (cursor) {
148                         g_object_unref(cursor);
149                 }
150
151                 g_error_free(error);
152                 cleanup(state);
153                 return;
154         }
155
156         g_timer_start(state->timer);
157
158         tracker_sparql_cursor_next_async(cursor,
159                                          state->cancellable,
160                                          cursor_cb,
161                                          state);
162 }
163
164 static void connection_cb(GObject      *object,
165                           GAsyncResult *res,
166                           gpointer      user_data)
167 {
168         struct test_state *state = talloc_get_type_abort(
169                 user_data, struct test_state);
170         GError *error = NULL;
171
172         g_print("Async connection took: %.6f\n",
173                 g_timer_elapsed(state->timer, NULL));
174
175         state->connection = tracker_sparql_connection_get_finish(res, &error);
176         if (error) {
177                 g_critical("Could not connect: %s", error->message);
178                 g_error_free(error);
179                 cleanup(state);
180                 return;
181         }
182
183         g_timer_start(state->timer);
184
185         tracker_sparql_connection_query_async(
186                 state->connection,
187                 "SELECT ?name nie:mimeType(?s) nfo:fileName(?s) "
188                 "WHERE { {?s nie:url ?name}}",
189                 state->cancellable,
190                 query_cb,
191                 state);
192 }
193
194 static void debug_fn(void *private_data,
195                      enum tevent_debug_level level,
196                      const char *fmt,
197                      va_list ap)
198 {
199         dbgtext_va(fmt, ap);
200 }
201
202 int main(int argc, const char **argv)
203 {
204         TALLOC_CTX *mem_ctx = NULL;
205         struct test_state *state = NULL;
206         int c;
207         poptContext pc;
208         bool ok;
209         struct poptOption long_options[] = {
210                 POPT_AUTOHELP
211                 {
212                         .longName  = "tevent",
213                         .shortName = 't',
214                         .argInfo   = POPT_ARG_NONE,
215                         .val       = 'v',
216                         .descrip   = "Use tevent loop",
217                 },
218                 {
219                         .longName  = "glib",
220                         .shortName = 'g',
221                         .argInfo   = POPT_ARG_NONE,
222                         .val       = 'g',
223                         .descrip   = "Use glib loop",
224                 },
225                 POPT_COMMON_SAMBA
226                 POPT_COMMON_VERSION
227                 POPT_TABLEEND
228         };
229
230         mem_ctx = talloc_new(NULL);
231         if (mem_ctx == NULL) {
232                 exit(1);
233         }
234
235         state = talloc_zero(mem_ctx, struct test_state);
236         if (state == NULL) {
237                 exit(1);
238         }
239
240         state->loop_type = TEVENT_LOOP;
241
242         smb_init_locale();
243
244         ok = samba_cmdline_init(mem_ctx,
245                                 SAMBA_CMDLINE_CONFIG_CLIENT,
246                                 true /* require_smbconf */);
247         if (!ok) {
248                 TALLOC_FREE(mem_ctx);
249                 exit(1);
250         }
251
252         pc = samba_popt_get_context(getprogname(),
253                                     argc,
254                                     argv,
255                                     long_options,
256                                     POPT_CONTEXT_KEEP_FIRST);
257         if (pc == NULL) {
258                 TALLOC_FREE(mem_ctx);
259                 exit(1);
260         }
261
262         while ((c = poptGetNextOpt(pc)) != -1) {
263                 switch (c) {
264                 case 'g':
265                         state->loop_type = GLIB_LOOP;
266                         break;
267                 case 't':
268                         state->loop_type = TEVENT_LOOP;
269                         break;
270                 case POPT_ERROR_BADOPT:
271                         fprintf(stderr, "\nInvalid option %s: %s\n\n",
272                                 poptBadOption(pc, 0), poptStrerror(c));
273                         poptPrintUsage(pc, stderr, 0);
274                         exit(1);
275                 }
276         }
277
278         if (state->loop_type == GLIB_LOOP) {
279                 state->loop = g_main_loop_new(NULL, false);
280         } else {
281                 state->ev = tevent_context_init(mem_ctx);
282                 if (CHECK_DEBUGLVL(10)) {
283                         tevent_set_debug(state->ev, debug_fn, NULL);
284                 }
285                 state->glue = samba_tevent_glib_glue_create(
286                         mem_ctx, state->ev, g_main_context_default());
287                 if (state->glue == NULL) {
288                         printf("tevent_glib_glue_create failed\n");
289                         exit(1);
290                 }
291         }
292
293         state->timer = g_timer_new();
294         state->cancellable = g_cancellable_new();
295
296         tracker_sparql_connection_get_async(state->cancellable,
297                                             connection_cb,
298                                             state);
299
300         if (state->loop_type == GLIB_LOOP) {
301                 printf("entering g_main_loop_run\n");
302                 g_main_loop_run(state->loop);
303         } else {
304                 printf("entering tevent_loop_wait\n");
305                 tevent_loop_wait(state->ev);
306
307                 TALLOC_FREE(state->glue);
308                 TALLOC_FREE(state->ev);
309         }
310
311         TALLOC_FREE(mem_ctx);
312         poptFreeContext(pc);
313
314         return 0;
315 }