Exemple #1
0
int main(int argc,char **argv)
{
	edg_wll_Context		ctx;
	edg_wll_QueryRec  **conditions = NULL;
	time_t				valid = 0;
	char			   *errt, *errd;
	void		*fields = NULL;

	int	sock = -1, flags = 0;
	char	*fake_addr = NULL;
		
//	sleep(20);

	me = argv[0];
	if (edg_wll_InitContext(&ctx) != 0) {
		fprintf(stderr, "Couldn't create L&B context.\n");
		exit(1);
	}

	if ( argc < 2 ) {
		usage(NULL); goto cleanup;
	}
	if ( (argc < 2) || 
	!strcmp(argv[1], "help") || !strcmp(argv[1], "--help") || 
	!strcmp(argv[1], "-h") || !strcmp(argv[1], "-?")) 
	{
		usage(NULL); goto cleanup;
	}
	else if ( !strcmp(argv[1], "new") )
	{
		int	c;
		edg_wlc_JobId		jid;
		edg_wll_NotifId		id_out;
		int			attr = 0, i = 0, excl = 0;
		edg_wll_GssCred 	mycred;
                edg_wll_GssStatus	gss_code;
		static struct option long_options[] = {
			{"state", required_argument, 0, 'S'},
			{"jdl", no_argument, 0, 'J'},
			{"bootstrap", no_argument, 0, 'B'},
			{"terminal", no_argument, 0, 'T'},
			{"history", no_argument, 0, 'H'},
			{"anonymize", no_argument, 0, 'N'},
			{"type", no_argument, 0, 'E'},
			{0, 0, 0, 0}};
           	int option_index = 0;
		char *single, *statelist, *notif_server, *typelist, *type, *typestor;
		edg_wll_JobStatCode single_code;
		enum edg_wll_StatJobtype typecode;
		int statno, stdelims, sti;
		unsigned int notif_server_port;

#define MAX_NEW_CONDS 7
		conditions = (edg_wll_QueryRec **)calloc(MAX_NEW_CONDS + 1,sizeof(edg_wll_QueryRec *));
		conditions[0] = (edg_wll_QueryRec *)calloc(2,sizeof(edg_wll_QueryRec));

		while ((c = getopt_long(argc-1,argv+1,"j:o:v:n:s:a:t:f:cOS:JBTHNE:",long_options,&option_index)) > 0) { switch (c) {
			case 'j':
				conditions[i] = (edg_wll_QueryRec *)calloc(2,sizeof(edg_wll_QueryRec));
				conditions[i][0].attr = EDG_WLL_QUERY_ATTR_JOBID;
				conditions[i][0].op = EDG_WLL_QUERY_OP_EQUAL;
				if (edg_wlc_JobIdParse(optarg, &jid) ) {
					fprintf(stderr,"Job ID parameter not set propperly!\n");
					usage("new");
					goto cleanup;
				}
				conditions[i][0].value.j = jid;
				i++;
				edg_wll_GetParam(ctx, EDG_WLL_PARAM_NOTIF_SERVER, &notif_server);
				if (!notif_server) {
					glite_jobid_getServerParts(jid, &notif_server, &notif_server_port); 
					edg_wll_SetParam(ctx, EDG_WLL_PARAM_NOTIF_SERVER, notif_server);
					edg_wll_SetParamInt(ctx, EDG_WLL_PARAM_NOTIF_SERVER_PORT, notif_server_port);
				}
				free(notif_server);
				break;
			case 'o':
				if (excl) { usage("new"); return EX_USAGE; } else excl = 1;
				conditions[i] = (edg_wll_QueryRec *)calloc(2,sizeof(edg_wll_QueryRec));
				conditions[i][0].attr = EDG_WLL_QUERY_ATTR_OWNER;
				conditions[i][0].op = EDG_WLL_QUERY_OP_EQUAL;
				conditions[i][0].value.c = optarg;
				i++;
				break;
			case 'v':
				conditions[i] = (edg_wll_QueryRec *)calloc(2,sizeof(edg_wll_QueryRec));
				conditions[i][0].attr = EDG_WLL_QUERY_ATTR_JDL_ATTR;
				conditions[i][0].op = EDG_WLL_QUERY_OP_EQUAL;
				conditions[i][0].value.c = optarg;
				asprintf(&(conditions[i][0].attr_id.tag), "VirtualOrganisation");
				i++;
				break;
			case 'n':
				conditions[i] = (edg_wll_QueryRec *)calloc(2,sizeof(edg_wll_QueryRec));
				conditions[i][0].attr = EDG_WLL_QUERY_ATTR_NETWORK_SERVER;
				conditions[i][0].op = EDG_WLL_QUERY_OP_EQUAL;
				conditions[i][0].value.c = optarg;
				i++;
				break;
			case 's':
				if (fake_addr) { usage("new"); return EX_USAGE; }
				sock = atoi(optarg); break;
			case 'a':
				if (sock >= 0) { usage("new"); return EX_USAGE; }
				fake_addr = optarg; break;
			case 't':
				valid = time(NULL) + atol(optarg); break;
			case 'f':
				flags |= atoi(optarg); break;
			case 'J':
				flags |= EDG_WLL_STAT_CLASSADS; break;
			case 'B':
				flags |= EDG_WLL_NOTIF_BOOTSTRAP; break;
			case 'T':
				flags |= EDG_WLL_NOTIF_TERMINAL_STATES; break;
			case 'H':
				flags |= EDG_WLL_NOTIF_TERMINAL_STATES | EDG_WLL_NOTIF_HISTORY; break;
			case 'N':
				flags |= EDG_WLL_NOTIF_ANONYMIZE; break;
			case 'c':
				conditions[i] = (edg_wll_QueryRec *)calloc(2,sizeof(edg_wll_QueryRec));
				conditions[i][0].attr = EDG_WLL_QUERY_ATTR_STATUS;
				conditions[i][0].op = EDG_WLL_QUERY_OP_CHANGED;
				i++;
				break;
			case 'O':
				if (excl) { usage("new"); return EX_USAGE; } else excl = 1;
				if ( !edg_wll_gss_acquire_cred(NULL, NULL, GSS_C_INITIATE, &mycred, &gss_code) )
				{
					conditions[i] = (edg_wll_QueryRec *)calloc(2,sizeof(edg_wll_QueryRec));
					conditions[i][0].attr = EDG_WLL_QUERY_ATTR_OWNER;
					conditions[i][0].op = EDG_WLL_QUERY_OP_EQUAL;
					conditions[i][0].value.c = strdup(mycred->name);
					edg_wll_gss_release_cred(&mycred, NULL);
					i++;
				}
				else {
					fprintf(stderr,"No credentials found! Exiting. \n");	
					goto cleanup;
				}
				break;
			case 'S':
				statelist = optarg;

				statno = 0;
				stdelims = 0;
				for (sti = 0; sti < strlen(statelist); sti++) 
					if (statelist[sti] == ',') stdelims++;
				conditions[i] = (edg_wll_QueryRec *)calloc(stdelims+2,sizeof(edg_wll_QueryRec));
				while((single = strtok(statelist, ","))) {
					single_code = edg_wll_StringToStat(single);
					if (single_code != -1) {
						conditions[i][statno].attr = EDG_WLL_QUERY_ATTR_STATUS;
						conditions[i][statno].op = EDG_WLL_QUERY_OP_EQUAL;
						conditions[i][statno].value.i = single_code;
						statelist = NULL;
						statno++;
					}
					else {
						fprintf(stderr,"'%s' is not a valid state name! Exitting.\n", single);	
						goto cleanup;
					}
				}
				i++;
				break;
			case 'E':
				typelist = optarg;
				statno = 0;
				for( type = strtok_r(typelist, ",", &typestor); type ; type = strtok_r(NULL, ",", &typestor))
					statno++;
				conditions[i] = (edg_wll_QueryRec *)calloc(statno+1,sizeof(edg_wll_QueryRec));
				statno = 0;
				for( type = strtok_r(typelist, ",", &typestor); type ; type = strtok_r(NULL, ",", &typestor)) {
					typecode=edg_wll_JobtypeStrToCode(type);
					if (((int)typecode)<0) {
						fprintf(stderr,"'%s' is not a valid job type! Exitting.\n", type);	
						goto cleanup;
					}
					else {
						conditions[i][statno].attr = EDG_WLL_QUERY_ATTR_JOB_TYPE;
						conditions[i][statno].op = EDG_WLL_QUERY_OP_EQUAL;
						conditions[i][statno].value.i = typecode;
						statelist = NULL;
						statno++;
					}
				}
				i++;
				break;
			default:
				usage("new"); return EX_USAGE;
			}
			if (i > MAX_NEW_CONDS) {
				usage("new"); return EX_USAGE;
			}
		}

		if ( !edg_wll_NotifNew(ctx,
					(edg_wll_QueryRec const* const*)conditions,
					flags, sock, fake_addr, &id_out, &valid))
			fprintf(stdout,"notification ID: %s\nvalid: %s (%ld)\n",
					edg_wll_NotifIdUnparse(id_out),
					TimeToStr(valid),
					valid);
		edg_wll_NotifIdFree(id_out);
		if (attr == EDG_WLL_QUERY_ATTR_JOBID) edg_wlc_JobIdFree(jid);
		if (edg_wll_Error(ctx,&errt,&errd)) {
			fprintf(stderr, "%s: %s (%s)\n", me, errt, errd);
			return EX_IOERR;
		}
	}
	else if ( !strcmp(argv[1], "bind") )
	{
		edg_wll_NotifId		nid;
		int			c;

		while ((c = getopt(argc-1,argv+1,"s:a:t:")) > 0) switch (c) {
			case 's':
				if (fake_addr) { usage("bind"); return EX_USAGE; }
				sock = atoi(optarg); break;
			case 'a':
				if (sock >= 0) { usage("bind"); return EX_USAGE; }
				fake_addr = optarg; break;
			case 't':
				valid = time(NULL) + atol(optarg); break;
			default:
				usage("bind"); return EX_USAGE;
		}

		if ( (optind+1 == argc) || edg_wll_NotifIdParse(argv[optind+1], &nid) )
		{
			fprintf(stderr,"Notification ID parameter not set propperly!\n\n");
			usage("bind");
			return EX_USAGE;
		}
		if ( !edg_wll_NotifBind(ctx, nid, sock, fake_addr, &valid) )
			printf("valid until: %s (%ld)\n", TimeToStr(valid), valid);
		edg_wll_NotifIdFree(nid);
		if (edg_wll_Error(ctx,&errt,&errd)) {
			fprintf(stderr, "%s: %s (%s)\n", me, errt, errd);
			return EX_IOERR;
		}
	}
	else if ( !strcmp(argv[1], "receive") )
	{
		edg_wll_JobStat		stat;
		edg_wll_NotifId		nid = NULL;
		int			c;
		char	*field_arg = "owner",*err;
		time_t	client_tout = time(NULL) + 600;
	        int	refresh = 0;
		struct timeval		tout;
		time_t	opt_valid = 0,do_refresh = client_tout,now;

		while ((c = getopt(argc-1,argv+1,"s:a:i:f:t:r")) > 0) switch (c) {
			case 's':
				if (fake_addr || refresh || opt_valid) { usage("receive"); return EX_USAGE; }
				sock = atoi(optarg); break;
			case 'a':
				if (sock >= 0) { usage("receive"); return EX_USAGE; }
				fake_addr = optarg; break;
			case 'i':
				client_tout = time(NULL) + atoi(optarg); break;
			case 'f':
				field_arg = optarg; break;
			case 't':
				if (sock >= 0) { usage("receive"); return EX_USAGE; }
				opt_valid = atol(optarg); break;
			case 'r':
				if (sock >= 0) { usage("receive"); return EX_USAGE; }
				refresh = 1; break;
			default:
				usage("receive"); return EX_USAGE;
		}

		if (opt_valid == 0) opt_valid = 3600;

		if ((err = glite_lb_parse_stat_fields(field_arg,&fields))) {
			fprintf(stderr,"%s: invalid argument\n",err);
			return EX_USAGE;
		}

		memset(&stat,0,sizeof stat);

		if (sock == -1) {
			int	param = optind+1;

			if (param == argc)
			{
				fprintf(stderr, "Notification ID parameter not set propperly!\n\n");
				usage("receive");
				return EX_USAGE;
			}

			valid = time(NULL) + opt_valid;

			while (param < argc) {
				if (edg_wll_NotifIdParse(argv[param], &nid)) {
					fprintf(stderr, "Notification ID parameter not set propperly!\n\n");
					usage("receive");
					return EX_USAGE;
				}

				if (edg_wll_NotifBind(ctx, nid, -1, fake_addr, &valid) )
					goto receive_err;
				fprintf(stderr,"notification is valid until: %s (%ld)\n", TimeToStr(valid), valid);
				
				param++;
			}
			now = time(NULL);
			do_refresh = now + (valid - now)/2;
			if (refresh) fprintf(stderr,"next refresh %s (%ld)\n",
					TimeToStr(do_refresh),do_refresh);
		}

		do {
			edg_wll_NotifId		recv_nid = NULL;
			int	err;

			tout.tv_sec = (refresh && client_tout >= do_refresh ? do_refresh : client_tout)
					- time(NULL);
			if (tout.tv_sec < 0) tout.tv_sec = 0;
			tout.tv_usec = 0;

			if ( (err = edg_wll_NotifReceive(ctx, sock, &tout, &stat, &recv_nid)) ) {
				edg_wll_NotifIdFree(recv_nid);
				recv_nid = NULL; 

				if (err != ETIMEDOUT) goto receive_err;
			}
			else {
				glite_lb_print_stat_fields(fields,&stat);
				edg_wll_FreeStatus(&stat);
				stat.state = EDG_WLL_JOB_UNDEF;
			}

			if ((now = time(NULL)) >= client_tout) goto cleanup;

			if (refresh && now >= do_refresh) {
				valid = now + opt_valid;
				if (!edg_wll_NotifRefresh(ctx,nid,&valid)) {
					do_refresh = now + (valid - now)/2;
					fprintf(stderr,"notification is valid until: %s (%ld)\n",TimeToStr(valid), valid);
					fprintf(stderr,"next refresh %s (%ld)\n", TimeToStr(do_refresh),do_refresh);
				}
				else {
					char	*et,*ed;
					edg_wll_Error(ctx,&et,&ed);
					do_refresh = now + (valid - now)/2;
					fprintf(stderr,"warning: edg_wll_NotifRefresh failed (%s, %s)\n"
							"next refresh %s (%ld)\n",
							et,ed,TimeToStr(do_refresh),do_refresh);
				}
			}
/* original example */
#if 0
			printf("\nnotification ID: %s\n", edg_wll_NotifIdUnparse(recv_nid)); 
			
			if (stat.state != EDG_WLL_JOB_UNDEF) {
				char	*jobid_s;

				jobid_s = edg_wlc_JobIdUnparse(stat.jobId);
				printf("Jobid:\t%s\nStatus:\t%s\n", 
						jobid_s,
						edg_wll_StatToString(stat.state));
				edg_wll_FreeStatus(&stat);
				free(jobid_s);
				stat.state = EDG_WLL_JOB_UNDEF;
			}
#endif
			
			if (recv_nid) {
				edg_wll_NotifIdFree(recv_nid);
				recv_nid = NULL;
			}
		} while (1); // till timeout....
		return 0;

receive_err:		
		if (stat.state != EDG_WLL_JOB_UNDEF) edg_wll_FreeStatus(&stat);
		if (nid) edg_wll_NotifIdFree(nid);
		edg_wll_NotifCloseFd(ctx);
		edg_wll_NotifClosePool(ctx);

		if (edg_wll_Error(ctx,&errt,&errd))
			fprintf(stderr, "%s: %s (%s)\n", me, errt, errd);

		return EX_IOERR;
	}
	else if ( !strcmp(argv[1], "change") )
	{
		edg_wlc_JobId		jid;
		edg_wll_NotifId		nid;

		if ( (argc < 3) || edg_wll_NotifIdParse(argv[2], &nid) )
		{
			printf("Notification ID parameter not set propperly!\n");
			usage("bind");
			return 1;
		}
		if ( (argc < 4) || edg_wlc_JobIdParse(argv[3], &jid) )
		{
			fprintf(stderr,"Job ID parameter not set propperly!\n");
			usage("change");
			goto cleanup;
		}

		conditions = (edg_wll_QueryRec **)calloc(2,sizeof(edg_wll_QueryRec *));
	
		conditions[0] = (edg_wll_QueryRec *)calloc(2,sizeof(edg_wll_QueryRec));
		conditions[0][0].attr = EDG_WLL_QUERY_ATTR_JOBID;
		conditions[0][0].op = EDG_WLL_QUERY_OP_EQUAL;
		conditions[0][0].value.j = jid;

		conditions[1] = NULL;

		/*conditions[1] = (edg_wll_QueryRec *)calloc(3, sizeof(edg_wll_QueryRec));
		conditions[1][0].attr = EDG_WLL_QUERY_ATTR_STATUS;
		conditions[1][0].op = EDG_WLL_QUERY_OP_EQUAL;
		conditions[1][0].value.i = EDG_WLL_JOB_DONE;

		conditions[1][1].attr = EDG_WLL_QUERY_ATTR_STATUS;
		conditions[1][1].op = EDG_WLL_QUERY_OP_EQUAL;
		conditions[1][1].value.i = EDG_WLL_JOB_RUNNING;*/

		edg_wll_NotifChange(ctx, nid,
						(edg_wll_QueryRec const * const *) conditions,
						EDG_WLL_NOTIF_REPLACE);
		edg_wlc_JobIdFree(jid);
		edg_wll_NotifIdFree(nid);
	}
	else if ( !strcmp(argv[1], "refresh") )
	{
		edg_wll_NotifId		nid;
		int			c;

		while ((c = getopt(argc-1,argv+1,"t:")) > 0) switch (c) {
			case 't':
				valid = time(NULL) + atol(optarg); break;
			default:
				usage("refresh"); return EX_USAGE;
		}

		if ( (optind+1 == argc) || edg_wll_NotifIdParse(argv[optind+1], &nid) )
		{
			fprintf(stderr,"Notification ID parameter not set propperly!\n\n");
			usage("refresh");
			return EX_USAGE;
		}

		if ( !edg_wll_NotifRefresh(ctx, nid, &valid) )
			printf("valid until: %s (%ld)\n", TimeToStr(valid), valid);
		edg_wll_NotifIdFree(nid);
	}
	else if ( !strcmp(argv[1], "drop") )
	{
		edg_wll_NotifId		nid;

		if ( (argc < 3) || edg_wll_NotifIdParse(argv[2], &nid) )
		{
			fprintf(stderr,"Notification ID parameter not set propperly!\n");
			usage("drop");
			return EX_USAGE;
		}
		edg_wll_NotifDrop(ctx, nid);
		edg_wll_NotifIdFree(nid);
	}
	else {
		usage(NULL);
		return EX_USAGE;
	}
	
cleanup:
	
	if ( conditions )
	{
		/*
		for ( i = 0; conditions[i][0].attr; i++ )
			free(conditions[1]);
		*/
		free(conditions);
	}

	int retval;
	if (retval = edg_wll_Error(ctx,&errt,&errd)) 
		fprintf(stderr, "%s: %s (%s)\n", me, errt, errd);

	edg_wll_NotifCloseFd(ctx);
	edg_wll_FreeContext(ctx);
	edg_wll_poolFree();

	return retval;
}
Exemple #2
0
void edg_wll_FreeContext(edg_wll_Context ctx)
{
	struct timeval close_timeout = {0, 50000};
	int	i;

	if (!ctx) return;
#ifdef CTXTRACE
{
	int	trc = open(CTXTRACE,O_WRONLY|O_CREAT,0644);
	char	buf[200];
	sprintf(buf,"%p free\n",ctx);
	lseek(trc,0,SEEK_END);
	write(trc,buf,strlen(buf));
	close(trc);
}
#endif
	if (ctx->errDesc) free(ctx->errDesc);
	if (ctx->connections->connPool) {
#ifdef GLITE_LB_THREADED
		int i;

                /* Since the introduction of a shared connection pool, the pool
                   cannot be freed here. We only need to unlock connections that
                   may have been locked using this context. */

                #ifdef EDG_WLL_CONNPOOL_DEBUG
                     printf("Running edg_wll_FreeContext - checking for connections locked by the current context.\n");
		#endif

                edg_wll_poolLock();

		for (i=0; i<ctx->connections->poolSize; i++) {
	
                        if (ctx->connections->locked_by[i]==ctx) {
                                #ifdef EDG_WLL_CONNPOOL_DEBUG
                                    printf("Unlocking connection No. %d...",i);
                                #endif
				edg_wll_connectionUnlock(ctx, i);

			}
		}

                edg_wll_poolUnlock();
#endif

/*		
		for (i=0; i<ctx->connections->poolSize; i++) {
			if (ctx->connections->connPool[i].peerName) free(ctx->connections->connPool[i].peerName);
			edg_wll_gss_close(&ctx->connections->connPool[i].gss,&close_timeout);
			if (ctx->connections->connPool[i].gsiCred)
				edg_wll_gss_release_cred(&ctx->connections->connPool[i].gsiCred, NULL);
			if (ctx->connections->connPool[i].buf) free(ctx->connections->connPool[i].buf);
		}	
		free(ctx->connections->connPool);*/
	}
 	if (ctx->connNotif) {
		for (i=0; i<ctx->connNotif->poolSize; i++) {
	 		if (ctx->connNotif->connPool[i].peerName) free(ctx->connNotif->connPool[i].peerName);
 			edg_wll_gss_close(&ctx->connNotif->connPool[i].gss,&close_timeout);
 			if (ctx->connNotif->connPool[i].gsiCred)
 				edg_wll_gss_release_cred(&ctx->connNotif->connPool[i].gsiCred, NULL);
	 		if (ctx->connNotif->connPool[i].buf) free(ctx->connNotif->connPool[i].buf);
	 		if (ctx->connNotif->connPool[i].bufOut) free(ctx->connNotif->connPool[i].bufOut);
		}
 		free(ctx->connNotif->connPool);
		free(ctx->connNotif);
 	}
	if ( ctx->connProxy ) {
		if ( ctx->connProxy->buf ) free(ctx->connProxy->buf);
		edg_wll_plain_close(&ctx->connProxy->conn);
		free(ctx->connProxy);
	}
	if (ctx->notifSock >=0) close(ctx->notifSock);
	if (ctx->srvName) free(ctx->srvName);
	if (ctx->peerName) free(ctx->peerName);
	if (ctx->vomsGroups.len) free_voms_groups(&ctx->vomsGroups);
	if (ctx->dumpStorage) free(ctx->dumpStorage);
	if (ctx->purgeStorage) free(ctx->purgeStorage);
	if (ctx->fqans) {
		char **f;
		for (f = ctx->fqans; f && *f; f++)
			free(*f);
		free(ctx->fqans);
		ctx->fqans = NULL;
	}
	if (ctx->authz_policy.actions_num) {
		for (i = 0; i < ctx->authz_policy.actions_num; i++) {
			int j, k;
			struct _edg_wll_authz_rule *r;
			for (j = 0; j < ctx->authz_policy.actions[i].rules_num; j++) {
				r = &ctx->authz_policy.actions[i].rules[j];
				for (k = 0; r->attrs && k < r->attrs_num; k++) {
					free(r->attrs[k].value);
				}
				free(r->attrs);
			}
			free(ctx->authz_policy.actions[i].rules);
		}
		free (ctx->authz_policy.actions);
	}
	if (ctx->id_mapping.num) {
		for (i = 0; i < ctx->id_mapping.num; i++) {
			free(ctx->id_mapping.rules[i].a);
			free(ctx->id_mapping.rules[i].b);
		}
		free(ctx->id_mapping.rules);
		ctx->id_mapping.num = 0;
	}
	
	if (ctx->jpreg_dir) free(ctx->jpreg_dir);
	if (ctx->serverIdentity) free(ctx->serverIdentity);
	if (ctx->msg_prefixes) {
		char **fm;
		for (fm = ctx->msg_prefixes; fm && *fm; fm++)
			free(*fm);
		free(ctx->msg_prefixes);
		ctx->msg_prefixes = NULL;
	}
	if (ctx->msg_brokers) {
		char **fm;
		for (fm = ctx->msg_brokers; fm && *fm; fm++)
			free(*fm);
		free(ctx->msg_brokers);
		ctx->msg_brokers = NULL;
	}
	
	if (ctx->authz_policy_file) free(ctx->authz_policy_file);

	if (ctx->html_header_file) free(ctx->html_header_file);

	edg_wll_FreeParams(ctx);

	free(ctx);
}
Exemple #3
0
/*
 *----------------------------------------------------------------------
 *
 * Main -
 *
 *----------------------------------------------------------------------
 */
