📄 query_man.c
字号:
static char rcsid[] = "$Id: query_man.c,v 2.2 2000/01/21 17:37:33 sxw Exp $";/* * query_man.c -- Broker query manager interface * * DEBUG: section 75, level 1 Broker query manager routines * section 75, level 4 Broker query_list debugging * AUTHOR: Harvest derived * * Harvest Indexer http://www.tardis.ed.ac.uk/harvest/ * --------------------------------------------------- * * The Harvest Indexer is a continued development of code developed by * the Harvest Project. Development is carried out by numerous individuals * in the Internet community, and is not officially connected with the * original Harvest Project or its funding sources. * * Please mail harvest@tardis.ed.ac.uk if you are interested in participating * in the development effort. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* ---------------------------------------------------------------------- * Copyright (c) 1994, 1995. All rights reserved. * * The Harvest software was developed by the Internet Research Task * Force Research Group on Resource Discovery (IRTF-RD): * * Mic Bowman of Transarc Corporation. * Peter Danzig of the University of Southern California. * Darren R. Hardy of the University of Colorado at Boulder. * Udi Manber of the University of Arizona. * Michael F. Schwartz of the University of Colorado at Boulder. * Duane Wessels of the University of Colorado at Boulder. * * This copyright notice applies to software in the Harvest * ``src/'' directory only. Users should consult the individual * copyright notices in the ``components/'' subdirectories for * copyright information about other software bundled with the * Harvest source code distribution. * * TERMS OF USE * * The Harvest software may be used and re-distributed without * charge, provided that the software origin and research team are * cited in any use of the system. Most commonly this is * accomplished by including a link to the Harvest Home Page * (http://harvest.cs.colorado.edu/) from the query page of any * Broker you deploy, as well as in the query result pages. These * links are generated automatically by the standard Broker * software distribution. * * The Harvest software is provided ``as is'', without express or * implied warranty, and with no support nor obligation to assist * in its use, correction, modification or enhancement. We assume * no liability with respect to the infringement of copyrights, * trade secrets, or any patents, and are not responsible for * consequential damages. Proper use of the Harvest software is * entirely the responsibility of the user. * * DERIVATIVE WORKS * * Users may make derivative works from the Harvest software, subject * to the following constraints: * * - You must include the above copyright notice and these * accompanying paragraphs in all forms of derivative works, * and any documentation and other materials related to such * distribution and use acknowledge that the software was * developed at the above institutions. * * - You must notify IRTF-RD regarding your distribution of * the derivative work. * * - You must clearly notify users that your are distributing * a modified version and not the original Harvest software. * * - Any derivative product is also subject to these copyright * and use restrictions. * * Note that the Harvest software is NOT in the public domain. We * retain copyright, as specified above. * * HISTORY OF FREE SOFTWARE STATUS * * Originally we required sites to license the software in cases * where they were going to build commercial products/services * around Harvest. In June 1995 we changed this policy. We now * allow people to use the core Harvest software (the code found in * the Harvest ``src/'' directory) for free. We made this change * in the interest of encouraging the widest possible deployment of * the technology. The Harvest software is really a reference * implementation of a set of protocols and formats, some of which * we intend to standardize. We encourage commercial * re-implementations of code complying to this set of standards. * */#include "broker.h"#include "log.h"#ifndef MAX_ATTRIBUTES#define MAX_ATTRIBUTES 256#endif/* Global variables */qlist_t *query_list = NULL;int t_flag = 0;long sincetime = 0L;char *errstr = NULL;char *QM_op = NULL; /* name of operation to perform */int QM_opaqueflag = 0;int QM_descflag = 0;int QM_gotphrase = 0;char *QM_attlist[MAX_ATTRIBUTES];int QM_nattlist = 0;extern char *DIRpath;extern char *input_buffer;extern int input_bufsz;extern int input_bufferp;/* Global functions */extern int yyparse();extern int yyrestart();/* Local variables */static int nqueries = 1, nbulk = 1, nacomd = 1;/* Local functions */static void admin_log();/* Shared data structures */Buffer *admin_return = NULL;/* * QM_query_manager - Based on an event, process a query and * return information on the socket. */int QM_query_manager(inev)event_t *inev;{ int ret = 0; int ttype = inev->type; int sock = inev->sock; char *tmps = inev->queri; time_t ptime = 0; /* initialize global variables */ query_list = NULL; t_flag = 0; sincetime = 0L; if (errstr != NULL) { xfree(errstr); errstr = NULL; } switch (ttype) { case UQUERY: Log("Processing Query %d: %s\n", nqueries++, tmps); LOGQUERY(tmps); break; case ADMIN: admin_log(nacomd, tmps); nacomd++; LOGADMIN(tmps); break; case QBULK: case ABULK: Log("Processing Bulk Transfer %d: %s\n", nbulk++, tmps); LOGBULK(tmps); break; default: Log("Processing client request: %s\n", tmps); break; } /* * This sucks. flex and lex don't work remotely the same. For both * flex, we need to read from a memory string rather than a file. * So we set our input_buffer variables to the query. Then we * call yyparse() to parse the query. If we're running flex, then * we need to call yyrestart() *after* the yyparse(); if you call * it before the first yyparse() - core dump. We're using stdin * as the argument; it's ignored anyway. If you use NULL or something * else - core dump. As for lex, query.l defines a dummy yyrestart() * where we do our own thing. -Darren */ input_buffer = tmps; input_bufsz = strlen(tmps); input_bufferp = 0; Debug(75, 1, ("QM_query_manager: query string is (%d bytes)\n\t%s\n", input_bufsz, input_buffer)); do_IND_Init_Flags(); QM_opaqueflag = 0; /* Show opaque data or not? */ QM_descflag = 0; /* Display Descriptions or not */ QM_gotphrase = 0; /* A quote string was present */ QM_nattlist = 0; memset(QM_attlist, '\0', MAX_ATTRIBUTES * sizeof(char *)); if (QM_op != NULL) { xfree(QM_op); QM_op = NULL; } ret = yyparse(); yyrestart(stdin); if (ret == 1) { switch (ttype) { case UQUERY: Log("User query is invalid.\n"); LOGQUERYERR(PARSERR); QM_free_qlist(query_list); SWRITE(sock, PARSERR, PARSERR_S); break; case ADMIN: Log("Administrative command is invalid.\n"); LOGADMIN_R(ADMINERR); SWRITE(sock, ADMINERR, ADMINERR_S); break; case QBULK: Log("Bulk query is invalid.\n"); LOGBULKERR(PARSERR); QM_free_qlist(query_list); (void)QM_send_bulk_err(sock); break; case ABULK: Log("Bulk query is invalid.\n"); LOGBULKERR(PARSERR); (void)QM_send_bulk_err(sock); break; default: errorlog("QM_query_manager: We should never be here!: %s, line %d, ttype=%d\n", __FILE__, __LINE__, ttype); break; } close(sock); return ERROR; } /* * Before we do a user query, we need to perform 2 write's on * the socket to the client to test whether or not the client * will be able to receive the query results. * We have to do two writes because the first will complete even * though the other side is gone. */ if (t_flag == UQUERY) { (void) write(sock, PIPECHK, strlen(PIPECHK)); if (write(sock, PIPECHK, strlen(PIPECHK)) == -1) { errorlog("Client is gone -- aborting user query.\n"); close(sock); if (query_list) QM_free_qlist(query_list); return ERROR; } } switch (t_flag) { case UQUERY: if (query_list) { (void) do_IND_do_query(query_list, sock, t_flag, ptime); QM_free_qlist(query_list); } else { LOGQUERYERR(PARSERR); SWRITE(sock, PARSERR, PARSERR_S); } break; case QBULK: ptime = (time_t) sincetime; if (query_list) { (void) do_IND_do_query(query_list, sock, t_flag, ptime); QM_free_qlist(query_list); } else { LOGBULKERR(PARSERR); (void)QM_send_bulk_err(sock); } break; case ABULK: ptime = (time_t) sincetime; RG_bulk_query(sock, ptime); break; case QDELETE: if (query_list) { (void)do_IND_Index_Start(); ret = do_IND_do_query(query_list, sock, t_flag, ptime); (void)do_IND_Index_Flush(); QM_free_qlist(query_list); (void)RG_Sync_Registry(); if (ret == SUCCESS) { LOGADMIN_R(ADMINSUC); SWRITE(sock, ADMINSUC, ADMINSUC_S); } else { LOGADMIN_R(ADMINERR); SWRITE(sock, ADMINERR, ADMINERR_S); } } else { LOGADMIN_R(ADMINERR); SWRITE(sock, ADMINERR, ADMINERR_S); } break; case ADMIN: LOGADMIN_R(ADMINSUC); if (admin_return) { Debug(75,1,("QM_query_manager: returning %s\n", admin_return->data)); SWRITE(sock, admin_return->data, admin_return->length); free_buffer(admin_return); } else { Debug(75,1,("QM_query_manager: returning %s\n", ADMINSUC)); SWRITE(sock, ADMINSUC, ADMINSUC_S); } admin_return = NULL; break; default: errorlog("QM_query_manager: Fatal internal error 2: %d.\n", t_flag); break; } (void) close(sock); return SUCCESS;}/* Free a query argument list */int QM_free_args(arg)arg_t *arg;{ arg_t *t, *next; for (t=arg; t; t=next) { next = t->next; Debug (75, 4, ("Freeing arg=%x; next=%x\n", t, next)); switch (t->type) { case FUNCTION: Debug (75, 4, ("Arg is FUNCTION, calling QM_free_qlist(ptr=%x)\n", t->ptr)); if (t->ptr) QM_free_qlist ((qlist_t *) t->ptr); break; case STRING: Debug (75, 4, ("Arg is STRING, freeing %x='%s'\n", t->ptr, t->ptr)); if (t->ptr) { xfree (t->ptr); t->ptr = NULL; } break; default: Debug (75, 4, ("Arg is Unknown!\n")); break; } xfree (t); t = NULL; } return SUCCESS;}/* Recursively free a query list */int QM_free_qlist(qptr)qlist_t *qptr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -