add identifier sanitation for setting FSM instance ids

We often compose FSM instance IDs from context information, for example placing
an MSISDN string or IP:port information in the FSM instance id, using
osmo_fsm_inst_update_id_f(). This fails if any characters are contained that
don't pass osmo_identifier_valid(). Hence it is the task of the caller to make
sure only characters allowed in an FSM id are applied.

Provide API to trivially allow this by replacing illegal chars:
- osmo_identifier_sanitize_buf(), with access to the same set of illegal
  characters defined in utils.c,
- osmo_fsm_inst_update_id_f_sanitize() implicitly replaces non-identifier
  chars.

This makes it easy to add strings like '192.168.0.1:2342' or '+4987654321' to
an FSM instance id, without adding string mangling to each place that sets an
id; e.g. replacing with '-' to yield '192-168-0-1:2342' or '-4987654321'.

Change-Id: Ia40a6f3b2243c95fe428a080b938e11d8ab771a7
diff --git a/src/fsm.c b/src/fsm.c
index b6912c6..c32767b 100644
--- a/src/fsm.c
+++ b/src/fsm.c
@@ -364,6 +364,35 @@
 	return 0;
 }
 
+/*! Change id of the FSM instance using a string format, and ensuring a valid id.
+ * Replace any characters that are not permitted as FSM identifier with replace_with.
+ * \param[in] fi FSM instance.
+ * \param[in] replace_with Character to use instead of non-permitted FSM id characters.
+ *                         Make sure to choose a legal character, e.g. '-'.
+ * \param[in] fmt format string to compose new ID.
+ * \param[in] ... variable argument list for format string.
+ * \returns 0 if the ID was updated, otherwise -EINVAL.
+ */
+int osmo_fsm_inst_update_id_f_sanitize(struct osmo_fsm_inst *fi, char replace_with, const char *fmt, ...)
+{
+	char *id = NULL;
+	va_list ap;
+	int rc;
+
+	if (!fmt)
+		return osmo_fsm_inst_update_id(fi, NULL);
+
+	va_start(ap, fmt);
+	id = talloc_vasprintf(fi, fmt, ap);
+	va_end(ap);
+
+	osmo_identifier_sanitize_buf(id, NULL, replace_with);
+
+	rc = osmo_fsm_inst_update_id(fi, id);
+	talloc_free(id);
+	return rc;
+}
+
 /*! allocate a new instance of a specified FSM
  *  \param[in] fsm Descriptor of the FSM
  *  \param[in] ctx talloc context from which to allocate memory