]> andersk Git - moira.git/blob - lib/mr_query.c
5b3b0e3a2c105ca47791da709817b7bbd7b34b03
[moira.git] / lib / mr_query.c
1 /* $Id$
2  *
3  * Perform a Moira query
4  *
5  * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology
6  * For copying and distribution information, please see the file
7  * <mit-copyright.h>.
8  *
9  */
10
11 #include <mit-copyright.h>
12 #include <moira.h>
13 #include "mr_private.h"
14
15 #include <stdlib.h>
16 #include <string.h>
17
18 RCSID("$Header$");
19
20 int mr_query_internal(int argc, char **argv,
21                       int (*callback)(int, char **, void *), void *callarg);
22
23 /*
24  * This routine is the primary external interface to the mr library.
25  *
26  * It builds a new argument vector with the query handle prepended,
27  * and calls mr_query_internal.
28  */
29 static int level = 0;
30
31 int mr_query(char *name, int argc, char **argv,
32              int (*callproc)(int, char **, void *), void *callarg)
33 {
34   char **nargv = malloc(sizeof(char *) * (argc + 1));
35   int status = 0;
36
37   nargv[0] = name;
38   memcpy(nargv + 1, argv, sizeof(char *) * argc);
39   status = mr_query_internal(argc + 1, nargv, callproc, callarg);
40   free(nargv);
41   return status;
42 }
43
44 /*
45  * This routine makes a Moira query.
46  *
47  * argv[0] is the query name.
48  * argv[1..argc-1] are the query arguments.
49  *
50  * callproc is called once for each returned value, with arguments
51  * argc, argv, and callarg.
52  * If it returns a non-zero value, further calls to it are not done, and
53  * all future data from the server is ignored (there should be some
54  * way to send it a quench..)
55  */
56
57 int mr_query_internal(int argc, char **argv,
58                       int (*callproc)(int, char **, void *), void *callarg)
59 {
60   int status;
61   mr_params params_st;
62   mr_params *params = NULL;
63   mr_params *reply = NULL;
64   int stopcallbacks = 0;
65
66   if (level)
67     return MR_QUERY_NOT_REENTRANT;
68
69   CHECK_CONNECTED;
70   level++;
71
72   params = &params_st;
73   params->mr_version_no = sending_version_no;
74   params->mr_procno = MR_QUERY;
75   params->mr_argc = argc;
76   params->mr_argl = NULL;
77   params->mr_argv = argv;
78
79   if ((status = mr_do_call(params, &reply)))
80     goto punt;
81
82   while ((status = reply->mr_status) == MR_MORE_DATA)
83     {
84       if (!stopcallbacks && callproc)
85         stopcallbacks = (*callproc)(reply->mr_argc, reply->mr_argv, callarg);
86       mr_destroy_reply(reply);
87       reply = NULL;
88
89       initialize_operation(_mr_recv_op, mr_start_recv, &reply, NULL);
90       queue_operation(_mr_conn, CON_INPUT, _mr_recv_op);
91
92       complete_operation(_mr_recv_op);
93       if (OP_STATUS(_mr_recv_op) != OP_COMPLETE)
94         {
95           mr_disconnect();
96           status = MR_ABORTED;
97           goto punt_1;
98         }
99     }
100 punt:
101   mr_destroy_reply(reply);
102 punt_1:
103   level--;
104   return status;
105 }
This page took 0.031093 seconds and 3 git commands to generate.