00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <limits.h>
00036 #include "sr_module.h"
00037 #include "dprint.h"
00038 #include "parser/msg_parser.h"
00039 #include "flags.h"
00040 #include "error.h"
00041 #include "stdlib.h"
00042 #include "hashes.h"
00043 #include "clist.h"
00044 #include "mem/mem.h"
00045
00046 int setflag( struct sip_msg* msg, flag_t flag ) {
00047 msg->flags |= 1 << flag;
00048 return 1;
00049 }
00050
00051 int resetflag( struct sip_msg* msg, flag_t flag ) {
00052 msg->flags &= ~ (1 << flag);
00053 return 1;
00054 }
00055
00056 int isflagset( struct sip_msg* msg, flag_t flag ) {
00057 return (msg->flags & (1<<flag)) ? 1 : -1;
00058 }
00059
00060 int flag_in_range( flag_t flag ) {
00061 if (flag > MAX_FLAG ) {
00062 LOG(L_ERR, "ERROR: message flag %d too high; MAX=%d\n",
00063 flag, MAX_FLAG );
00064 return 0;
00065 }
00066 if (flag<0) {
00067 LOG(L_ERR, "ERROR: message flag (%d) must be in range %d..%d\n",
00068 flag, 0, MAX_FLAG );
00069 return 0;
00070 }
00071 return 1;
00072 }
00073
00074
00075
00076 #define FLAGS_NAME_HASH_ENTRIES 32
00077
00078 struct flag_entry{
00079 struct flag_entry* next;
00080 struct flag_entry* prev;
00081 str name;
00082 int no;
00083 };
00084
00085
00086 struct flag_hash_head{
00087 struct flag_entry* next;
00088 struct flag_entry* prev;
00089 };
00090
00091 static struct flag_hash_head name2flags[FLAGS_NAME_HASH_ENTRIES];
00092 static unsigned char registered_flags[MAX_FLAG+1];
00093
00094
00095 void init_named_flags()
00096 {
00097 int r;
00098
00099 for (r=0; r<FLAGS_NAME_HASH_ENTRIES; r++)
00100 clist_init(&name2flags[r], next, prev);
00101 }
00102
00103
00104
00105
00106 int check_flag(int n)
00107 {
00108 if (!flag_in_range(n))
00109 return -1;
00110 if (registered_flags[n]){
00111 LOG(L_WARN, "WARNING: check_flag: flag %d is already used by "
00112 " a named flag\n", n);
00113 }
00114 return 0;
00115 }
00116
00117
00118 inline static struct flag_entry* flag_search(struct flag_hash_head* lst,
00119 char* name, int len)
00120 {
00121 struct flag_entry* fe;
00122
00123 clist_foreach(lst, fe, next){
00124 if ((fe->name.len==len) && (memcmp(fe->name.s, name, len)==0)){
00125
00126 return fe;
00127 }
00128 }
00129 return 0;
00130 }
00131
00132
00133
00134
00135 inline static struct flag_entry* get_flag_entry(char* name, int len)
00136 {
00137 int h;
00138
00139 h=get_hash1_raw(name, len) & (FLAGS_NAME_HASH_ENTRIES-1);
00140 return flag_search(&name2flags[h], name, len);
00141 }
00142
00143
00144
00145
00146 int get_flag_no(char* name, int len)
00147 {
00148 struct flag_entry* fe;
00149
00150 fe=get_flag_entry(name, len);
00151 return (fe)?fe->no:-1;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 int register_flag(char* name, int pos)
00165 {
00166 struct flag_entry* e;
00167 int len;
00168 unsigned int r;
00169 static unsigned int crt_flag=0;
00170 unsigned int last_flag;
00171 unsigned int h;
00172
00173 len=strlen(name);
00174 h=get_hash1_raw(name, len) & (FLAGS_NAME_HASH_ENTRIES-1);
00175
00176 e=flag_search(&name2flags[h], name, len);
00177 if (e){
00178 LOG(L_ERR, "ERROR: register_flag: flag %.*s already registered\n",
00179 len, name);
00180 return -2;
00181 }
00182
00183 if (pos!=-1){
00184 if ((pos<0) || (pos>MAX_FLAG)){
00185 LOG(L_ERR, "ERROR: register_flag: invalid flag %.*s "
00186 "position(%d)\n", len, name, pos);
00187 return -4;
00188 }
00189 if (registered_flags[pos]!=0){
00190 LOG(L_WARN, "WARNING: register_flag: %.*s: flag %d already in "
00191 "use under another name\n", len, name, pos);
00192
00193 }
00194 }else{
00195
00196 last_flag=crt_flag+(MAX_FLAG+1);
00197 for (; crt_flag!=last_flag; crt_flag++){
00198 r=crt_flag%(MAX_FLAG+1);
00199 if (registered_flags[r]==0){
00200 pos=r;
00201 break;
00202 }
00203 }
00204 if (pos==-1){
00205 LOG(L_ERR, "ERROR: register_flag: could not register %.*s"
00206 " - too many flags\n", len, name);
00207 return -5;
00208 }
00209 }
00210 registered_flags[pos]++;
00211
00212 e=pkg_malloc(sizeof(struct flag_entry));
00213 if (e==0){
00214 LOG(L_ERR, "ERROR: register_flag: memory allocation failure\n");
00215 return -3;
00216 }
00217 e->name.s=name;
00218 e->name.len=len;
00219 e->no=pos;
00220 clist_insert(&name2flags[h], e, next, prev);
00221 return pos;
00222 }
00223
00224
00225
00226 #ifdef _GET_AWAY
00227
00228
00229 static int fixup_t_flag(void** param, int param_no)
00230 {
00231 unsigned int *code;
00232 char *c;
00233 int token;
00234
00235 DBG("DEBUG: fixing flag: %s\n", (char *) (*param));
00236
00237 if (param_no!=1) {
00238 LOG(L_ERR, "ERROR: TM module: only parameter #1 for flags can be"
00239 " fixed\n");
00240 return E_BUG;
00241 };
00242
00243 if ( !(code =pkg_malloc( sizeof( unsigned int) )) ) return E_OUT_OF_MEM;
00244
00245 *code = 0;
00246 c = *param;
00247 while ( *c && (*c==' ' || *c=='\t')) c++;
00248
00249 token=1;
00250 if (strcasecmp(c, "white")==0) *code=FL_WHITE;
00251 else if (strcasecmp(c, "yellow")==0) *code=FL_YELLOW;
00252 else if (strcasecmp(c, "green")==0) *code=FL_GREEN;
00253 else if (strcasecmp(c, "red")==0) *code=FL_RED;
00254 else if (strcasecmp(c, "blue")==0) *code=FL_BLUE;
00255 else if (strcasecmp(c, "magenta")==0) *code=FL_MAGENTA;
00256 else if (strcasecmp(c, "brown")==0) *code=FL_BROWN;
00257 else if (strcasecmp(c, "black")==0) *code=FL_BLACK;
00258 else if (strcasecmp(c, "acc")==0) *code=FL_ACC;
00259 else {
00260 token=0;
00261 while ( *c && *c>='0' && *c<='9' ) {
00262 *code = *code*10+ *c-'0';
00263 if (*code > (sizeof( flag_t ) * CHAR_BIT - 1 )) {
00264 LOG(L_ERR, "ERROR: TM module: too big flag number: %s; MAX=%d\n",
00265 (char *) (*param), sizeof( flag_t ) * CHAR_BIT - 1 );
00266 goto error;
00267 }
00268 c++;
00269 }
00270 }
00271 while ( *c && (*c==' ' || *c=='\t')) c++;
00272
00273 if ( *code == 0 ) {
00274 LOG(L_ERR, "ERROR: TM module: bad flag number: %s\n", (char *) (*param));
00275 goto error;
00276 }
00277
00278 if (*code < FL_MAX && token==0) {
00279 LOG(L_ERR, "ERROR: TM module: too high flag number: %s (%d)\n; lower number"
00280 " bellow %d reserved\n", (char *) (*param), *code, FL_MAX );
00281 goto error;
00282 }
00283
00284
00285 pkg_free( *param );
00286
00287 *param = code;
00288
00289 return 0;
00290
00291 error:
00292 pkg_free( code );
00293 return E_CFG;
00294 }
00295
00296
00297 #endif