int main(int argc, char *argv[])
{
   int ret;
   int childpid;
   int opt;
   FILE *pidf;
   sigset_t mask;

   int listener_fd;
   int client_fd;
   struct sockaddr_storage client_addr;
   socklen_t client_addr_len;

   time_t	cert_mtime = 0;
   edg_wll_GssStatus	gss_stat;
   edg_wll_GssCred	cred = NULL;


   setlinebuf(stdout);
   setlinebuf(stderr);

   /* welcome */
   fprintf(stdout,"\
This is LocalLogger, part of Workload Management System in EU DataGrid & EGEE.\n");

   /* get arguments */
   while ((opt = getopt_long(argc,argv,
	"h"  /* help */
	"V"  /* version */
	"d"  /* debug */
	"p:" /* port */
	"f:" /* file prefix */
	"c:" /* certificate */
	"k:" /* key */
	"C:" /* CA dir */
	"s:" /* socket */
	"i:" /* pidfile */
	"x"  /* noAuth */
	"y"  /* noIPC */
	"z",  /* noParse */
	long_options, (int *) 0)) != EOF) {

	switch (opt) {
		case 'V': fprintf(stdout,"%s:\t%s\n",argv[0],rcsid); exit(0);
		case 'd': debug = 1; break;
		case 'p': port = atoi(optarg); break;
		case 'f': prefix = optarg; break;
		case 'c': cert_file = optarg; break;
		case 'k': key_file = optarg; break;
		case 'C': CAcert_dir = optarg; break;
		case 's': socket_path = optarg; break;
		case 'i': pidfile = optarg; break;
		case 'x': noAuth = 1; break;
		case 'y': noIPC = 1; break;
		case 'z': noParse = 1; break;
		case 'h':
		default:
			usage(argv[0]); exit(0);
	}
   }
   if (glite_common_log_init()) {
	fprintf(stderr,"glite_common_log_init() failed, exiting.");
	exit(1);
   }
   glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Initializing...\n");

   /* check noParse */
   if (noParse) {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Parse messages for correctness... [no]\n");
   } else {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Parse messages for correctness... [yes]\n");
   }

   /* check noIPC */
   if (noIPC) {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Send messages also to inter-logger... [no]\n");
   } else {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Send messages also to inter-logger... [yes]\n");
   }

   /* check prefix correctness */
   if (strlen(prefix) > FILENAME_MAX - 34) {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_FATAL,"Too long prefix (%s) for file names, would not be able to write to log files. Exiting.\n",prefix);
	exit(1);
   }
   /* TODO: check for write permisions */
   glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Messages will be stored with the filename prefix \"%s\".\n",prefix);

   if (CAcert_dir)
	setenv("X509_CERT_DIR", CAcert_dir, 1);

