#define __COMMAND_C #include #include #include #include "kavcommand.h" #include "kaverrors.h" #include "kavsockets.h" struct kavCommandStruct *kavCommandConstruct(unsigned int family) { struct kavCommandStruct *ret = 0; // allocate memory for kavCommandStruct if ((ret = calloc(1, sizeof(struct kavCommandStruct))) != 0) ret->family = family; else kavSetError("Cannot allocate memory"); return (ret); } void kavCommandDestroy(struct kavCommandStruct **cmd) { struct kavParamList *p = (*cmd)->params; while (p != 0) { struct kavParamList *tmp = p->next; if (p->data.value != 0) free(p->data.value); free(p); p = tmp; } free(*cmd); *cmd = 0; } struct kavParamList *kavCommandParamAdd(struct kavCommandStruct *cmd, unsigned int id, const char *value, unsigned int size) { struct kavParamList *p; // allocate memory for structure if ((p = calloc(1, sizeof(struct kavParamList))) == 0) { kavSetError("Cannot allocate memory"); return (0); } // allocate memory for data if ((p->data.value = malloc(size)) == 0) { kavSetError("Cannot allocate memory"); free(p); return (0); } // copy value into the new allocated memory memcpy(p->data.value, value, size); // set members p->data.id = id; p->data.size = size; // p->next is already 0, due to calloc() call kavCommandParamAppend(cmd, p); // keep track of how many params there are ++(cmd->params_count); return (p); } int kavCommandSerialize(struct kavCommandStruct *cmd, int fd) { struct kavParamList *p; // send family unsigned int tmp = htonl(cmd->family); if (kavSocketWrite(fd, &tmp, 4) == -1) return (-1); if (cmd->family == CMD_FAMILY_RESPONSE) { // if this is a response, send maction tmp = htonl(cmd->maction); if (kavSocketWrite(fd, &tmp, 4) == -1) return (-1); } // send the number of parameters tmp = htonl(cmd->params_count); if (kavSocketWrite(fd, &tmp, 4) == -1) return (-1); // send the parameters for (p = cmd->params; p != 0; p = p->next) { // send the id tmp = htonl(p->data.id); if (kavSocketWrite(fd, &tmp, 4) == -1) return (-1); // send the size of parameter tmp = htonl(p->data.size); if (kavSocketWrite(fd, &tmp, 4) == -1) return (-1); // send the value of parameter if (kavSocketWrite(fd, p->data.value, p->data.size) == -1) return (-1); } return (0); } int kavCommandDeserialize(struct kavCommandStruct *cmd, int fd) { struct kavParamList *p; unsigned int tmp, i; int needs_cleaning = 0; // read family if (kavSocketRead(fd, &tmp, 4) == -1) return (-1); cmd->family = ntohl(tmp); if (cmd->family == CMD_FAMILY_RESPONSE) { // if this is a response, read maction if (kavSocketRead(fd, &tmp, 4) == -1) return (-1); cmd->maction = ntohl(tmp); } // read the number of params if (kavSocketRead(fd, &tmp, 4) == -1) return (-1); cmd->params_count = ntohl(tmp); // read params for (i = 0; i < cmd->params_count; ++i) { if ((p = calloc(1, sizeof(struct kavParamList))) == 0) { kavSetError("Cannot allocate memory"); return (-1); } // read param id if (kavSocketRead(fd, &tmp, 4) == -1) { free(p); ++needs_cleaning; break; } p->data.id = ntohl(tmp); // read value size if (kavSocketRead(fd, &tmp, 4) == -1) { free(p); ++needs_cleaning; break; } p->data.size = ntohl(tmp); // allocate memory for value if ((p->data.value = malloc(p->data.size)) == 0) { kavSetError("Cannot allocate memory"); free(p); ++needs_cleaning; break; } if (kavSocketRead(fd, p->data.value, p->data.size) == -1) { free(p->data.value); free(p); ++needs_cleaning; break; } kavCommandParamAppend(cmd, p); } if (needs_cleaning != 0) { // an error was encountered while reading parameters, // thus the allocated memory needs to be freed kavCommandParamDestroy(&cmd->params); return (-1); } return (0); } static void kavCommandParamAppend(struct kavCommandStruct *cmd, struct kavParamList *p) { struct kavParamList *it; // append the new paramStruct to kavCommandStruct if (cmd->params == 0) // this is the first param cmd->params = p; else { // find the last param it = cmd->params; while (it->next != 0) it = it->next; // add the new one as last it->next = p; } } static void kavCommandParamDestroy(struct kavParamList **param) { struct kavParamList *it = *param; while (it != 0) { struct kavParamList *tmp = it->next; if (it->data.value != 0) free(it->data.value); free(it); it = tmp; } *param = 0; }