- make sure handle is NULL
[oweals/gnunet.git] / src / psyc / psyc_common.c
1 /*
2  * This file is part of GNUnet
3  * (C) 2013 Christian Grothoff (and other contributing authors)
4  *
5  * GNUnet is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published
7  * by the Free Software Foundation; either version 3, or (at your
8  * option) any later version.
9  *
10  * GNUnet is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with GNUnet; see the file COPYING.  If not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /**
22  * @file psyc/psyc_common.c
23  * @brief Common functions for PSYC
24  * @author Gabor X Toth
25  */
26
27 #include <inttypes.h>
28 #include "psyc.h"
29
30 /**
31  * Check if @a data contains a series of valid message parts.
32  *
33  * @param data_size  Size of @a data.
34  * @param data       Data.
35  *
36  * @return Message type number
37  *         or GNUNET_NO if the message contains invalid or no parts.
38  */
39 uint16_t
40 GNUNET_PSYC_message_last_part (uint16_t data_size, const char *data)
41 {
42   const struct GNUNET_MessageHeader *pmsg;
43   uint16_t ptype = GNUNET_NO;
44   uint16_t psize = 0;
45   uint16_t pos = 0;
46
47   for (pos = 0; pos < data_size; pos += psize)
48   {
49     pmsg = (const struct GNUNET_MessageHeader *) (data + pos);
50     psize = ntohs (pmsg->size);
51     ptype = ntohs (pmsg->type);
52     if (psize < sizeof (*pmsg) || pos + psize > data_size
53         || ptype < GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD
54         || GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL < ptype)
55     {
56       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
57                   "Invalid message part of type %u and size %u.\n",
58                   ptype, psize);
59       return GNUNET_NO;
60     }
61   }
62   return ptype;
63 }
64
65
66 void
67 GNUNET_PSYC_log_message (enum GNUNET_ErrorType kind,
68                          const struct GNUNET_MessageHeader *msg)
69 {
70   uint16_t size = ntohs (msg->size);
71   uint16_t type = ntohs (msg->type);
72   GNUNET_log (kind, "Message of type %d and size %u:\n", type, size);
73   switch (type)
74   {
75   case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE:
76   {
77     struct GNUNET_PSYC_MessageHeader *pmsg
78       = (struct GNUNET_PSYC_MessageHeader *) msg;
79     GNUNET_log (kind, "\tID: %" PRIu64 "\tflags: %" PRIu32 "\n",
80                 GNUNET_ntohll (pmsg->message_id), ntohl (pmsg->flags));
81     break;
82   }
83   case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD:
84   {
85     struct GNUNET_PSYC_MessageMethod *meth
86       = (struct GNUNET_PSYC_MessageMethod *) msg;
87     GNUNET_log (kind, "\t%.*s\n", size - sizeof (*meth), &meth[1]);
88     break;
89   }
90   case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER:
91   {
92     struct GNUNET_PSYC_MessageModifier *mod
93       = (struct GNUNET_PSYC_MessageModifier *) msg;
94     uint16_t name_size = ntohs (mod->name_size);
95     char oper = ' ' < mod->oper ? mod->oper : ' ';
96     GNUNET_log (kind, "\t%c%.*s\t%.*s\n", oper, name_size, &mod[1],
97                 size - sizeof (*mod) - name_size - 1,
98                 ((char *) &mod[1]) + name_size + 1);
99     break;
100   }
101   case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT:
102   case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA:
103     GNUNET_log (kind, "\t%.*s\n", size - sizeof (*msg), &msg[1]);
104     break;
105   }
106 }