#ifdef LB_PERF
   glite_wll_perftest_init(NULL, NULL, NULL, NULL, 0);
#endif
 
   /* daemonize */
   if (debug) {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Running as daemon... [no]\n");
   } else {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Running as daemon... [yes]\n");
	if (daemon(0,0) < 0) {
		glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_FATAL,"Failed to run as daemon. Exiting.\n");
		glite_common_log_SYS_ERROR("daemon");
		exit(1);
	}
   }

   edg_wll_gss_initialize();
   ret = edg_wll_gss_watch_creds(cert_file,&cert_mtime);
   if (ret < 0)
   	glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"edg_wll_gss_watch_creds failed, unable to access credentials\n");
   /* XXX DK: support noAuth */
   ret = edg_wll_gss_acquire_cred(cert_file, key_file, GSS_C_ACCEPT, &cred, &gss_stat);
   if (ret) {
	/* XXX DK: call edg_wll_gss_get_error() */
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_FATAL,"Failed to get GSI credentials. Exiting.\n");
	exit(1);
   }

   if (cred->name!=NULL) {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Server running with certificate: %s\n",cred->name);
   } else if (noAuth) {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Server running without certificate\n");
   }

   /* initialize signal handling */
#if 1
   if(edg_wll_gss_set_signal_handler(SIGUSR1, handle_signal) < 0) { perror("signal"); exit(1); }
   if(edg_wll_gss_set_signal_handler(SIGUSR2, handle_signal) < 0) { perror("signal"); exit(1); }
   if(edg_wll_gss_set_signal_handler(SIGPIPE, handle_signal) < 0) { perror("signal"); exit(1); }
   if(edg_wll_gss_set_signal_handler(SIGHUP, handle_signal) < 0) { perror("signal"); exit(1); }
   if(edg_wll_gss_set_signal_handler(SIGINT, handle_signal) < 0) { perror("signal"); exit(1); }
   if(edg_wll_gss_set_signal_handler(SIGQUIT, handle_signal) < 0) { perror("signal"); exit(1); }
   if(edg_wll_gss_set_signal_handler(SIGTERM, handle_signal) < 0) { perror("signal"); exit(1); }
   if(edg_wll_gss_set_signal_handler(SIGCHLD, handle_signal) < 0) { perror("signal"); exit(1); }
