1 /***************************************************************************
2 * copyright : (C) 2004 by Hendrik Sattler *
3 * mail : post@hendrik-sattler.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 ***************************************************************************/
11
12 #include <smspdu.h>
13
14 #include <helper.h>
15
16 #include <string.h>
17 #include <strings.h>
18 #include <ctype.h>
19 #include <stdlib.h>
20
21 static
sms_pdu_sort_type(struct sms ** list,const char * sub_order)22 void sms_pdu_sort_type (struct sms** list, const char* sub_order) {
23 //4 lists for type sorting
24 struct sms** list_sub; //SMS-SUBMIT
25 unsigned int lssub = 0;
26 struct sms** list_del; //SMS-DELIVER
27 unsigned int lsdel = 0;
28 struct sms** list_sr; //SMS-STATUS-REPORT
29 unsigned int lssr = 0;
30 struct sms** list_uns; //unsupported types
31 unsigned int lsuns = 0;
32 unsigned int listsize = 0;
33
34 if (list == NULL || list[0] == NULL) return;
35
36 //count items in list;
37 while (list[listsize] != NULL) ++listsize;
38
39 //splitting into type lists
40 list_sub = mem_alloc((listsize+1)*sizeof(struct sms*),0);
41 list_del = mem_alloc((listsize+1)*sizeof(struct sms*),0);
42 list_sr = mem_alloc((listsize+1)*sizeof(struct sms*),0);
43 list_uns = mem_alloc((listsize+1)*sizeof(struct sms*),0);
44 listsize = 0;
45 //do type sorting
46 while (list[listsize] != NULL) {
47 switch (list[listsize]->decoded->pdu->options.type) {
48 case SMS_TYPE_SUBMIT:
49 list_sub[lssub++] = list[listsize];
50 break;
51 case SMS_TYPE_DELIVER:
52 list_del[lsdel++] = list[listsize];
53 break;
54 case SMS_TYPE_STATUS_REPORT:
55 list_sr[lssr++] = list[listsize];
56 break;
57 default:
58 list_uns[lsuns++] = list[listsize];
59 break;
60 }
61 ++listsize;
62 }
63 list_sub[lssub] = NULL;
64 list_del[lsdel] = NULL;
65 list_sr[lssr] = NULL;
66 list_uns[lsuns] = NULL;
67
68 //subsorting
69 sms_pdu_sort(list_sub,sub_order);
70 sms_pdu_sort(list_del,sub_order);
71 sms_pdu_sort(list_sr,sub_order);
72
73 //merging to list
74 listsize = 0;
75 for (lsuns = 0; list_uns[lsuns] != NULL; ++lsuns) list[listsize++] = list_uns[lsuns];
76 for (lssub = 0; list_sub[lssub] != NULL; ++lssub) list[listsize++] = list_sub[lssub];
77 for (lssr = 0; list_sr[lssr] != NULL; ++lssr) list[listsize++] = list_sr[lssr];
78 for (lsdel = 0; list_del[lsdel] != NULL; ++lsdel) list[listsize++] = list_del[lsdel];
79 list[listsize] = NULL;
80 mem_realloc(list_uns,0);
81 mem_realloc(list_sub,0);
82 mem_realloc(list_sr,0);
83 mem_realloc(list_del,0);
84 }
85
86 //as input for argument 4 of qsort
87 static
sms_pdu_sort_slot(const void * s1,const void * s2)88 int sms_pdu_sort_slot (const void* s1, const void* s2) {
89 const struct sms* sms1 = *((const struct sms**)s1);
90 const struct sms* sms2 = *((const struct sms**)s2);
91 int slot1 = sms1->encoded[sms1->decoded->pdu->partnum]->slot;
92 int slot2 = sms2->encoded[sms1->decoded->pdu->partnum]->slot;
93 return slot1-slot2;
94 }
95
96 //as input for argument 4 of qsort
97 static
sms_pdu_sort_time(const void * s1,const void * s2)98 int sms_pdu_sort_time (const void* s1, const void* s2) {
99 const struct sms* sms1 = *((const struct sms**)s1);
100 const struct sms* sms2 = *((const struct sms**)s2);
101 struct sms_pdu_time* t1 = &sms1->decoded->pdu->timedata;
102 struct sms_pdu_time* t2 = &sms2->decoded->pdu->timedata;
103 if (t1->format != t2->format) return t1->format-t2->format;
104 else return t1->value-t2->value;
105 }
106
sms_pdu_sort(struct sms ** list,const char * order)107 void sms_pdu_sort (struct sms** list, const char* order) {
108 char* new_order;
109 char* orders[] = { "type", "slot", "time" };
110 unsigned int listsize = 0;
111
112 if (list == NULL || list[0] == NULL || str_len(order) == 0) return;
113
114 //count items in list;
115 while (list[listsize] != NULL) ++listsize;
116
117 //find next sorting item
118 new_order = strchr(order,',');
119 if (new_order != NULL) {
120 do {
121 ++new_order;
122 } while (isspace((int)*new_order) &&
123 *new_order != 0);
124 }
125
126 if (strncasecmp(order,orders[0],strlen(orders[0])) == 0) {
127 /* type sorting */
128 sms_pdu_sort_type(list,new_order);
129 } else if (strncasecmp(order,orders[1],strlen(orders[1])) == 0) {
130 /* slot sorting */
131 qsort(list,listsize,sizeof(*list),sms_pdu_sort_slot);
132 } else if (strncasecmp(order,orders[2],strlen(orders[2])) == 0) {
133 /* time sorting */
134 qsort(list,listsize,sizeof(*list),sms_pdu_sort_time);
135 }
136 }
137