]> andersk Git - moira.git/blob - server/mr_glue.c
eliminate use of the `register' keyword: let the compiler decide
[moira.git] / server / mr_glue.c
1 /*
2  *      $Source$
3  *      $Author$
4  *      $Header$
5  *
6  *      Copyright (C) 1987 by the Massachusetts Institute of Technology
7  *      For copying and distribution information, please see the file
8  *      <mit-copyright.h>.
9  *
10  *      Glue routines to allow the database stuff to be linked in to
11  *      a program expecting a library level interface.
12  */
13
14 #ifndef lint
15 static char *rcsid_mr_glue_c = "$Header$";
16 #endif lint
17
18 #include <mit-copyright.h>
19 #include <sys/types.h>
20 #include <sys/signal.h>
21 #include <sys/wait.h>
22 #include <krb_et.h>
23 #include <pwd.h>
24 #include "mr_server.h"
25 #include "query.h"
26
27 static int already_connected = 0;
28
29 #define CHECK_CONNECTED { if (!already_connected) return MR_NOT_CONNECTED; }
30
31 static client pseudo_client;
32 extern int errno;
33 extern char *whoami;
34 extern time_t now;
35 void reapchild();
36
37 int mr_connect(char *server)
38 {
39   int status;
40   extern int query_timeout;
41   struct sigaction action;
42
43   if (already_connected)
44     return MR_ALREADY_CONNECTED;
45
46   initialize_sms_error_table();
47   initialize_krb_error_table();
48   memset(&pseudo_client, 0, sizeof(pseudo_client));
49
50   query_timeout = 0;
51   status =  mr_open_database();
52   if (!status)
53     already_connected = 1;
54
55   action.sa_flags = 0;
56   sigemptyset(&action.sa_mask);
57   sigaddset(&action.sa_mask, SIGCHLD);
58   action.sa_handler = reapchild;
59   if (sigaction(SIGCHLD, &action, NULL) < 0)
60     {
61       com_err(whoami, errno, "Unable to establish signal handlers.");
62       exit(1);
63     }
64   return status;
65 }
66
67 int mr_disconnect(void)
68 {
69   CHECK_CONNECTED;
70   mr_close_database();
71   already_connected = 0;
72   return 0;
73 }
74
75 int mr_noop(void)
76 {
77   CHECK_CONNECTED;
78   return 0;
79 }
80
81 /*
82  * This routine is rather bogus, as it only fills in who you claim to be.
83  */
84 int mr_auth(char *prog)
85 {
86   struct passwd *pw;
87   extern char *krb_realm;
88   char buf[1024], *strsave();
89
90   CHECK_CONNECTED;
91   pw = getpwuid(getuid());
92   if (!pw)
93     return KDC_PR_UNKNOWN + ERROR_TABLE_BASE_krb;
94   strcpy(pseudo_client.kname.name, pw->pw_name);
95   krb_get_lrealm(pseudo_client.kname.realm, 1);
96   krb_realm = pseudo_client.kname.realm;
97
98   strcpy(buf, pw->pw_name);
99   strcat(buf, "@");
100   strcat(buf, pseudo_client.kname.realm);
101   strcpy(pseudo_client.clname, buf);
102   pseudo_client.users_id = 0;
103   name_to_id(pseudo_client.kname.name, USERS_TABLE, &pseudo_client.users_id);
104   pseudo_client.client_id = pseudo_client.users_id;
105   strncpy(pseudo_client.entity, prog, 8);
106   pseudo_client.args = malloc(sizeof(mr_params));
107   pseudo_client.args->mr_version_no = MR_VERSION_2;
108   return 0;
109 }
110
111 struct hint {
112   int (*proc)();
113   char *hint;
114 };
115
116 callback(int argc, char **argv, struct hint *arg)
117 {
118   if (mr_trim_args(argc, argv) == MR_NO_MEM)
119     com_err(whoami, MR_NO_MEM, "while trimmming args");
120   (*arg->proc)(argc, argv, arg->hint);
121 }
122
123
124 int mr_query(char *name, int argc, char **argv, int (*callproc)(), char *callarg)
125 {
126   struct hint hints;
127
128   time(&now);
129   hints.proc = callproc;
130   hints.hint = callarg;
131   next_incremental();
132   return mr_process_query(&pseudo_client, name, argc,
133                           mr_copy_args(argv, argc), callback,
134                           (char *)&hints);
135 }
136
137 int mr_access(char *name, int argc, char **argv)
138 {
139   time(&now);
140   return mr_check_access(&pseudo_client, name, argc,
141                          mr_copy_args(argv, argc));
142 }
143
144 int mr_query_internal(int argc, char **argv, int (*callproc)(), char *callarg)
145 {
146   struct hint hints;
147
148   time(&now);
149   hints.proc = callproc;
150   hints.hint = callarg;
151   next_incremental();
152   return mr_process_query(&pseudo_client, argv[0], argc - 1,
153                           mr_copy_args(argv + 1, argc - 1), callback,
154                           (char *)&hints);
155 }
156
157 int mr_access_internal(int argc, char **argv)
158 {
159   time(&now);
160   return mr_check_access(&pseudo_client, argv[0], argc - 1,
161                          mr_copy_args(argv + 1, argc - 1));
162 }
163
164 mr_shutdown(char *why)
165 {
166   fprintf(stderr, "Sorry, not implemented\n");
167 }
168
169
170 /* trigger_dcm is also used as a followup routine to the
171  * set_server_host_override query, hence the two dummy arguments.
172  */
173
174 struct query pseudo_query = {
175   "trigger_dcm",
176   "tdcm",
177 };
178
179 int trigger_dcm(int dummy0, int dummy1, client *cl)
180 {
181   int pid, status;
182   char prog[128];
183
184   if ((status = check_query_access(&pseudo_query, 0, cl)))
185     return status;
186
187   sprintf(prog, "%s/startdcm", BIN_DIR);
188   pid = vfork();
189   switch (pid)
190     {
191     case 0:
192       execl(prog, "startdcm", 0);
193       exit(1);
194
195     case -1:
196       return errno;
197
198     default:
199       return MR_SUCCESS;
200     }
201 }
202
203
204 void reapchild(void)
205 {
206   int status, pid;
207
208   while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
209     {
210       if (pid == inc_pid)
211         {
212           inc_running = 0;
213           next_incremental();
214         }
215       if (WTERMSIG(status) != 0 || WEXITSTATUS(status) != 0)
216         {
217           com_err(whoami, 0, "%d: child exits with signal %d status %d",
218                   pid, WTERMSIG(status), WEXITSTATUS(status));
219         }
220     }
221 }
This page took 0.052058 seconds and 5 git commands to generate.