#else
   if (mysignal(SIGUSR1, handle_signal) == SIG_ERR) { perror("signal"); exit(1); }
   if (mysignal(SIGUSR2, handle_signal) == SIG_ERR) { perror("signal"); exit(1); }
   if (mysignal(SIGPIPE, handle_signal) == SIG_ERR) { perror("signal"); exit(1); }
   if (mysignal(SIGHUP,  handle_signal) == SIG_ERR) { perror("signal"); exit(1); }
   if (mysignal(SIGINT,  handle_signal) == SIG_ERR) { perror("signal"); exit(1); }
   if (mysignal(SIGQUIT, handle_signal) == SIG_ERR) { perror("signal"); exit(1); }
   if (mysignal(SIGTERM, handle_signal) == SIG_ERR) { perror("signal"); exit(1); }
   if (mysignal(SIGCHLD, handle_signal) == SIG_ERR) { perror("signal"); exit(1); }

   sigemptyset(&mask);
   sigaddset(&mask, SIGUSR1);
   sigaddset(&mask, SIGUSR2);
   sigaddset(&mask, SIGPIPE);
   sigaddset(&mask, SIGHUP);
   sigaddset(&mask, SIGINT);
   sigaddset(&mask, SIGQUIT);
   sigaddset(&mask, SIGTERM);
   sigaddset(&mask, SIGCHLD);
   sigprocmask(SIG_UNBLOCK, &mask, NULL);
