static char* check_ident_reply(char* reply) { char* token; char* end; char* vector[USERID_TOKEN_COUNT]; int count = token_vector(reply, ':', vector, USERID_TOKEN_COUNT); if (USERID_TOKEN_COUNT != count) return 0; /* * second token is the reply type */ token = vector[IDENT_REPLY_TYPE]; if (EmptyString(token)) return 0; while (IsSpace(*token)) ++token; if (0 != strncmp(token, "USERID", 6)) return 0; /* * third token is the os type */ token = vector[IDENT_OS_TYPE]; if (EmptyString(token)) return 0; while (IsSpace(*token)) ++token; /* * Unless "OTHER" is specified as the operating system * type, the server is expected to return the "normal" * user identification of the owner of this connection. * "Normal" in this context may be taken to mean a string * of characters which uniquely identifies the connection * owner such as a user identifier assigned by the system * administrator and used by such user as a mail * identifier, or as the "user" part of a user/password * pair used to gain access to system resources. When an * operating system is specified (e.g., anything but * "OTHER"), the user identifier is expected to be in a * more or less immediately useful form - e.g., something * that could be used as an argument to "finger" or as a * mail address. */ if (0 == strncmp(token, "OTHER", 5)) return 0; /* * fourth token is the username */ token = vector[IDENT_INFO]; if (EmptyString(token)) return 0; while (IsSpace(*token)) ++token; /* * look for the end of the username, terminators are '\0, @, <SPACE>, :' */ for (end = token; *end; ++end) { if (IsSpace(*end) || '@' == *end || ':' == *end) break; } *end = '\0'; return token; }
bool parse(const sm_type &sm_, iterator &iter_, basic_match_results<sm_type> &results_, token_vector &productions_, std::multimap<typename sm_type::id_type, token_vector> *prod_map_) { while (results_.entry.action != error) { switch (results_.entry.action) { case error: break; case shift: results_.stack.push_back(results_.entry.param); productions_.push_back(typename token_vector::value_type(iter_->id, iter_->first, iter_->second)); if (results_.token_id != 0) { ++iter_; } results_.token_id = iter_->id; if (results_.token_id == iterator::value_type::npos()) { results_.entry.action = error; results_.entry.param = unknown_token; } else { results_.entry = sm_._table[results_.stack.back() * sm_._columns + results_.token_id]; } break; case reduce: { const std::size_t size_ = sm_._rules[results_.entry.param].second.size(); token<iterator> token_; if (size_) { if (prod_map_) { prod_map_->insert(std::make_pair(results_.entry.param, token_vector(productions_.end() - size_, productions_.end()))); } token_.first = (productions_.end() - size_)->first; token_.second = productions_.back().second; results_.stack.resize(results_.stack.size() - size_); productions_.resize(productions_.size() - size_); } else { if (productions_.empty()) { token_.first = token_.second = iter_->first; } else { token_.first = token_.second = productions_.back().second; } } results_.token_id = sm_._rules[results_.entry.param].first; results_.entry = sm_._table[results_.stack.back() * sm_._columns + results_.token_id]; token_.id = results_.token_id; productions_.push_back(token_); break; } case go_to: results_.stack.push_back(results_.entry.param); results_.token_id = iter_->id; results_.entry = sm_._table[results_.stack.back() * sm_._columns + results_.token_id]; break; } if (results_.entry.action == accept) { const std::size_t size_ = sm_._rules[results_.entry.param].second.size(); if (size_) { results_.stack.resize(results_.stack.size() - size_); } break; } } return results_.entry.action == accept; }