in speakup/kobjects.c [751:837]
static ssize_t message_store_helper(const char *buf, size_t count,
struct msg_group_t *group)
{
char *cp = (char *)buf;
char *end = cp + count;
char *linefeed = NULL;
char *temp = NULL;
ssize_t msg_stored = 0;
ssize_t retval = count;
size_t desc_length = 0;
unsigned long index = 0;
int received = 0;
int used = 0;
int rejected = 0;
int reset = 0;
enum msg_index_t firstmessage = group->start;
enum msg_index_t lastmessage = group->end;
enum msg_index_t curmessage;
while (cp < end) {
while ((cp < end) && (*cp == ' ' || *cp == '\t'))
cp++;
if (cp == end)
break;
if (strchr("dDrR", *cp)) {
reset = 1;
break;
}
received++;
linefeed = strchr(cp, '\n');
if (!linefeed) {
rejected++;
break;
}
if (!isdigit(*cp)) {
rejected++;
cp = linefeed + 1;
continue;
}
/*
* Do not replace with kstrtoul:
* here we need temp to be updated
*/
index = simple_strtoul(cp, &temp, 10);
while ((temp < linefeed) && (*temp == ' ' || *temp == '\t'))
temp++;
desc_length = linefeed - temp;
curmessage = firstmessage + index;
/*
* Note the check (curmessage < firstmessage). It is not
* redundant. Suppose that the user gave us an index
* equal to ULONG_MAX - 1. If firstmessage > 1, then
* firstmessage + index < firstmessage!
*/
if ((curmessage < firstmessage) || (curmessage > lastmessage)) {
rejected++;
cp = linefeed + 1;
continue;
}
msg_stored = spk_msg_set(curmessage, temp, desc_length);
if (msg_stored < 0) {
retval = msg_stored;
if (msg_stored == -ENOMEM)
reset = 1;
break;
}
used++;
cp = linefeed + 1;
}
if (reset)
spk_reset_msg_group(group);
report_msg_status(reset, received, used, rejected, group->name);
return retval;
}