#endif

   /* do listen */
   glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Listening on port %d\n",port);
   listener_fd = do_listen(port);
   if (listener_fd == -1) {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_FATAL,"Failed to listen on port %d\n",port);
	edg_wll_gss_release_cred(&cred, NULL);
	exit(-1);
   } else {
	glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_DEBUG,"Listener's socket descriptor is '%d'\n",listener_fd);
   }

   client_addr_len = sizeof(client_addr);
   bzero((char *) &client_addr, client_addr_len);

/* just try it before deamonizing to be able to complain aloud */
  if (!(pidf = fopen(pidfile,"w"))) {
        perror(pidfile);
        exit(-1);
  }
  fclose(pidf);


  pidf = fopen(pidfile,"w"); assert(pidf); /* XXX */
  fprintf(pidf,"%d\n",getpid());
  fclose(pidf);

  umask(S_IRWXG | S_IRWXO);

   /*
    * Main loop
    */
   while (1) {
        int opt,my_errno;
	fd_set fds;
	struct timeval tv;


	glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_INFO,"Accepting incomming connections...\n");
	client_fd = 0;
	while(0 == client_fd) {
		FD_ZERO(&fds);
		FD_SET(listener_fd, &fds);
		tv.tv_sec = 2;
		tv.tv_usec = 0;

		client_fd = select(listener_fd + 1, &fds, NULL, NULL, &tv);
		do_handle_signal();
		if(client_fd < 0) {
			glite_common_log_SYS_ERROR("select");
			client_fd = 0;
		}
	}
	client_fd = accept(listener_fd, (struct sockaddr *) &client_addr,
			&client_addr_len);
	my_errno = errno;
	if (client_fd < 0) {
		if (my_errno == EINTR) continue;
		close(listener_fd);
		glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_FATAL,"Failed to accept incomming connections\n");
		glite_common_log_SYS_ERROR("accept");
		edg_wll_gss_release_cred(&cred, NULL);
		exit(-1);
	} else {
		glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_DEBUG,"Incomming connection on socket '%d'\n",client_fd);
	}

	opt = 0;
	if (setsockopt(client_fd,IPPROTO_TCP,TCP_CORK,(const void *) &opt,sizeof opt)) {
		glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_WARN,"Can't reset TCP_CORK\n");
	}
	opt = 1;
	if (setsockopt(client_fd,IPPROTO_TCP,TCP_NODELAY,(const void *) &opt,sizeof opt)) {
		glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_WARN,"Can't set TCP_NODELAY\n");
	}

	switch (edg_wll_gss_watch_creds(cert_file,&cert_mtime)) {
	edg_wll_GssCred newcred;
	case 0: break;
	case 1:
		ret = edg_wll_gss_acquire_cred(cert_file,key_file, GSS_C_ACCEPT, &newcred,&gss_stat);
		if (ret) {
			glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"Reloading credentials failed, continue with older\n");
		} else {
			glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_DEBUG,"Reloading credentials succeeded\n");
			edg_wll_gss_release_cred(&cred, NULL);
			cred = newcred;
		}
		break;
	case -1:
		glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"edg_wll_gss_watch_creds failed, unable to access credentials\n");
		break;
	}

	/* FORK - change next line if fork() is not needed (for debugging for example) */
