📄 xlat.c
字号:
openbraces++; *pa++ = *p++; break; case '}': openbraces--; if (openbraces == *open) { p++; stop=1; } else { *pa++ = *p++; } break; /* * Attr-Name1:-Attr-Name2 * * Use Attr-Name1, and if not found, * use Attr-Name2. */ case ':': if (p[1] == '-') { p += 2; stop = 1; break; } /* else FALL-THROUGH */ default: *pa++ = *p++; break; } } *pa = '\0'; /* * Look up almost everything in the new tree of xlat * functions. this makes it a little quicker... */ if ((c = xlat_find(attrname)) != NULL) { if (!c->internal) DEBUG("radius_xlat: Running registered xlat function of module %s for string \'%s\'", c->module, attrname+ c->length + 1); retlen = c->do_xlat(c->instance, request, attrname+(c->length+1), q, freespace, func); /* If retlen is 0, treat it as not found */ if (retlen == 0) { found = 0; } else { found = 1; q += retlen; } /* * Not in the default xlat database. Must be * a bare attribute number. */ } else if ((retlen = xlat_packet(&xlat_inst[1], request, attrname, q, freespace, func)) > 0) { found = 1; q += retlen; /* * Look up the name, in order to get the correct * debug message. */#ifndef NDEBUG } else if (dict_attrbyname(attrname) == NULL) { /* * No attribute by that name, return an error. */ DEBUG2("WARNING: Attempt to use unknown xlat function, or non-existent attribute in string %%{%s}", attrname);#endif } /* else the attribute is known, but not in the request */ /* * Skip to last '}' if attr is found * The rest of the stuff within the braces is * useless if we found what we need */ if (found) { while((*p != '\0') && (openbraces > 0)) { /* * Handle escapes outside of the loop. */ if (*p == '\\') { p++; if (!*p) break; p++; /* get & ignore next character */ continue; } switch (*p) { default: break; /* * Bare brace */ case '{': openbraces++; break; case '}': openbraces--; break; } p++; /* skip the character */ } } *open = openbraces; *from = p; *to = q;}/* * If the caller doesn't pass xlat an escape function, then * we use this one. It simplifies the coding, as the check for * func == NULL only happens once. */static int xlat_copy(char *out, int outlen, const char *in){ int len = 0; while (*in) { /* * Truncate, if too much. */ if (len >= outlen) { break; } /* * Copy data. * * FIXME: Do escaping of bad stuff! */ *out = *in; out++; in++; len++; } *out = '\0'; return len;}/* * Replace %<whatever> in a string. * * See 'doc/variables.txt' for more information. */int radius_xlat(char *out, int outlen, const char *fmt, REQUEST *request, RADIUS_ESCAPE_STRING func){ int i, c,freespace; const char *p; char *q; VALUE_PAIR *tmp; struct tm *TM, s_TM; char tmpdt[40]; /* For temporary storing of dates */ int openbraces=0; /* * Catch bad modules. */ if (!fmt || !out || !request) return 0; /* * Ensure that we always have an escaping function. */ if (func == NULL) { func = xlat_copy; } q = out; p = fmt; while (*p) { /* Calculate freespace in output */ freespace = outlen - (q - out); if (freespace <= 1) break; c = *p; if ((c != '%') && (c != '$') && (c != '\\')) { /* * We check if we're inside an open brace. If we are * then we assume this brace is NOT literal, but is * a closing brace and apply it */ if ((c == '}') && openbraces) { openbraces--; p++; /* skip it */ continue; } *q++ = *p++; continue; } /* * There's nothing after this character, copy * the last '%' or "$' or '\\' over to the output * buffer, and exit. */ if (*++p == '\0') { *q++ = c; break; } if (c == '\\') { switch(*p) { case '\\': *q++ = *p; break; case 't': *q++ = '\t'; break; case 'n': *q++ = '\n'; break; default: *q++ = c; *q++ = *p; break; } p++; /* * Hmmm... ${User-Name} is a synonym for * %{User-Name}. * * Why, exactly? */ } else if (c == '$') switch(*p) { case '{': /* Attribute by Name */ decode_attribute(&p, &q, freespace, &openbraces, request, func); break; default: *q++ = c; *q++ = *p++; break; } else if (c == '%') switch(*p) { case '{': decode_attribute(&p, &q, freespace, &openbraces, request, func); break; case '%': *q++ = *p++; break; case 'a': /* Protocol: */ q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_FRAMED_PROTOCOL),PW_TYPE_INTEGER, func); p++; break; case 'c': /* Callback-Number */ q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_CALLBACK_NUMBER),PW_TYPE_STRING, func); p++; break; case 'd': /* request day */ TM = localtime_r(&request->timestamp, &s_TM); strftime(tmpdt,sizeof(tmpdt),"%d",TM); strNcpy(q,tmpdt,freespace); q += strlen(q); p++; break; case 'f': /* Framed IP address */ q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_FRAMED_IP_ADDRESS),PW_TYPE_IPADDR, func); p++; break; case 'i': /* Calling station ID */ q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_CALLING_STATION_ID),PW_TYPE_STRING, func); p++; break; case 'l': /* request timestamp */ snprintf(tmpdt, sizeof(tmpdt), "%lu", (unsigned long) request->timestamp); strNcpy(q,tmpdt,freespace); q += strlen(q); p++; break; case 'm': /* request month */ TM = localtime_r(&request->timestamp, &s_TM); strftime(tmpdt,sizeof(tmpdt),"%m",TM); strNcpy(q,tmpdt,freespace); q += strlen(q); p++; break; case 'n': /* NAS IP address */ q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_NAS_IP_ADDRESS),PW_TYPE_IPADDR, func); p++; break; case 'p': /* Port number */ q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_NAS_PORT),PW_TYPE_INTEGER, func); p++; break; case 's': /* Speed */ q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_CONNECT_INFO),PW_TYPE_STRING, func); p++; break; case 't': /* request timestamp */ CTIME_R(&request->timestamp, q, freespace); q += strlen(q); p++; break; case 'u': /* User name */ q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_USER_NAME),PW_TYPE_STRING, func); p++; break; case 'A': /* radacct_dir */ strNcpy(q,radacct_dir,freespace-1); q += strlen(q); p++; break; case 'C': /* ClientName */ strNcpy(q,client_name(request->packet->src_ipaddr),freespace-1); q += strlen(q); p++; break; case 'D': /* request date */ TM = localtime_r(&request->timestamp, &s_TM); strftime(tmpdt,sizeof(tmpdt),"%Y%m%d",TM); strNcpy(q,tmpdt,freespace); q += strlen(q); p++; break; case 'H': /* request hour */ TM = localtime_r(&request->timestamp, &s_TM); strftime(tmpdt,sizeof(tmpdt),"%H",TM); strNcpy(q,tmpdt,freespace); q += strlen(q); p++; break; case 'L': /* radlog_dir */ strNcpy(q,radlog_dir,freespace-1); q += strlen(q); p++; break; case 'M': /* MTU */ q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_FRAMED_MTU),PW_TYPE_INTEGER, func); p++; break; case 'R': /* radius_dir */ strNcpy(q,radius_dir,freespace-1); q += strlen(q); p++; break; case 'S': /* request timestamp in SQL format*/ TM = localtime_r(&request->timestamp, &s_TM); strftime(tmpdt,sizeof(tmpdt),"%Y-%m-%d %H:%M:%S",TM); strNcpy(q,tmpdt,freespace); q += strlen(q); p++; break; case 'T': /* request timestamp */ TM = localtime_r(&request->timestamp, &s_TM); strftime(tmpdt,sizeof(tmpdt),"%Y-%m-%d-%H.%M.%S.000000",TM); strNcpy(q,tmpdt,freespace); q += strlen(q); p++; break; case 'U': /* Stripped User name */ q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_STRIPPED_USER_NAME),PW_TYPE_STRING, func); p++; break; case 'V': /* Request-Authenticator */ if (request->packet->verified) strNcpy(q,"Verified",freespace-1); else strNcpy(q,"None",freespace-1); q += strlen(q); p++; break; case 'Y': /* request year */ TM = localtime_r(&request->timestamp, &s_TM); strftime(tmpdt,sizeof(tmpdt),"%Y",TM); strNcpy(q,tmpdt,freespace); q += strlen(q); p++; break; case 'Z': /* Full request pairs except password */ tmp = request->packet->vps; while (tmp && (freespace > 3)) { if (tmp->attribute != PW_PASSWORD) { *q++ = '\t'; i = vp_prints(q,freespace-2,tmp); q += i; freespace -= (i+2); *q++ = '\n'; } tmp = tmp->next; } p++; break; default: DEBUG2("WARNING: Unknown variable '%%%c': See 'doc/variables.txt'", *p); if (freespace > 2) { *q++ = '%'; *q++ = *p++; } break; } } *q = '\0'; DEBUG2("radius_xlat: '%s'", out); return strlen(out);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -