]> andersk Git - moira.git/blob - lib/mr_ops.c
Avoid buffer overruns and check return value of malloc()
[moira.git] / lib / mr_ops.c
1 /* $Id$
2  *
3  * This routine is part of the client library.  It handles
4  * the protocol operations: invoking an update and getting the
5  * Moira message of the day.
6  *
7  * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology
8  * For copying and distribution information, please see the file
9  * <mit-copyright.h>.
10  */
11
12 #include <mit-copyright.h>
13 #include <moira.h>
14 #include "mr_private.h"
15
16 #include <errno.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 RCSID("$Header$");
21
22 /* Invoke a DCM update. */
23
24 int mr_do_update(void)
25 {
26   int status;
27   mr_params param_st;
28   struct mr_params *params = NULL;
29   struct mr_params *reply = NULL;
30
31   CHECK_CONNECTED;
32   params = &param_st;
33   params->mr_version_no = sending_version_no;
34   params->mr_procno = MR_DO_UPDATE;
35   params->mr_argc = 0;
36   params->mr_argl = NULL;
37   params->mr_argv = NULL;
38
39   if ((status = mr_do_call(params, &reply)) == 0)
40     status = reply->mr_status;
41
42   mr_destroy_reply(reply);
43
44   return status;
45 }
46
47
48 /* Get the Moira motd.  This returns a Moira status, and motd will either
49  * point to NULL or the motd in a static buffer.
50  */
51
52 int mr_motd(char **motd)
53 {
54   int status;
55   mr_params param_st;
56   struct mr_params *params = NULL;
57   struct mr_params *reply = NULL;
58   static char *buffer = NULL;
59
60   *motd = NULL;
61   CHECK_CONNECTED;
62   params = &param_st;
63   params->mr_version_no = sending_version_no;
64   params->mr_procno = MR_MOTD;
65   params->mr_argc = 0;
66   params->mr_argl = NULL;
67   params->mr_argv = NULL;
68
69   if ((status = mr_do_call(params, &reply)))
70     goto punt;
71
72   while ((status = reply->mr_status) == MR_MORE_DATA)
73     {
74       if (reply->mr_argc > 0)
75         {
76           buffer = realloc(buffer, reply->mr_argl[0] + 1);
77           if (!buffer)
78             {
79               mr_disconnect();
80               return ENOMEM;
81             }
82           strcpy(buffer, reply->mr_argv[0]);
83           *motd = buffer;
84         }
85       mr_destroy_reply(reply);
86       reply = NULL;
87
88       initialize_operation(_mr_recv_op, mr_start_recv, &reply, NULL);
89       queue_operation(_mr_conn, CON_INPUT, _mr_recv_op);
90
91       complete_operation(_mr_recv_op);
92       if (OP_STATUS(_mr_recv_op) != OP_COMPLETE)
93         {
94           mr_disconnect();
95           status = MR_ABORTED;
96           return status;
97         }
98     }
99 punt:
100   mr_destroy_reply(reply);
101   /* for backwards compatability */
102   if (status == MR_UNKNOWN_PROC)
103     return 0;
104   else
105     return status;
106 }
This page took 0.0513 seconds and 5 git commands to generate.