169 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* This file is part of the Project Athena Zephyr Notification System.
 | |
|  * It contains source for asynchronous location functions.
 | |
|  *
 | |
|  *	Created by:	Marc Horowitz
 | |
|  *
 | |
|  *	$Id$
 | |
|  *
 | |
|  *	Copyright (c) 1990,1991 by the Massachusetts Institute of Technology.
 | |
|  *	For copying and distribution information, see the file
 | |
|  *	"mit-copyright.h". 
 | |
|  */
 | |
| 
 | |
| #include <internal.h>
 | |
| 
 | |
| #ifndef lint
 | |
| static const char rcsid_ZAsyncLocate_c[] = "$Id$";
 | |
| #endif
 | |
| 
 | |
| Code_t
 | |
| ZRequestLocations(char *user,
 | |
| 		  register ZAsyncLocateData_t *zald,
 | |
| 		  ZNotice_Kind_t kind,                /* UNSAFE, UNACKED, or ACKED */
 | |
| 		  Z_AuthProc auth)
 | |
| {
 | |
|     int retval;
 | |
|     ZNotice_t notice;
 | |
| 
 | |
|     if (ZGetFD() < 0)
 | |
| 	if ((retval = ZOpenPort((u_short *)0)) != ZERR_NONE)
 | |
| 	    return (retval);
 | |
| 
 | |
|     (void) memset((char *)¬ice, 0, sizeof(notice));
 | |
|     notice.z_kind = kind;
 | |
|     notice.z_port = __Zephyr_port;
 | |
|     notice.z_class = LOCATE_CLASS;
 | |
|     notice.z_class_inst = user;
 | |
|     notice.z_opcode = LOCATE_LOCATE;
 | |
|     notice.z_sender = 0;
 | |
|     notice.z_recipient = "";
 | |
|     notice.z_default_format = "";
 | |
|     notice.z_message_len = 0;
 | |
| 
 | |
|     if ((retval = ZSendNotice(¬ice, auth)) != ZERR_NONE)
 | |
| 	return(retval);
 | |
| 
 | |
|     if ((zald->user = (char *) malloc(strlen(user)+1)) == NULL) {
 | |
| 	return(ENOMEM);
 | |
|     }
 | |
|     if ((zald->version = (char *) malloc(strlen(notice.z_version)+1)) == NULL) {
 | |
| 	free(zald->user);
 | |
| 	return(ENOMEM);
 | |
|     }
 | |
|     zald->uid = notice.z_multiuid;
 | |
|     strcpy(zald->user,user);
 | |
|     strcpy(zald->version,notice.z_version);
 | |
| 
 | |
|     return(ZERR_NONE);
 | |
| }
 | |
| 
 | |
| Code_t
 | |
| ZParseLocations(register ZNotice_t *notice,
 | |
| 		register ZAsyncLocateData_t *zald,
 | |
| 		int *nlocs,
 | |
| 		char **user)
 | |
| {
 | |
|     char *ptr, *end;
 | |
|     int i;
 | |
| 
 | |
|     ZFlushLocations();    /* This never fails (this function is part of the
 | |
| 			     library, so it is allowed to know this). */
 | |
| 
 | |
|     /* non-matching protocol version numbers means the
 | |
|        server is probably an older version--must punt */
 | |
| 
 | |
|     if (zald && strcmp(notice->z_version, zald->version))
 | |
|       return(ZERR_VERS);
 | |
| 
 | |
|     if (notice->z_kind == SERVNAK)
 | |
|       return (ZERR_SERVNAK);
 | |
| 
 | |
|     /* flag ACKs as special */
 | |
|     if (notice->z_kind == SERVACK &&
 | |
| 	!strcmp(notice->z_opcode, LOCATE_LOCATE)) {
 | |
| 	*nlocs = -1;
 | |
| 	return(ZERR_NONE);
 | |
|     }
 | |
| 
 | |
|     if (notice->z_kind != ACKED)
 | |
| 	return (ZERR_INTERNAL);
 | |
| 
 | |
|     end = notice->z_message+notice->z_message_len;
 | |
| 
 | |
|     __locate_num = 0;
 | |
| 	
 | |
|     for (ptr=notice->z_message;ptr<end;ptr++)
 | |
|       if (!*ptr)
 | |
| 	__locate_num++;
 | |
| 
 | |
|     __locate_num /= 3;
 | |
| 
 | |
|     if (__locate_num)
 | |
|       {
 | |
|       __locate_list = (ZLocations_t *)malloc((unsigned)__locate_num*
 | |
| 					     sizeof(ZLocations_t));
 | |
|       if (!__locate_list)
 | |
| 	return (ENOMEM);
 | |
|     } else {
 | |
|       __locate_list = 0;
 | |
|     }
 | |
| 
 | |
|     for (ptr=notice->z_message, i=0; i<__locate_num; i++) {
 | |
|        unsigned int len;
 | |
| 
 | |
|        len = strlen (ptr) + 1;
 | |
|        __locate_list[i].host = (char *) malloc(len);
 | |
|        if (!__locate_list[i].host)
 | |
| 	  return (ENOMEM);
 | |
|        (void) strcpy(__locate_list[i].host, ptr);
 | |
|        ptr += len;
 | |
| 
 | |
|        len = strlen (ptr) + 1;
 | |
|        __locate_list[i].time = (char *) malloc(len);
 | |
|        if (!__locate_list[i].time)
 | |
| 	  return (ENOMEM);
 | |
|        (void) strcpy(__locate_list[i].time, ptr);
 | |
|        ptr += len;
 | |
| 
 | |
|        len = strlen (ptr) + 1;
 | |
|        __locate_list[i].tty = (char *) malloc(len);
 | |
|        if (!__locate_list[i].tty)
 | |
| 	  return (ENOMEM);
 | |
|        (void) strcpy(__locate_list[i].tty, ptr);
 | |
|        ptr += len;
 | |
|     }
 | |
| 
 | |
|     __locate_next = 0;
 | |
|     *nlocs = __locate_num;
 | |
|     if (user) {
 | |
| 	if (zald) {
 | |
| 	    if ((*user = (char *) malloc(strlen(zald->user)+1)) == NULL)
 | |
| 		return(ENOMEM);
 | |
| 	    strcpy(*user,zald->user);
 | |
| 	} else {
 | |
| 	    if ((*user = (char *) malloc(strlen(notice->z_class_inst)+1)) == NULL)
 | |
| 		return(ENOMEM);
 | |
| 	    strcpy(*user,notice->z_class_inst);
 | |
| 	}
 | |
|     }
 | |
|     return (ZERR_NONE);
 | |
| }
 | |
| 
 | |
| int
 | |
| ZCompareALDPred(ZNotice_t *notice,
 | |
| 		void *zald)
 | |
| {
 | |
|     return(ZCompareUID(&(notice->z_multiuid),
 | |
| 		       &(((ZAsyncLocateData_t *) zald)->uid)));
 | |
| }
 | |
| 
 | |
| void
 | |
| ZFreeALD(register ZAsyncLocateData_t *zald)
 | |
| {
 | |
|    if (!zald) return;
 | |
| 
 | |
|    if (zald->user) free(zald->user);
 | |
|    if (zald->version) free(zald->version);
 | |
|    (void) memset(zald, 0, sizeof(*zald));
 | |
| }
 |