mosquitto/client/client_props.c

222 lines
6.0 KiB
C
Raw Normal View History

2018-10-31 12:38:39 +00:00
/*
Copyright (c) 2018-2020 Roger Light <roger@atchoo.org>
2018-10-31 12:38:39 +00:00
All rights reserved. This program and the accompanying materials
2020-11-25 17:34:21 +00:00
are made available under the terms of the Eclipse Public License 2.0
2018-10-31 12:38:39 +00:00
and Eclipse Distribution License v1.0 which accompany this distribution.
2021-10-05 14:20:37 +00:00
2018-10-31 12:38:39 +00:00
The Eclipse Public License is available at
2020-11-25 17:34:21 +00:00
https://www.eclipse.org/legal/epl-2.0/
2018-10-31 12:38:39 +00:00
and the Eclipse Distribution License is available at
http://www.eclipse.org/org/documents/edl-v10.php.
2021-10-05 14:20:37 +00:00
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
2020-12-01 18:21:59 +00:00
2018-10-31 12:38:39 +00:00
Contributors:
Roger Light - initial implementation and documentation.
*/
#include "config.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <unistd.h>
#include <strings.h>
#else
#include <process.h>
#include <winsock2.h>
#define snprintf sprintf_s
#define strncasecmp _strnicmp
#endif
#include "mosquitto.h"
#include "mqtt_protocol.h"
#include "client_shared.h"
enum prop_type
{
PROP_TYPE_BYTE,
PROP_TYPE_INT16,
PROP_TYPE_INT32,
PROP_TYPE_BINARY,
PROP_TYPE_STRING,
PROP_TYPE_STRING_PAIR
};
/* This parses property inputs. It should work for any command type, but is limited at the moment.
*
* Format:
*
* command property value
* command property key value
*
* Example:
*
* publish message-expiry-interval 32
* connect user-property key value
*/
int cfg_parse_property(struct mosq_config *cfg, int argc, char *argv[], int *idx)
{
char *cmdname = NULL, *propname = NULL;
char *key = NULL, *value = NULL;
int cmd, identifier, type;
mosquitto_property **proplist;
int rc;
long tmpl;
size_t szt;
2018-10-31 12:38:39 +00:00
/* idx now points to "command" */
if((*idx)+2 > argc-1){
/* Not enough args */
fprintf(stderr, "Error: --property argument given but not enough arguments specified.\n\n");
return MOSQ_ERR_INVAL;
}
cmdname = argv[*idx];
if(mosquitto_string_to_command(cmdname, &cmd)){
fprintf(stderr, "Error: Invalid command given in --property argument.\n\n");
return MOSQ_ERR_INVAL;
}
propname = argv[(*idx)+1];
if(mosquitto_string_to_property_info(propname, &identifier, &type)){
fprintf(stderr, "Error: Invalid property name given in --property argument.\n\n");
return MOSQ_ERR_INVAL;
}
if(mosquitto_property_check_command(cmd, identifier)){
2021-04-20 20:09:08 +00:00
fprintf(stderr, "Error: %s property not allowed for %s in --property argument.\n\n", propname, cmdname);
return MOSQ_ERR_INVAL;
}
2018-10-31 12:38:39 +00:00
if(identifier == MQTT_PROP_USER_PROPERTY){
if((*idx)+3 > argc-1){
/* Not enough args */
fprintf(stderr, "Error: --property argument given but not enough arguments specified.\n\n");
return MOSQ_ERR_INVAL;
}
key = argv[(*idx)+2];
value = argv[(*idx)+3];
(*idx) += 3;
}else{
value = argv[(*idx)+2];
(*idx) += 2;
}
switch(cmd){
case CMD_CONNECT:
proplist = &cfg->connect_props;
break;
case CMD_PUBLISH:
if(identifier == MQTT_PROP_TOPIC_ALIAS){
cfg->have_topic_alias = true;
}
2018-10-31 12:38:39 +00:00
if(identifier == MQTT_PROP_SUBSCRIPTION_IDENTIFIER){
fprintf(stderr, "Error: %s property not supported for %s in --property argument.\n\n", propname, cmdname);
return MOSQ_ERR_INVAL;
}
proplist = &cfg->publish_props;
break;
case CMD_SUBSCRIBE:
2018-12-20 15:32:43 +00:00
if(identifier != MQTT_PROP_SUBSCRIPTION_IDENTIFIER && identifier != MQTT_PROP_USER_PROPERTY){
2018-10-31 12:38:39 +00:00
fprintf(stderr, "Error: %s property not supported for %s in --property argument.\n\n", propname, cmdname);
return MOSQ_ERR_NOT_SUPPORTED;
}
proplist = &cfg->subscribe_props;
break;
case CMD_UNSUBSCRIBE:
proplist = &cfg->unsubscribe_props;
2018-10-31 12:38:39 +00:00
break;
case CMD_DISCONNECT:
proplist = &cfg->disconnect_props;
break;
case CMD_AUTH:
fprintf(stderr, "Error: %s property not supported for %s in --property argument.\n\n", propname, cmdname);
return MOSQ_ERR_NOT_SUPPORTED;
case CMD_WILL:
proplist = &cfg->will_props;
break;
case CMD_PUBACK:
case CMD_PUBREC:
case CMD_PUBREL:
case CMD_PUBCOMP:
case CMD_SUBACK:
case CMD_UNSUBACK:
fprintf(stderr, "Error: %s property not supported for %s in --property argument.\n\n", propname, cmdname);
return MOSQ_ERR_NOT_SUPPORTED;
default:
return MOSQ_ERR_INVAL;
}
switch(type){
case MQTT_PROP_TYPE_BYTE:
tmpl = atol(value);
if(tmpl < 0 || tmpl > UINT8_MAX){
fprintf(stderr, "Error: Property value (%ld) out of range for property %s.\n\n", tmpl, propname);
return MOSQ_ERR_INVAL;
}
rc = mosquitto_property_add_byte(proplist, identifier, (uint8_t )tmpl);
2018-10-31 12:38:39 +00:00
break;
case MQTT_PROP_TYPE_INT16:
tmpl = atol(value);
if(tmpl < 0 || tmpl > UINT16_MAX){
fprintf(stderr, "Error: Property value (%ld) out of range for property %s.\n\n", tmpl, propname);
return MOSQ_ERR_INVAL;
}
rc = mosquitto_property_add_int16(proplist, identifier, (uint16_t )tmpl);
2018-10-31 12:38:39 +00:00
break;
case MQTT_PROP_TYPE_INT32:
tmpl = atol(value);
if(tmpl < 0 || tmpl > UINT32_MAX){
fprintf(stderr, "Error: Property value (%ld) out of range for property %s.\n\n", tmpl, propname);
return MOSQ_ERR_INVAL;
}
rc = mosquitto_property_add_int32(proplist, identifier, (uint32_t )tmpl);
2018-10-31 12:38:39 +00:00
break;
case MQTT_PROP_TYPE_VARINT:
tmpl = atol(value);
if(tmpl < 0 || tmpl > UINT32_MAX){
fprintf(stderr, "Error: Property value (%ld) out of range for property %s.\n\n", tmpl, propname);
return MOSQ_ERR_INVAL;
}
rc = mosquitto_property_add_varint(proplist, identifier, (uint32_t )tmpl);
2018-10-31 12:38:39 +00:00
break;
case MQTT_PROP_TYPE_BINARY:
szt = strlen(value);
if(szt > UINT16_MAX){
fprintf(stderr, "Error: Property value too long for property %s.\n\n", propname);
return MOSQ_ERR_INVAL;
}
rc = mosquitto_property_add_binary(proplist, identifier, value, (uint16_t )szt);
2018-10-31 12:38:39 +00:00
break;
case MQTT_PROP_TYPE_STRING:
rc = mosquitto_property_add_string(proplist, identifier, value);
break;
case MQTT_PROP_TYPE_STRING_PAIR:
rc = mosquitto_property_add_string_pair(proplist, identifier, key, value);
break;
default:
return MOSQ_ERR_INVAL;
}
if(rc){
fprintf(stderr, "Error adding property %s %d\n", propname, type);
return rc;
}
return MOSQ_ERR_SUCCESS;
}