00001 #include <aquosa/qsup_lib.h>
00002 #include <sys/types.h>
00003 #include <pwd.h>
00004 #include <stdio.h>
00005 #include <grp.h>
00006 #include <string.h>
00007 #include <errno.h>
00008
00009 #define MAX_LINE 1024
00010 #define MAX_RULENAME 6
00011 #define MAX_TOKENLENGTH 32
00012
00013
00014 #define PARSE_ERROR 1
00015 #define INVALID_RULE 2
00016 #define NO_ENTRY 3
00017
00018 typedef enum rules {LEVEL=1, GROUP, USER} rule_type;
00019
00020
00021 struct rule
00022 {
00023 rule_type r_type;
00024 int rule_id;
00025 union value
00026 {
00027 qsup_constraints_t qc;
00028 qos_bw_t qb;
00029 } rule_value;
00030 };
00031
00032
00033 void pushout_nums (char** buf, int n)
00034 {
00035 int i = 1;
00036 while ((n = n / 10) != 0) i++;
00037
00038 *buf = *buf + i;
00039 }
00040
00041 int fill_rule (char* buf, struct rule* r)
00042 {
00043 char* str;
00044 float f_value;
00045 unsigned int uint_value;
00046
00047 if (r->r_type == LEVEL)
00048 {
00049 r->rule_value.qb = 0;
00050 if ((str = strstr (buf, "max=")) != NULL)
00051 {
00052 if (sscanf (str, "max=%f", &f_value) == EOF)
00053 return PARSE_ERROR;
00054 else
00055 r->rule_value.qb = d2bw (f_value);
00056 }
00057 if (r->rule_value.qb == 0)
00058 return INVALID_RULE;
00059 return 0;
00060 }
00061 else
00062 {
00063 r->rule_value.qc.level = -1;
00064 r->rule_value.qc.weight = -1;
00065 r->rule_value.qc.max_bw = 0;
00066 r->rule_value.qc.max_min_bw = 0;
00067 r->rule_value.qc.flags_mask = 0;
00068
00069 if ((str = strstr (buf, "level=")) != NULL)
00070 if (sscanf (str, "level=%d", &(r->rule_value.qc.level)) == EOF)
00071 return PARSE_ERROR;
00072 if ((str = strstr (buf, "weight=")) != NULL)
00073 if (sscanf (str, "weight=%d", &(r->rule_value.qc.weight)) == EOF)
00074 return PARSE_ERROR;
00075 if ((str = strstr (buf, "max=")) != NULL)
00076 {
00077 if (sscanf (str, "max=%f", &f_value) == EOF)
00078 return PARSE_ERROR;
00079 else
00080 r->rule_value.qc.max_bw = d2bw (f_value);
00081 }
00082 if ((str = strstr (buf, "max_gua=")) != NULL)
00083 {
00084 if (sscanf (str, "max_gua=%f", &f_value) == EOF)
00085 return PARSE_ERROR;
00086 else
00087 r->rule_value.qc.max_min_bw = d2bw (f_value);
00088 }
00089 if ((str = strstr (buf, "flags_mask=")) != NULL)
00090 {
00091 if (sscanf (str, "flags_mask=%x", &uint_value) == EOF)
00092 return PARSE_ERROR;
00093 else
00094 r->rule_value.qc.flags_mask = uint_value;
00095 }
00096
00097 if (r->rule_value.qc.level == -1 || r->rule_value.qc.max_bw == 0 || r->rule_value.qc.max_min_bw == 0)
00098 return INVALID_RULE;
00099
00100 return 0;
00101 }
00102 }
00103
00104
00105 rule_type getrule (char** buf)
00106 {
00107 char* rule_name = malloc (sizeof (char) * MAX_RULENAME);
00108
00109 sscanf (*buf, "%s", rule_name);
00110 *buf = *buf + strlen (rule_name);
00111
00112 if (!strcmp (rule_name, "level"))
00113 {
00114 free(rule_name);
00115 return LEVEL;
00116 }
00117 if (!strcmp (rule_name, "group"))
00118 {
00119 free(rule_name);
00120 return GROUP;
00121 }
00122 if (!strcmp (rule_name, "user"))
00123 {
00124 free(rule_name);
00125 return USER;
00126 }
00127 return 0;
00128 }
00129
00130 int parse_rule (struct rule* r, char* buf)
00131 {
00132 int id_is_numeric;
00133
00134 while (buf[0] == ' ') buf++;
00135
00136 if (buf[0] - '0' < 10 && buf[0] - '0' >= 0)
00137 id_is_numeric = 1;
00138 else
00139 id_is_numeric = 0;
00140
00141 switch (r->r_type)
00142 {
00143 case LEVEL:
00144 if (!(id_is_numeric))
00145 return PARSE_ERROR;
00146
00147 sscanf (buf, "%d", &(r->rule_id));
00148
00149 pushout_nums (&buf, r->rule_id);
00150 break;
00151 case GROUP:
00152 if (!(id_is_numeric))
00153 {
00154 char str[MAX_TOKENLENGTH];
00155 struct group* g;
00156
00157 sscanf (buf, "%s", str);
00158 if ((g = getgrnam (str)) == 0)
00159 return NO_ENTRY;
00160
00161 r->rule_id = g->gr_gid;
00162 buf = buf + strlen(str);
00163 }
00164 else
00165 {
00166
00167 sscanf (buf, "%d", &(r->rule_id));
00168
00169 pushout_nums (&buf, r->rule_id);
00170 }
00171
00172 break;
00173 case USER:
00174 if (!(id_is_numeric))
00175 {
00176 char str[MAX_TOKENLENGTH];
00177 struct passwd* p;
00178
00179 sscanf (buf, "%s", str);
00180 if ((p = getpwnam (str)) == 0 )
00181 return NO_ENTRY;
00182
00183 r->rule_id = p->pw_uid;
00184 buf = buf + strlen(str);
00185 }
00186 else
00187 {
00188
00189 sscanf (buf, "%d", &(r->rule_id));
00190
00191 pushout_nums (&buf, r->rule_id);
00192 }
00193 break;
00194 default:
00195 return 1;
00196 }
00197
00198 while (buf[0] == ' ') buf++;
00199 return fill_rule (buf, r);
00200 }
00201
00202
00203 int main(int argc, char* argv[])
00204 {
00205 FILE *supconf_i;
00206 char line[MAX_LINE];
00207 char* buffer;
00208 struct rule* a_rule;
00209
00210 if (argc != 2 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)
00211 {
00212 fprintf (stderr, "Usage: %s {-h | --help | <rules_file>}\n", argv[0]);
00213 exit(1);
00214 }
00215
00216
00217 supconf_i = fopen (argv[1], "r");
00218 if (supconf_i == NULL) {
00219 fprintf(stderr, "Could not open rules file '%s': %s\n",
00220 argv[1], strerror(errno));
00221 exit(-1);
00222 }
00223 qos_chk_ok_exit (qsup_init ());
00224
00225
00226 while (fgets (line, MAX_LINE, supconf_i) != NULL)
00227 {
00228 buffer = line;
00229
00230 while (buffer[0] == ' ') buffer++;
00231
00232 if (buffer[0] == '#' || buffer[0] == '\n')
00233 continue;
00234
00235 a_rule = malloc (sizeof (struct rule));
00236
00237
00238 a_rule->r_type = getrule (&buffer);
00239
00240 if (!a_rule->r_type)
00241 {
00242 free (a_rule);
00243 continue;
00244 }
00245
00246
00247 if (parse_rule (a_rule, buffer) != 0)
00248 {
00249 free (a_rule);
00250 continue;
00251 }
00252
00253 switch (a_rule->r_type)
00254 {
00255 case LEVEL:
00256 qos_chk_ok_exit (qsup_add_level_rule (a_rule->rule_id, a_rule->rule_value.qb));
00257 break;
00258 case GROUP:
00259 qos_chk_ok_exit (qsup_add_group_rule (a_rule->rule_id, &(a_rule->rule_value.qc)));
00260 break;
00261 case USER:
00262 qos_chk_ok_exit (qsup_add_user_rule (a_rule->rule_id, &(a_rule->rule_value.qc)));
00263 break;
00264 default:
00265 break;
00266 }
00267 free (a_rule);
00268 }
00269
00270 qsup_cleanup();
00271 return 0;
00272 }
00273
00274