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

Diff of /radius/radiusd/files.c

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

revision 1.85 by gray, Tue Oct 14 07:10:42 2003 UTC revision 1.86 by gray, Tue Oct 14 13:49:09 2003 UTC
# Line 88  locus_free(LOCUS *loc) Line 88  locus_free(LOCUS *loc)
88  Symtab          *user_tab;     /* raddb/users  */  Symtab          *user_tab;     /* raddb/users  */
89  Symtab          *deny_tab;     /* raddb/access.deny */  Symtab          *deny_tab;     /* raddb/access.deny */
90    
91  MATCHING_RULE   *huntgroups;   /* raddb/huntgroups */  static RAD_LIST /* of MATCHING_RULE */  *huntgroups;   /* raddb/huntgroups */
92  MATCHING_RULE   *hints;        /* raddb/hints */  static RAD_LIST /* of MATCHING_RULE */  *hints;        /* raddb/hints */
93  RAD_LIST /* of CLIENT */ *clients; /* raddb/clients */  static RAD_LIST /* of CLIENT */ *clients; /* raddb/clients */
94  RAD_LIST /* of RADCK_TYPE */ *radck_type;   /* raddb/nastypes */  static RAD_LIST /* of RADCK_TYPE */ *radck_type;   /* raddb/nastypes */
95    
96  static struct keyword op_tab[] = {  static struct keyword op_tab[] = {
97          { "=", OPERATOR_EQUAL },          { "=", OPERATOR_EQUAL },
# Line 120  static int user_find_sym(char *name, RAD Line 120  static int user_find_sym(char *name, RAD
120  int user_find_db(char *name, RADIUS_REQ *req,  int user_find_db(char *name, RADIUS_REQ *req,
121                          VALUE_PAIR **check_pairs, VALUE_PAIR **reply_pairs);                          VALUE_PAIR **check_pairs, VALUE_PAIR **reply_pairs);
122  #endif  #endif
123  static MATCHING_RULE *file_read(int cf_file, char *name);  static RAD_LIST *file_read(int cf_file, char *name);
124    
125  int  int
126  comp_op(int op, int result)  comp_op(int op, int result)
# Line 210  free_user_entry(User_symbol *sym) Line 210  free_user_entry(User_symbol *sym)
210          return 0;          return 0;
211  }  }
212    
213  struct temp_list {  struct temp_data {
214          int cf_file;          int cf_file;
215          MATCHING_RULE *head;          RAD_LIST *list;
         MATCHING_RULE *tail;  
216  };  };
217    
218  int  int
219  add_pairlist(void *closure, LOCUS *loc,  add_pairlist(void *closure, LOCUS *loc,
220               char *name, VALUE_PAIR *lhs, VALUE_PAIR *rhs)               char *name, VALUE_PAIR *lhs, VALUE_PAIR *rhs)
221  {  {
222          struct temp_list *tlist = closure;          struct temp_data *data = closure;
223          MATCHING_RULE *pl;          MATCHING_RULE *rule;
224                    
225          if ((lhs == NULL && rhs == NULL)          if ((lhs == NULL && rhs == NULL)
226              || fix_check_pairs(tlist->cf_file, loc, name, &lhs)              || fix_check_pairs(data->cf_file, loc, name, &lhs)
227              || fix_reply_pairs(tlist->cf_file, loc, name, &rhs)) {              || fix_reply_pairs(data->cf_file, loc, name, &rhs)) {
228                  radlog_loc(L_ERR, loc, _("discarding entry `%s'"), name);                  radlog_loc(L_ERR, loc, _("discarding entry `%s'"), name);
229                  avl_free(lhs);                  avl_free(lhs);
230                  avl_free(rhs);                  avl_free(rhs);
231                  return 0;                  return 0;
232          }          }
233    
234          pl = emalloc(sizeof(MATCHING_RULE));          rule = emalloc(sizeof(MATCHING_RULE));
235          pl->name = estrdup(name);          rule->name = estrdup(name);
236          pl->lhs = lhs;          rule->lhs = lhs;
237          pl->rhs = rhs;          rule->rhs = rhs;
238          locus_dup(&pl->loc, loc);          locus_dup(&rule->loc, loc);
239          if (tlist->tail)          list_append(data->list, rule);
                 tlist->tail->next = pl;  
         else  
                 tlist->head = pl;  
         tlist->tail = pl;  
240          return  0;          return  0;
241  }  }
242    
# Line 253  read_users(char *name) Line 248  read_users(char *name)
248          return parse_file(name, user_tab, add_user_entry);          return parse_file(name, user_tab, add_user_entry);
249  }  }
250    
251  MATCHING_RULE *  static RAD_LIST *
252  file_read(int cf_file, char *name)  file_read(int cf_file, char *name)
253  {  {
254          struct temp_list tmp;          struct temp_data tmp;
255    
256          tmp.cf_file = cf_file;          tmp.cf_file = cf_file;
257          tmp.head = tmp.tail = NULL;          tmp.list = list_create();
258          parse_file(name, &tmp, add_pairlist);          parse_file(name, &tmp, add_pairlist);
259          return tmp.head;          return tmp.list;
260  }  }
261    
262  enum lookup_state {  enum lookup_state {
# Line 482  nextkn(char **sptr, char *token, int tok Line 477  nextkn(char **sptr, char *token, int tok
477          /* skip whitespace */          /* skip whitespace */
478          while (**sptr && isws(**sptr))          while (**sptr && isws(**sptr))
479                  ++(*sptr);                  ++(*sptr);
480          if (!*sptr)          if (!**sptr)
481                  return 0;                  return -1;
482          start = token;          start = token;
483          if (**sptr == '"') {          if (**sptr == '"') {
484                  (*sptr)++;                  (*sptr)++;
# Line 555  userparse(char *buffer, VALUE_PAIR **fir Line 550  userparse(char *buffer, VALUE_PAIR **fir
550          loc.line = 0;          loc.line = 0;
551                    
552          state = PS_LHS;          state = PS_LHS;
553          while (nextkn(&buffer, token, sizeof(token))) {          while (nextkn(&buffer, token, sizeof(token)) >= 0) {
554                  switch (state) {                  switch (state) {
555                  case PS_LHS:                  case PS_LHS:
556                          if (token[0] == '\n' || token[0] == '#')                          if (token[0] == '\n' || token[0] == '#')
# Line 616  userparse(char *buffer, VALUE_PAIR **fir Line 611  userparse(char *buffer, VALUE_PAIR **fir
611  /* Provide a support for backward-compatible attributes Replace-User-Name  /* Provide a support for backward-compatible attributes Replace-User-Name
612     and Rewrite-Function */     and Rewrite-Function */
613  static void  static void
614  hints_eval_compat(RADIUS_REQ *req, VALUE_PAIR *name_pair, MATCHING_RULE *i)  hints_eval_compat(RADIUS_REQ *req, VALUE_PAIR *name_pair, MATCHING_RULE *rule)
615  {  {
616          VALUE_PAIR      *tmp;          VALUE_PAIR      *tmp;
617    
618          /* Let's see if we need to further modify the username */          /* Let's see if we need to further modify the username */
619          if ((tmp = avl_find(i->rhs, DA_REPLACE_USER_NAME))          if ((tmp = avl_find(rule->rhs, DA_REPLACE_USER_NAME))
620              || (tmp = avl_find(i->lhs, DA_REPLACE_USER_NAME))) {              || (tmp = avl_find(rule->lhs, DA_REPLACE_USER_NAME))) {
621                  char *ptr;                  char *ptr;
622                  struct obstack hints_stk;                  struct obstack hints_stk;
623    
# Line 635  hints_eval_compat(RADIUS_REQ *req, VALUE Line 630  hints_eval_compat(RADIUS_REQ *req, VALUE
630          }          }
631                                    
632          /* Is the rewrite function specified? */          /* Is the rewrite function specified? */
633          if ((tmp = avl_find(i->rhs, DA_REWRITE_FUNCTION))          if ((tmp = avl_find(rule->rhs, DA_REWRITE_FUNCTION))
634              || (tmp = avl_find(i->lhs, DA_REWRITE_FUNCTION))) {              || (tmp = avl_find(rule->lhs, DA_REWRITE_FUNCTION))) {
635                  if (rewrite_eval(tmp->avp_strvalue, req, NULL, NULL)) {                  if (rewrite_eval(tmp->avp_strvalue, req, NULL, NULL)) {
636                          radlog_loc(L_ERR, &i->loc, "%s(): %s",                          radlog_loc(L_ERR, &rule->loc, "%s(): %s",
637                                     tmp->avp_strvalue,                                     tmp->avp_strvalue,
638                                     _("not defined"));                                     _("not defined"));
639                  }                  }
# Line 656  hints_setup(RADIUS_REQ *req) Line 651  hints_setup(RADIUS_REQ *req)
651          VALUE_PAIR      *name_pair;          VALUE_PAIR      *name_pair;
652          VALUE_PAIR      *orig_name_pair;          VALUE_PAIR      *orig_name_pair;
653          VALUE_PAIR      *tmp;          VALUE_PAIR      *tmp;
654          MATCHING_RULE   *i;          MATCHING_RULE   *rule;
655          int             matched = 0;          int             matched = 0;
656            ITERATOR *itr;
657            
658          /* Add Proxy-Replied pair if necessary */          /* Add Proxy-Replied pair if necessary */
659          switch (req->code) {          switch (req->code) {
660          case RT_AUTHENTICATION_ACK:          case RT_AUTHENTICATION_ACK:
# Line 700  hints_setup(RADIUS_REQ *req) Line 696  hints_setup(RADIUS_REQ *req)
696                          avl_merge(&request_pairs, &tmp);                          avl_merge(&request_pairs, &tmp);
697          }          }
698    
699          for (i = hints; i; i = i->next) {          itr = iterator_create(hints);
700            for (rule = iterator_first(itr); rule; rule = iterator_next(itr)) {
701                  int do_strip;                  int do_strip;
702                  VALUE_PAIR *add;                  VALUE_PAIR *add;
703                                    
704                  if (matches(req, name_pair->avp_strvalue, i, newname))                  if (matches(req, name_pair->avp_strvalue, rule, newname))
705                          continue;                          continue;
706    
707                  matched++;                  matched++;
708                                    
709                  debug(1, ("matched %s at %s:%lu", i->name, i->loc.file,                  debug(1, ("matched %s at %s:%lu", rule->name, rule->loc.file,
710                            (unsigned long) i->loc.line));                            (unsigned long) rule->loc.line));
711                    
712                  add = avl_dup(i->rhs);                  add = avl_dup(rule->rhs);
713                    
714                  /* See if we need to adjust the name. */                  /* See if we need to adjust the name. */
715                  do_strip = 1;                  do_strip = 1;
716                  if ((tmp = avl_find(i->rhs, DA_STRIP_USER_NAME)) != NULL                  if ((tmp = avl_find(rule->rhs, DA_STRIP_USER_NAME)) != NULL
717                      || (tmp = avl_find(i->lhs, DA_STRIP_USER_NAME)) != NULL)                      || (tmp = avl_find(rule->lhs, DA_STRIP_USER_NAME)) != NULL)
718                          do_strip = tmp->avp_lvalue;                          do_strip = tmp->avp_lvalue;
719                                    
720                  if (do_strip)                  if (do_strip)
721                          string_replace(&name_pair->avp_strvalue, newname);                          string_replace(&name_pair->avp_strvalue, newname);
722    
723                  /* Handle Rewrite-Function and Replace-User-Name */                  /* Handle Rewrite-Function and Replace-User-Name */
724                  hints_eval_compat(req, name_pair, i);                  hints_eval_compat(req, name_pair, rule);
725                  /* Evaluate hints */                  /* Evaluate hints */
726                  radius_eval_avl(req, add); /*FIXME: return value?*/                  radius_eval_avl(req, add); /*FIXME: return value?*/
727                                    
# Line 743  hints_setup(RADIUS_REQ *req) Line 740  hints_setup(RADIUS_REQ *req)
740                                    
741                  /* Ok, let's see if we need to further check the                  /* Ok, let's see if we need to further check the
742                     hint's rules */                     hint's rules */
743                  if (((tmp = avl_find(i->rhs, DA_FALL_THROUGH)) != NULL                  if (((tmp = avl_find(rule->rhs, DA_FALL_THROUGH)) != NULL
744                       || (tmp = avl_find(i->lhs, DA_FALL_THROUGH)) != NULL)                       || (tmp = avl_find(rule->lhs, DA_FALL_THROUGH)) != NULL)
745                      && tmp->avp_lvalue)                      && tmp->avp_lvalue)
746                          continue;                          continue;
747                  break;                  break;
748          }          }
749    
750            iterator_destroy(&itr);
751            
752          if (matched) {          if (matched) {
753                  if (orig_name_pair)                  if (orig_name_pair)
754                          avl_add_pair(&request_pairs, orig_name_pair);                          avl_add_pair(&request_pairs, orig_name_pair);
# Line 777  hints_setup(RADIUS_REQ *req) Line 776  hints_setup(RADIUS_REQ *req)
776  int  int
777  huntgroup_match(RADIUS_REQ *req, char *huntgroup)  huntgroup_match(RADIUS_REQ *req, char *huntgroup)
778  {  {
779          MATCHING_RULE *pl;          MATCHING_RULE *rule;
780                    ITERATOR *itr;
781          for (pl = huntgroups; pl; pl = pl->next) {  
782                  if (strcmp(pl->name, huntgroup) != 0)          if (!huntgroups)
783                    return 0;
784            itr = iterator_create(huntgroups);
785            for (rule = iterator_first(itr); rule; rule = iterator_next(itr)) {
786                    if (strcmp(rule->name, huntgroup) != 0)
787                          continue;                          continue;
788                  if (paircmp(req, pl->lhs, NULL) == 0) {                  if (paircmp(req, rule->lhs, NULL) == 0) {
789                          debug(1, ("matched %s at %s:%lu",                          debug(1, ("matched %s at %s:%lu",
790                                    pl->name, pl->loc.file,                                    rule->name, rule->loc.file,
791                                    (unsigned long) pl->loc.line));                                    (unsigned long) rule->loc.line));
792                          break;                          break;
793                  }                  }
794          }          }
795            iterator_destroy(&itr);
796          return (pl != NULL);          return (rule != NULL);
797  }  }
798    
799    
# Line 804  int Line 807  int
807  huntgroup_access(RADIUS_REQ *radreq)  huntgroup_access(RADIUS_REQ *radreq)
808  {  {
809          VALUE_PAIR      *pair;          VALUE_PAIR      *pair;
810          MATCHING_RULE   *pl;          MATCHING_RULE   *rule;
811            ITERATOR *itr;
812          int             r = 1;          int             r = 1;
813    
814          if (huntgroups == NULL)          if (huntgroups == NULL)
815                  return 1;                  return 1;
816    
817          for (pl = huntgroups; pl; pl = pl->next) {          itr = iterator_create(huntgroups);
818            for (rule = iterator_first(itr); rule; rule = iterator_next(itr)) {
819                  /*                  /*
820                   *      See if this entry matches.                   *      See if this entry matches.
821                   */                   */
822                  if (paircmp(radreq, pl->lhs, NULL) != 0)                  if (paircmp(radreq, rule->lhs, NULL) != 0)
823                          continue;                          continue;
824                  debug(1, ("matched huntgroup at %s:%lu", pl->loc.file,                  debug(1, ("matched huntgroup at %s:%lu", rule->loc.file,
825                            (unsigned long) pl->loc.line));                            (unsigned long) rule->loc.line));
826                  r = paircmp(radreq, pl->rhs, NULL) == 0;                  r = paircmp(radreq, rule->rhs, NULL) == 0;
827                  break;                  break;
828          }          }
829            iterator_destroy(&itr);
830            
831  #ifdef DA_REWRITE_FUNCTION  #ifdef DA_REWRITE_FUNCTION
832          if (pl &&          if (rule &&
833              (pair = avl_find(pl->lhs, DA_REWRITE_FUNCTION)) != NULL) {              (pair = avl_find(rule->lhs, DA_REWRITE_FUNCTION)) != NULL) {
834                  if (rewrite_eval(pair->avp_strvalue, radreq, NULL, NULL)) {                  if (rewrite_eval(pair->avp_strvalue, radreq, NULL, NULL)) {
835                          radlog_loc(L_ERR, &pl->loc, "%s(): %s",                          radlog_loc(L_ERR, &rule->loc, "%s(): %s",
836                                     pair->avp_strvalue,                                     pair->avp_strvalue,
837                                     _("not defined"));                                     _("not defined"));
838                  }                  }
# Line 1268  paircmp(RADIUS_REQ *request, VALUE_PAIR Line 1274  paircmp(RADIUS_REQ *request, VALUE_PAIR
1274                  if (debug_on(20)) {                  if (debug_on(20)) {
1275                          radlog(L_DEBUG,                          radlog(L_DEBUG,
1276                                 "check_item: %s",                                 "check_item: %s",
1277                                 format_pair(check_item, &save));                                 format_pair(check_item, 1, &save));
1278                          free(save);                          free(save);
1279                  }                  }
1280    
# Line 1315  paircmp(RADIUS_REQ *request, VALUE_PAIR Line 1321  paircmp(RADIUS_REQ *request, VALUE_PAIR
1321                  if (debug_on(20)) {                  if (debug_on(20)) {
1322                          radlog(L_DEBUG,                          radlog(L_DEBUG,
1323                                 "auth_item: %s",                                 "auth_item: %s",
1324                                 format_pair(auth_item, &save));                                 format_pair(auth_item, 1, &save));
1325                          free(save);                          free(save);
1326                  }                  }
1327    
# Line 1390  paircmp(RADIUS_REQ *request, VALUE_PAIR Line 1396  paircmp(RADIUS_REQ *request, VALUE_PAIR
1396  /*  /*
1397   * Free a MATCHING_RULE   * Free a MATCHING_RULE
1398   */   */
1399  void  static int
1400  matchrule_free(MATCHING_RULE **pl)  matching_rule_free(void *item, void *data ARG_UNUSED)
1401  {  {
1402          MATCHING_RULE *p, *next;          MATCHING_RULE *p = item;
1403            
1404          for (p = *pl; p; p = next) {          if (p->name)
1405                  if (p->name)                  efree(p->name);
1406                          efree(p->name);          if (p->lhs)
1407                  if (p->lhs)                  avl_free(p->lhs);
1408                          avl_free(p->lhs);          if (p->rhs)
1409                  if (p->rhs)                  avl_free(p->rhs);
1410                          avl_free(p->rhs);          efree(p);
                 next = p->next;  
                 efree(p);  
         }  
         *pl = NULL;  
1411  }  }
1412    
1413  /* ***************************************************************************  /* ***************************************************************************
# Line 1646  reload_data(enum reload_what what, int * Line 1648  reload_data(enum reload_what what, int *
1648                  break;                  break;
1649                                    
1650          case reload_huntgroups:          case reload_huntgroups:
1651                  matchrule_free(&huntgroups);                  list_destroy(&huntgroups, matching_rule_free, NULL);
1652                  path = mkfilename(radius_dir, RADIUS_HUNTGROUPS);                  path = mkfilename(radius_dir, RADIUS_HUNTGROUPS);
1653                  huntgroups = file_read(CF_HUNTGROUPS, path);                  huntgroups = file_read(CF_HUNTGROUPS, path);
1654                  efree(path);                  efree(path);
1655                  break;                  break;
1656                                    
1657          case reload_hints:          case reload_hints:
1658                  matchrule_free(&hints);                  list_destroy(&hints, matching_rule_free, NULL);
1659                  path = mkfilename(radius_dir, RADIUS_HINTS);                  path = mkfilename(radius_dir, RADIUS_HINTS);
1660                  hints = file_read(CF_HINTS, path);                  hints = file_read(CF_HINTS, path);
1661                  efree(path);                  efree(path);
# Line 1730  reload_config_file(enum reload_what what Line 1732  reload_config_file(enum reload_what what
1732  /* ****************************************************************************  /* ****************************************************************************
1733   * Debugging functions   * Debugging functions
1734   */   */
 static void  
 dump_pairs(FILE *fp, VALUE_PAIR *pair)  
 {  
         int etype;  
           
         for (; pair; pair = pair->next) {  
                 fprintf(fp, "\t\t%s %s ", pair->name,  
                         op_tab[pair->operator].name);  
   
                 switch (pair->type) {  
                 case TYPE_STRING:  
                         fprintf(fp, "(STRING) ");  
                         break;  
   
                 case TYPE_INTEGER:  
                         fprintf(fp, "(INTEGER) ");  
                         break;  
   
                 case TYPE_IPADDR:  
                         fprintf(fp, "(IP) ");  
                         break;  
                   
                 case TYPE_DATE:  
                         fprintf(fp, "(DATE) ");  
                         break;  
                           
                 default:  
                         fprintf(fp, "(%d) ", pair->type);  
                 }  
   
                 if (pair->eval_type != eval_const) {  
                         etype = TYPE_STRING;  
                         fprintf(fp, "=");  
                 } else  
                         etype = pair->type;  
                   
                 switch (etype) {  
                 case TYPE_STRING:  
                         fprintf(fp, "%s", pair->avp_strvalue);  
                         break;  
   
                 case TYPE_INTEGER:  
                         fprintf(fp, "%ld", pair->avp_lvalue);  
                         break;  
   
                 case TYPE_IPADDR:  
                         fprintf(fp, "%lx", pair->avp_lvalue);  
                         break;  
                   
                 case TYPE_DATE:  
                         fprintf(fp, "%ld", pair->avp_lvalue);  
                         break;  
                           
                 }  
                 fprintf(fp, "\n");  
         }  
 }  
   
1735  void  void
1736  dump_pair_list(FILE *fp, char *header, MATCHING_RULE *pl)  dump_matching_rules(FILE *fp, char *header, RAD_LIST *list)
1737  {  {
1738            MATCHING_RULE *rule;
1739            ITERATOR *itr = iterator_create(hints);
1740    
1741          fprintf(fp, "%s {\n", header);          fprintf(fp, "%s {\n", header);
1742          for ( ; pl; pl = pl->next) {          for (rule = iterator_first(itr); rule; rule = iterator_next(itr)) {
1743                  fprintf(fp, "\t%s:\n", pl->name);                  fprintf(fp, "\t%s:\n", rule->name);
1744                  fprintf(fp, "\tlhs {\n");                  fprintf(fp, "\tlhs {\n");
1745                  dump_pairs(fp, pl->lhs);                  avl_fprint(fp, "\t\t", 1, rule->lhs);
1746                  fprintf(fp, "\t}\n");                  fprintf(fp, "\t}\n");
1747    
1748                  fprintf(fp, "\trhs {\n");                  fprintf(fp, "\trhs {\n");
1749                  dump_pairs(fp, pl->rhs);                  avl_fprint(fp, "\t\t", 1, rule->rhs);
1750                  fprintf(fp, "\t}\n");                  fprintf(fp, "\t}\n");
1751          }          }
1752            iterator_destroy(&itr);
1753            
1754          fprintf(fp, "}\n");          fprintf(fp, "}\n");
1755  }  }
1756    
# Line 1810  dump_user(FILE *fp, User_symbol *sym) Line 1759  dump_user(FILE *fp, User_symbol *sym)
1759  {  {
1760          fprintf(fp, "\t%s:\n", sym->name);          fprintf(fp, "\t%s:\n", sym->name);
1761          fprintf(fp, "\tlhs {\n");          fprintf(fp, "\tlhs {\n");
1762          dump_pairs(fp, sym->check);          avl_fprint(fp, "\t\t", 1, sym->check);
1763          fprintf(fp, "\t}\n");          fprintf(fp, "\t}\n");
1764    
1765          fprintf(fp, "\trhs {\n");          fprintf(fp, "\trhs {\n");
1766          dump_pairs(fp, sym->reply);          avl_fprint(fp, "\t\t", 1, sym->reply);
1767          fprintf(fp, "\t}\n");          fprintf(fp, "\t}\n");
1768                    
1769          return 0;          return 0;
# Line 1841  dump_users_db() Line 1790  dump_users_db()
1790          symtab_iterate(user_tab, dump_user, fp);          symtab_iterate(user_tab, dump_user, fp);
1791          fprintf(fp, "}\n");          fprintf(fp, "}\n");
1792    
1793          dump_pair_list(fp, "huntgroups", huntgroups);          dump_matching_rules(fp, "huntgroups", huntgroups);
1794          dump_pair_list(fp, "hints", hints);          dump_matching_rules(fp, "hints", hints);
1795          radlog(L_INFO, _("dumped users database to %s"), RADIUS_DUMPDB_NAME);          radlog(L_INFO, _("dumped users database to %s"), RADIUS_DUMPDB_NAME);
1796          fclose(fp);          fclose(fp);
1797          efree(name);          efree(name);
# Line 1879  strip_username(int do_strip, char *name, Line 1828  strip_username(int do_strip, char *name,
1828    
1829    
1830    
   
   
   
   
   
   
   
   
   
   
   
   
   
1831    
1832    

Legend:
Removed from v.1.85  
changed lines
  Added in v.1.86

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