#if 1
	if ((childpid = fork()) < 0) {
		glite_common_log_SYS_ERROR("fork");
		if (client_fd) close(client_fd);
	}
	if (childpid == 0) {
		ret = doit(client_fd,cred,prefix,noIPC,noParse);
		if (client_fd) close(client_fd);
		glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_DEBUG,"Exiting.\n");
		exit(0);
	}
	if (childpid > 0) {
		glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_DEBUG,"Forked a new child with PID %d\n",childpid);
		if (client_fd) close(client_fd);
	}
#else
	ret = doit(client_fd,cred,prefix,noIPC,noParse);
	if (client_fd) close(client_fd);

#endif
    } /* while */

	if (listener_fd) close(listener_fd);
	edg_wll_gss_release_cred(&cred, NULL);
	exit(ret);
}
Exemple #4
0
/*
 *  Returns: 0 - not connected, timeout set, 1 - OK
 */
int 
event_queue_connect(struct event_queue *eq, struct queue_thread *me)
{
  int ret;
  struct timeval tv;
  edg_wll_GssStatus gss_stat;
  cred_handle_t *local_cred_handle;

  assert(eq != NULL);
  assert(me != NULL);

#ifdef LB_PERF
  if(!nosend) {
#endif

  if(me->gss.context == NULL) {

    tv.tv_sec = TIMEOUT;
    tv.tv_usec = 0;

    /* get pointer to the credentials */
    if(pthread_mutex_lock(&cred_handle_lock) < 0)
	    abort();
    local_cred_handle = cred_handle;
    local_cred_handle->counter++;
    if(pthread_mutex_unlock(&cred_handle_lock) < 0)
	    abort();
    
    glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, 
		     "    trying to connect to %s:%d", 
		     eq->dest_name, eq->dest_port);
#if defined(IL_NOTIFICATIONS)
    ret = edg_wll_gss_connect_name(local_cred_handle->creds, eq->dest_name, eq->dest_port, eq->owner, /* mech */NULL, &tv, &me->gss, &gss_stat);
#else
    ret = edg_wll_gss_connect(local_cred_handle->creds, eq->dest_name, eq->dest_port, &tv, &me->gss, &gss_stat);
#endif
    if(pthread_mutex_lock(&cred_handle_lock) < 0)
	    abort();
    /* check if we need to release the credentials */
    --local_cred_handle->counter;
    if(local_cred_handle != cred_handle && local_cred_handle->counter == 0) {
	    edg_wll_gss_release_cred(&local_cred_handle->creds, NULL);
	    free(local_cred_handle);
	    glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, "   freed credentials, not used anymore");
    }
    if(pthread_mutex_unlock(&cred_handle_lock) < 0) 
	    abort();

    if(ret < 0) {
      char *gss_err = NULL;

      if (ret == EDG_WLL_GSS_ERROR_GSS)
	 edg_wll_gss_get_error(&gss_stat, "event_queue_connect: edg_wll_gss_connect", &gss_err);
      set_error(IL_DGGSS, ret,
	        (ret == EDG_WLL_GSS_ERROR_GSS) ? gss_err : "event_queue_connect: edg_wll_gss_connect");
      if (gss_err) free(gss_err);
      me->gss.context = NULL;
      me->timeout = TIMEOUT;
      return(0);
    }
    me->first_event_sent = 0;
  }

#ifdef LB_PERF
  }
#endif

  eq->last_connected = time(NULL);
  return(1);
}