⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zephyr.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
					continue;				if (b->account->gc == gc) {					const char *chk;					chk = local_zephyr_normalize(zephyr,b->name);					purple_debug_info("zephyr","chk: %s b->name %s\n",chk,b->name);					/* XXX add real error reporting */					/* doesn't matter if this fails or not; we'll just move on to the next one */					if (use_zeph02(zephyr)) {#ifdef WIN32						int numlocs;						int one=1;						ZLocateUser(chk,&numlocs,ZAUTH);						if (numlocs) {							int i;							for(i=0;i<numlocs;i++) {								ZGetLocations(&locations,&one);								if (nlocs>0) 									purple_prpl_got_user_status(gc->account,b->name,"available",NULL);								else 									purple_prpl_got_user_status(gc->account,b->name,"offline",NULL);							}						}#else						ZRequestLocations(chk, &ald, UNACKED, ZAUTH);						g_free(ald.user);						g_free(ald.version);#endif /* WIN32 */					} else 						if (use_tzc(zephyr)) {							gchar *zlocstr = g_strdup_printf("((tzcfodder . zlocate) \"%s\")\n",chk);							write(zephyr->totzc[ZEPHYR_FD_WRITE],zlocstr,strlen(zlocstr));							g_free(zlocstr);						}				}			}		}	}		return TRUE;}#endif /* WIN32 */static char *get_exposure_level(){	/* XXX add real error reporting */	char *exposure = ZGetVariable("exposure");	if (!exposure)		return EXPOSE_REALMVIS;	if (!g_ascii_strcasecmp(exposure, EXPOSE_NONE))		return EXPOSE_NONE;	if (!g_ascii_strcasecmp(exposure, EXPOSE_OPSTAFF))		return EXPOSE_OPSTAFF;	if (!g_ascii_strcasecmp(exposure, EXPOSE_REALMANN))		return EXPOSE_REALMANN;	if (!g_ascii_strcasecmp(exposure, EXPOSE_NETVIS))		return EXPOSE_NETVIS;	if (!g_ascii_strcasecmp(exposure, EXPOSE_NETANN))		return EXPOSE_NETANN;	return EXPOSE_REALMVIS;}static void strip_comments(char *str){	char *tmp = strchr(str, '#');	if (tmp)		*tmp = '\0';	g_strchug(str);	g_strchomp(str);}static void zephyr_inithosts(zephyr_account *zephyr){	/* XXX This code may not be Win32 clean */	struct hostent *hent;		if (gethostname(zephyr->ourhost, sizeof(zephyr->ourhost)) == -1) {		purple_debug_error("zephyr", "unable to retrieve hostname, %%host%% and %%canon%% will be wrong in subscriptions and have been set to unknown\n");		g_strlcpy(zephyr->ourhost, "unknown", sizeof(zephyr->ourhost));		g_strlcpy(zephyr->ourhostcanon, "unknown", sizeof(zephyr->ourhostcanon));		return;	}		if (!(hent = gethostbyname(zephyr->ourhost))) {		purple_debug_error("zephyr", "unable to resolve hostname, %%canon%% will be wrong in subscriptions.and has been set to the value of %%host%%, %s\n",zephyr->ourhost);		g_strlcpy(zephyr->ourhostcanon, zephyr->ourhost, sizeof(zephyr->ourhostcanon));		return;	}	g_strlcpy(zephyr->ourhostcanon, hent->h_name, sizeof(zephyr->ourhostcanon));	return;}static void process_zsubs(zephyr_account *zephyr){	/* Loads zephyr chats "(subscriptions) from ~/.zephyr.subs, and 	   registers (subscribes to) them on the server */	/* XXX deal with unsubscriptions */	/* XXX deal with punts */	FILE *f;	gchar *fname;	gchar buff[BUFSIZ];	fname = g_strdup_printf("%s/.zephyr.subs", purple_home_dir());	f = g_fopen(fname, "r");	if (f) {		char **triple;		char *recip;		char *z_class;		char *z_instance;		char *z_galaxy = NULL;		while (fgets(buff, BUFSIZ, f)) {			strip_comments(buff);			if (buff[0]) {				triple = g_strsplit(buff, ",", 3);				if (triple[0] && triple[1]) {					char *tmp = g_strdup_printf("%s", zephyr->username);					char *atptr;					z_class = triple[0];					z_instance = triple[1];					if (triple[2] == NULL) {						recip = g_malloc0(1);					} else if (!g_ascii_strcasecmp(triple[2], "%me%")) {						recip = g_strdup_printf("%s", zephyr->username);					} else if (!g_ascii_strcasecmp(triple[2], "*")) {						/* wildcard						 * form of class,instance,* */						recip = g_malloc0(1);					} else if (!g_ascii_strcasecmp(triple[2], tmp)) {						/* form of class,instance,aatharuv@ATHENA.MIT.EDU */						recip = g_strdup(triple[2]);					} else if ((atptr = strchr(triple[2], '@')) != NULL) {						/* form of class,instance,*@ANDREW.CMU.EDU						 * class,instance,@ANDREW.CMU.EDU						 * If realm is local realm, blank recipient, else						 * @REALM-NAME						 */						char *realmat = g_strdup_printf("@%s",zephyr->realm);						if (!g_ascii_strcasecmp(atptr, realmat))							recip = g_malloc0(1);						else							recip = g_strdup(atptr);						g_free(realmat);					} else {						recip = g_strdup(triple[2]);					}					g_free(tmp);					if (!g_ascii_strcasecmp(triple[0],"%host%")) {						z_class = g_strdup(zephyr->ourhost);					} else if (!g_ascii_strcasecmp(triple[0],"%canon%")) {						z_class = g_strdup(zephyr->ourhostcanon);					} else {						z_class = g_strdup(triple[0]);					}										if (!g_ascii_strcasecmp(triple[1],"%host%")) {						z_instance = g_strdup(zephyr->ourhost);					} else if (!g_ascii_strcasecmp(triple[1],"%canon%")) {						z_instance = g_strdup(zephyr->ourhostcanon);					} else {						z_instance = g_strdup(triple[1]);					}					/* There should be some sort of error report listing classes that couldn't be subbed to.					   Not important right now though */					if (zephyr_subscribe_to(zephyr,z_class, z_instance, recip,z_galaxy) != ZERR_NONE) {						purple_debug_error("zephyr", "Couldn't subscribe to %s, %s, %s\n", z_class,z_instance,recip);					}					zephyr->subscrips = g_slist_append(zephyr->subscrips, new_triple(zephyr,z_class,z_instance,recip));					/*					  g_hash_table_destroy(sub_hash_table); */					g_free(z_instance);					g_free(z_class);					g_free(recip);				}				g_strfreev(triple);			}		}		fclose(f);	}}static void process_anyone(PurpleConnection *gc){	FILE *fd;	gchar buff[BUFSIZ], *filename;	PurpleGroup *g;	PurpleBuddy *b;	if (!(g = purple_find_group(_("Anyone")))) {		g = purple_group_new(_("Anyone"));		purple_blist_add_group(g, NULL);	}	filename = g_strconcat(purple_home_dir(), "/.anyone", NULL);	if ((fd = g_fopen(filename, "r")) != NULL) {		while (fgets(buff, BUFSIZ, fd)) {			strip_comments(buff);			if (buff[0]) {				if (!(b = purple_find_buddy(gc->account, buff))) {					char *stripped_user = zephyr_strip_local_realm(gc->proto_data,buff);					purple_debug_info("zephyr","stripped_user %s\n",stripped_user);					if (!(b = purple_find_buddy(gc->account,stripped_user))){						b = purple_buddy_new(gc->account, stripped_user, NULL);						purple_blist_add_buddy(b, NULL, g, NULL);					} 					g_free(stripped_user);				}			}		}		fclose(fd);	}	g_free(filename);}static char* normalize_zephyr_exposure(const char* exposure) {	char *exp2 = g_strstrip(g_ascii_strup(exposure,-1));	if (!exp2)		return EXPOSE_REALMVIS;	if (!g_ascii_strcasecmp(exp2, EXPOSE_NONE))		return EXPOSE_NONE;	if (!g_ascii_strcasecmp(exp2, EXPOSE_OPSTAFF))		return EXPOSE_OPSTAFF;	if (!g_ascii_strcasecmp(exp2, EXPOSE_REALMANN))		return EXPOSE_REALMANN;	if (!g_ascii_strcasecmp(exp2, EXPOSE_NETVIS))		return EXPOSE_NETVIS;	if (!g_ascii_strcasecmp(exp2, EXPOSE_NETANN))		return EXPOSE_NETANN;	return EXPOSE_REALMVIS;}static void zephyr_login(PurpleAccount * account){	PurpleConnection *gc;	zephyr_account *zephyr;	gboolean read_anyone; 	gboolean read_zsubs; 	gchar *exposure;	gc = purple_account_get_connection(account);	read_anyone = purple_account_get_bool(gc->account,"read_anyone",TRUE);	read_zsubs = purple_account_get_bool(gc->account,"read_zsubs",TRUE);	exposure = (gchar *)purple_account_get_string(gc->account, "exposure_level", EXPOSE_REALMVIS); #ifdef WIN32	username = purple_account_get_username(account);#endif	gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC;	gc->proto_data = zephyr=g_new0(zephyr_account,1); 	zephyr->account = account;	/* Make sure that the exposure (visibility) is set to a sane value */	zephyr->exposure=g_strdup(normalize_zephyr_exposure(exposure));	if (purple_account_get_bool(gc->account,"use_tzc",0)) {		zephyr->connection_type = PURPLE_ZEPHYR_TZC;	} else {		zephyr->connection_type = PURPLE_ZEPHYR_KRB4;	}	zephyr->encoding = (char *)purple_account_get_string(gc->account, "encoding", ZEPHYR_FALLBACK_CHARSET);	purple_connection_update_progress(gc, _("Connecting"), 0, 8);	/* XXX z_call_s should actually try to report the com_err determined error */	if (use_tzc(zephyr)) {		pid_t pid;		/*		  purple_connection_error(gc,"tzc not supported yet"); */		if ((pipe(zephyr->totzc) != 0) || (pipe(zephyr->fromtzc) != 0)) {			purple_debug_error("zephyr", "pipe creation failed. killing\n");			exit(-1);		}				pid = fork();				if (pid == -1) {			purple_debug_error("zephyr", "forking failed\n");			exit(-1);		}		if (pid == 0) {			unsigned int i=0;			gboolean found_ps = FALSE;			gchar ** tzc_cmd_array = g_strsplit(purple_account_get_string(gc->account,"tzc_command","/usr/bin/tzc -e %s")," ",0);			if (close(1) == -1) {				purple_debug_error("zephyr", "stdout couldn't be closed. dying\n");				exit(-1);			}			if (dup2(zephyr->fromtzc[1], 1) == -1) {				purple_debug_error("zephyr", "dup2 of stdout failed \n");				exit(-1);			}			if (close(zephyr->fromtzc[1]) == -1) {				purple_debug_error("zephyr", "closing of piped stdout failed\n");				exit(-1);			}			if (close(0) == -1) {				purple_debug_error("zephyr", "stdin couldn't be closed. dying\n");				exit(-1);			}			if (dup2(zephyr->totzc[0], 0) == -1) {				purple_debug_error("zephyr", "dup2 of stdin failed \n");				exit(-1);			}			if (close(zephyr->totzc[0]) == -1) {				purple_debug_error("zephyr", "closing of piped stdin failed\n");				exit(-1);			}			/* tzc_command should really be of the form 			   path/to/tzc -e %s			   or			   ssh username@hostname pathtotzc -e %s 			   -- this should not require a password, and ideally should be kerberized ssh --			   or			   fsh username@hostname pathtotzc -e %s			*/			while(tzc_cmd_array[i] != NULL){				if (!g_ascii_strncasecmp(tzc_cmd_array[i],"%s",2)) {					/*					fprintf(stderr,"replacing %%s with %s\n",zephyr->exposure); */					tzc_cmd_array[i] = g_strdup(zephyr->exposure);					found_ps = TRUE;									} else {					/*					fprintf(stderr,"keeping %s\n",tzc_cmd_array[i]); */				}				i++;			}			if (!found_ps) {				purple_connection_error(gc,"Tzc command needs %s to set the exposure\n");				return;			}			execvp(tzc_cmd_array[0], tzc_cmd_array);		}		else {			fd_set rfds;			int bufsize = 2048;			char *buf = (char *)calloc(bufsize, 1);			char *bufcur = buf;			struct timeval tv;			char *ptr;			int parenlevel=0;			char* tempstr;			int tempstridx;			zephyr->tzc_pid = pid;			/* wait till we have data to read from ssh */			FD_ZERO(&rfds);			FD_SET(zephyr->fromtzc[ZEPHYR_FD_READ], &rfds);			tv.tv_sec = 10;			tv.tv_usec = 0;			purple_debug_info("zephyr", "about to read from tzc\n");			select(zephyr->fromtzc[ZEPHYR_FD_READ] + 1, &rfds, NULL, NULL, NULL);			FD_ZERO(&rfds);			FD_SET(zephyr->fromtzc[ZEPHYR_FD_READ], &rfds);			while (select(zephyr->fromtzc[ZEPHYR_FD_READ] + 1, &rfds, NULL, NULL, &tv)) {				read(zephyr->fromtzc[ZEPHYR_FD_READ], bufcur, 1);				bufcur++;				if ((bufcur - buf) > (bufsize - 1)) {					if ((buf = realloc(buf, bufsize * 2)) == NULL) {						exit(-1);					} else {						bufcur = buf + bufsize;						bufsize *= 2;					}				}				FD_ZERO(&rfds);				FD_SET(zephyr->fromtzc[ZEPHYR_FD_READ], &rfds);				tv.tv_sec = 10;				tv.tv_usec = 0;			}			/*			  fprintf(stderr, "read from tzc\n"); */			*bufcur = '\0';			ptr = buf;			/* ignore all tzcoutput till we've received the first (*/			while (ptr < bufcur && (*ptr !='(')) {				ptr++;			}			if (ptr >=bufcur) {				purple_connection_error(gc,"invalid output by tzc (or bad parsing code)");				free(buf);				return;			}			while(ptr < bufcur) {				if (*ptr == '(') {					parenlevel++; 				}				else if (*ptr == ')') {					parenlevel--;				}				purple_debug_info("zephyr","tzc parenlevel is %d\n",parenlevel);				switch (parenlevel) {				case 0: 					break;				case 1:					/* Search for next beginning (, or for the ending */					ptr++;					while((*ptr != '(') && (*ptr != ')') && (ptr <bufcur)) 						ptr++;					if (ptr >= bufcur) 						purple_debug_error("zephyr","tzc parsing error\n");					break;				case 2: 					/* You are probably at					   (foo . bar ) or (foo . "bar") or (foo . chars) or (foo . numbers) or (foo . () )					   Parse all the data between the first and last f, and move past )					*/					tempstr = g_malloc0(20000);					tempstridx=0;					while(parenlevel >1) {						ptr++;						if (*ptr == '(')							parenlevel++;						if (*ptr == ')')							parenlevel--;						if (parenlevel > 1) {							tempstr[tempstridx++]=*ptr;						} else {							ptr++;						}					}					purple_debug_info("zephyr","tempstr parsed\n");					/* tempstr should now be a tempstridx length string containing all characters 					   from that after the first ( to the one before the last paren ). */					/* We should have the following possible lisp strings but we don't care 					   (tzcspew . start) (version . "something") (pid . number)*/					/* We care about 'zephyrid . "username@REALM.NAME"' and 'exposure . "SOMETHING"' */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -