/[radius]/radius/radiusd/sql.c
ViewVC logotype

Diff of /radius/radiusd/sql.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.61 by gray, Thu Jun 19 12:39:42 2003 UTC revision 1.62 by gray, Thu Jul 17 16:24:17 2003 UTC
# Line 39  Line 39 
39  static void sql_check_config(SQL_cfg *);  static void sql_check_config(SQL_cfg *);
40  static struct sql_connection *attach_sql_connection(int type);  static struct sql_connection *attach_sql_connection(int type);
41  static void detach_sql_connection(int type);  static void detach_sql_connection(int type);
42    static void sql_conn_destroy(struct sql_connection **conn);
43    
44  static char *getline();  static char *getline();
45  static int get_boolean(char *str, int *retval);  static int get_boolean(char *str, int *retval);
# Line 75  static struct sql_connection *sql_conn[S Line 76  static struct sql_connection *sql_conn[S
76  #define STMT_INTERFACE             22  #define STMT_INTERFACE             22
77  #define STMT_CHECK_ATTR_QUERY      23  #define STMT_CHECK_ATTR_QUERY      23
78    
79    
80    /* *********************** Configuration File Parser *********************** */
81    
82  static FILE  *sqlfd;  static FILE  *sqlfd;
83  static int line_no;  static int line_no;
84  static char *cur_line, *cur_ptr;  static char *cur_line, *cur_ptr;
# Line 482  rad_sql_init() Line 486  rad_sql_init()
486          return 0;          return 0;
487  }  }
488    
 static void  
 sql_conn_destroy(struct sql_connection **conn)  
 {  
         if (*conn) {  
                 disp_sql_disconnect(*conn);  
                 efree(*conn);  
                 *conn = NULL;  
         }  
 }  
   
489  void  void
490  radiusd_sql_shutdown()  radiusd_sql_shutdown()
491  {  {
# Line 564  sql_check_config(SQL_cfg *cfg) Line 558  sql_check_config(SQL_cfg *cfg)
558                 cfg->doauth));                 cfg->doauth));
559  }  }
560    
   
561  void  void
562  sql_flush()  sql_flush()
563  {  {
# Line 574  sql_flush() Line 567  sql_flush()
567          radiusd_sql_shutdown();          radiusd_sql_shutdown();
568  }  }
569    
570    
571    /* ********************************* SQL Cache ***************************** */
572    static void
573    sql_result_destroy(SQL_RESULT *res)
574    {
575            size_t i;
576            
577            if (!res)
578                    return;
579            efree(res->query);
580            for (i = 0; i < res->ntuples; i++) {
581                    size_t j;
582                    for (j = 0; j < res->nfields; j++)
583                            efree(res->tuple[i][j]);
584                    efree(res->tuple[i]);
585            }
586            efree(res->tuple);
587            efree(res);
588    }
589    
590    static size_t
591    sql_cache_level(struct sql_connection *conn)
592    {
593            if (conn->tail < conn->head)
594                    return conn->tail + SQL_CACHE_SIZE - conn->head;
595            else
596                    return conn->tail - conn->head;
597    }
598    
599    static void
600    sql_cache_destroy(struct sql_connection *conn)
601    {
602            size_t i;
603    
604            for (; sql_cache_level(conn) > 0;
605                 conn->head = (conn->head + 1) % SQL_CACHE_SIZE)
606                    sql_result_destroy(conn->cache[conn->head]);
607    }
608    
609    static void
610    sql_cache_insert(struct sql_connection *conn, SQL_RESULT *res)
611    {
612            debug(1,("cache: %d,(%d,%d)",sql_cache_level(conn),conn->head,conn->tail));
613            if (sql_cache_level(conn) >= SQL_CACHE_SIZE-1) {
614                    sql_result_destroy(conn->cache[conn->head]);
615                    conn->head = (conn->head + 1) % SQL_CACHE_SIZE;
616                    debug(1,("head: %d,%d", conn->head,conn->tail));
617            }
618            debug(1,("inserting at pos %d", conn->tail));
619            conn->cache[conn->tail] = res;
620            conn->tail = (conn->tail + 1) % SQL_CACHE_SIZE;
621            debug(1,("tail: %d,%d", conn->head,conn->tail));
622    }
623    
624    static SQL_RESULT *
625    sql_cache_retrieve(struct sql_connection *conn, char *query)
626    {
627            void *data;
628            SQL_RESULT *res;
629            size_t i;
630            
631            debug(1,("query: %s",query));
632            res = emalloc(sizeof(*res));
633            res->query = estrdup(query);
634            res->nfields = res->ntuples = 0;
635            res->tuple = NULL;
636            data = disp_sql_exec(conn, query);
637            if (!data) {
638                    sql_cache_insert(conn, res);
639                    return res;
640            }
641            
642            if (disp_sql_num_tuples(conn, data, &res->ntuples)
643                || disp_sql_num_columns(conn, data, &res->nfields)) {
644                    disp_sql_free(conn, data);
645                    res->nfields = res->ntuples = 0;
646                    sql_cache_insert(conn, res);
647                    return res;
648            }
649    
650            res->tuple = emalloc(sizeof(res->tuple[0]) * res->ntuples);
651            for (i = 0; i < res->ntuples
652                         && disp_sql_next_tuple(conn, data) == 0; i++) {
653                    int j;
654    
655                    res->tuple[i] = emalloc(sizeof(res->tuple[0][0]) * res->nfields);
656                            
657                    for (j = 0; j < res->nfields; j++) {
658                            char *p = disp_sql_column(conn, data, j);
659                            chop(p);
660                            res->tuple[i][j] = estrdup(p);
661                    }
662            }
663                    
664            disp_sql_free(conn, data);
665    
666            sql_cache_insert(conn, res);
667            
668            return res;
669    }
670    
671    static SQL_RESULT *
672    sql_cache_lookup(struct sql_connection *conn, char *query)
673    {
674            size_t i;
675    
676            debug(1,("looking up %s", query));
677            for (i = conn->head; i != conn->tail;
678                 i = (i + 1) % SQL_CACHE_SIZE) {
679                    if (strcmp(conn->cache[i]->query, query) == 0) {
680                            debug(1,("found at %d", i));
681                            return conn->cache[i];
682                    }
683            }
684            debug(1,("NOT FOUND"));
685            return NULL;
686    }
687    
688    
689    /* *********************** SQL Connection Handling ************************* */
690    
691  struct sql_connection *  struct sql_connection *
692  attach_sql_connection(int type)  attach_sql_connection(int type)
693  {  {
# Line 590  attach_sql_connection(int type) Line 704  attach_sql_connection(int type)
704                  conn->last_used = now;                  conn->last_used = now;
705                  conn->type = type;                  conn->type = type;
706    
707                    conn->head = 0;
708                    conn->tail = 0;
709                  sql_conn[type] = conn;                  sql_conn[type] = conn;
710          }          }
711    
# Line 622  detach_sql_connection(int type) Line 738  detach_sql_connection(int type)
738          }          }
739  }  }
740    
741    static void
742    sql_conn_destroy(struct sql_connection **conn)
743    {
744            if (*conn) {
745                    disp_sql_disconnect(*conn);
746                    sql_cache_destroy(*conn);
747                    efree(*conn);
748                    *conn = NULL;
749            }
750    }
751    
752    
753    /* ************************* Interface Functions *************************** */
754    
755  /*ARGSUSED*/  /*ARGSUSED*/
756  void  void
757  rad_sql_cleanup(int type, void *req ARG_UNUSED)  rad_sql_cleanup(int type, void *req ARG_UNUSED)
# Line 780  rad_sql_checkgroup(req, groupname) Line 910  rad_sql_checkgroup(req, groupname)
910  {  {
911          int   rc = -1;          int   rc = -1;
912          struct sql_connection *conn;          struct sql_connection *conn;
         void *data;  
         char *p;  
913          char *query;          char *query;
914          struct obstack stack;          struct obstack stack;
915            SQL_RESULT *res;
916            size_t i;
917                    
918          if (sql_cfg.doauth == 0 || sql_cfg.group_query == NULL)          if (sql_cfg.doauth == 0 || sql_cfg.group_query == NULL)
919                  return -1;                  return -1;
# Line 795  rad_sql_checkgroup(req, groupname) Line 925  rad_sql_checkgroup(req, groupname)
925          obstack_init(&stack);          obstack_init(&stack);
926                    
927          query = radius_xlate(&stack, sql_cfg.group_query, req, NULL);          query = radius_xlate(&stack, sql_cfg.group_query, req, NULL);
928            res = sql_cache_lookup(conn, query);
929            if (!res) {
930                    res = sql_cache_retrieve(conn, query);
931                    if (!res)
932                            return rc;
933            }
934            obstack_free(&stack, NULL);
935    
936          data = disp_sql_exec(conn, query);          if (res->ntuples == 0 || res->nfields == 0)
937          if (data) {                  return rc;
938                  while (rc != 0  
939                         && disp_sql_next_tuple(conn, data) == 0) {          for (i = 0; rc != 0 && i < res->ntuples; i++) {
940                          if ((p = disp_sql_column(conn, data, 0)) == NULL)                  if (strcmp(res->tuple[i][0], groupname) == 0)
941                                  break;                          rc = 0;
                         chop(p);  
                         if (strcmp(p, groupname) == 0)  
                                 rc = 0;  
                 }  
                 disp_sql_free(conn, data);  
942          }          }
943                    
         obstack_free(&stack, NULL);  
944          return rc;          return rc;
945  }  }
946    
# Line 819  rad_sql_retrieve_pairs(struct sql_connec Line 950  rad_sql_retrieve_pairs(struct sql_connec
950                         VALUE_PAIR **return_pairs,                         VALUE_PAIR **return_pairs,
951                         int op_too)                         int op_too)
952  {  {
953          void *data;          SQL_RESULT *res;
954          int i;          size_t i;
955                    
956          data = disp_sql_exec(conn, query);          res = sql_cache_lookup(conn, query);
957          if (!data)          if (!res) {
958                  return 0;                  res = sql_cache_retrieve(conn, query);
959                            if (!res)
960          for (i = 0; disp_sql_next_tuple(conn, data) == 0; i++) {                          return 0;
961                  VALUE_PAIR *pair;          }
962                  char *attribute;  
963                  char *value;          if (res->ntuples == 0
964                  int op;              || res->nfields < 2
965                                || (op_too && res->nfields < 3))
966                  if (!(attribute = disp_sql_column(conn, data, 0))                  return 0;
967                      || !(value =  disp_sql_column(conn, data, 1)))          
968                          break;          for (i = 0; i < res->ntuples; i++) {
969                  if (op_too) {                  int op;
970                          char *opstr;                  VALUE_PAIR *pair;
971                          opstr = disp_sql_column(conn, data, 2);                  
972                          if (!opstr)                  if (op_too) {
973                                  break;                          char *opstr = res->tuple[i][2];
                         chop(opstr);  
974                          op = str_to_op(opstr);                          op = str_to_op(opstr);
975                          if (op == NUM_OPERATORS) {                          if (op == NUM_OPERATORS) {
976                                  radlog(L_NOTICE,                                  radlog(L_NOTICE,
977                                         _("SQL: invalid operator: %s"), opstr);                                         _("SQL: invalid operator: %s"), opstr);
978                                  continue;                                  continue;
979                          }                          }
980                  } else                  } else
981                          op = OPERATOR_EQUAL;                          op = OPERATOR_EQUAL;
982    
983                  chop(attribute);                  pair = install_pair(__FILE__, __LINE__,
984                  chop(value);                                      res->tuple[i][0],
985                                                        op,
986                  pair = install_pair(__FILE__, __LINE__, attribute, op, value);                                      res->tuple[i][1]);
987                                    
988                  if (pair) {                  if (pair) {
989                          avl_merge(return_pairs, &pair);                          avl_merge(return_pairs, &pair);
990                          avl_free(pair);                          avl_free(pair);
991                  }                  }
992          }          }              
993    
994          disp_sql_free(conn, data);          return i;
         return i;  
995  }  }
996                            
997  int  int
998  rad_sql_reply_attr_query(RADIUS_REQ *req, VALUE_PAIR **reply_pairs)  rad_sql_reply_attr_query(RADIUS_REQ *req, VALUE_PAIR **reply_pairs)
999  {  {

Legend:
Removed from v.1.61  
changed lines
  Added in v.1.62

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26