adding zephyr-im master branch
This commit is contained in:
351
zwgc/notice.c
Normal file
351
zwgc/notice.c
Normal file
@ -0,0 +1,351 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It is one of the source files comprising zwgc, the Zephyr WindowGram
|
||||
* client.
|
||||
*
|
||||
* Created by: Marc Horowitz <marc@athena.mit.edu>
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1989 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
#if (!defined(lint) && !defined(SABER))
|
||||
static const char rcsid_notice_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <zephyr/mit-copyright.h>
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* Module containing code to extract a notice's fields: */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
#include <zephyr/zephyr.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "new_memory.h"
|
||||
#include "error.h"
|
||||
#include "variables.h"
|
||||
#include "notice.h"
|
||||
#ifdef CMU_ZWGCPLUS
|
||||
#include <pwd.h>
|
||||
#include "plus.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* int count_nulls(char *data, int length)
|
||||
* Requires: length>=0
|
||||
* Effects: Returns the # of nulls in data[0]..data[length-1]
|
||||
*/
|
||||
|
||||
int
|
||||
count_nulls(char *data,
|
||||
int length)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for (; length; data++, length--)
|
||||
if (!*data)
|
||||
count++;
|
||||
|
||||
return(count);
|
||||
}
|
||||
|
||||
/*
|
||||
* string get_next_field(char **data_p, int *length_p)
|
||||
* Requires: *length_p >= 0
|
||||
* Modifies: *data_p, *length_p
|
||||
* Effects: Treats (*data_p)[0], (*data_p)[1], ... (*data_p)[length-1]
|
||||
* as a series of null-seperated fields. This function
|
||||
* returns a copy of the first field on the heap. This
|
||||
* string must eventually be freed. Also, *data_p is
|
||||
* advanced and *length_p decreased so that another
|
||||
* call to this procedure with the same arguments will
|
||||
* return the second field. The next call will return
|
||||
* the third field, etc. "" is returned if 0 fields
|
||||
* remain. (this is the case when *length_p == 0)
|
||||
*/
|
||||
|
||||
string
|
||||
get_next_field(char **data_p,
|
||||
int *length_p)
|
||||
{
|
||||
char *data = *data_p;
|
||||
int length = *length_p;
|
||||
char *ptr;
|
||||
|
||||
for (ptr=data; length; ptr++, length--)
|
||||
if (!*ptr) {
|
||||
*data_p = ptr+1;
|
||||
*length_p = length-1;
|
||||
return(string_Copy(data));
|
||||
}
|
||||
|
||||
length = *length_p;
|
||||
*data_p = ptr;
|
||||
*length_p = 0;
|
||||
return(string_CreateFromData(data, length));
|
||||
}
|
||||
|
||||
/*
|
||||
* string get_field(char *data, int length, int num)
|
||||
* Requires: length>=0, num>0
|
||||
* Effects: Treats data[0]..data[length-1] as a series of
|
||||
* null-seperated fields. This function returns a copy of
|
||||
* the num'th field (numbered from 1 in this case) on the
|
||||
* heap. This string must eventually be freed. If there
|
||||
* is no num'th field (because num<1 or num># of fields),
|
||||
* "" is returned.
|
||||
*/
|
||||
|
||||
string get_field(char *data,
|
||||
int length,
|
||||
int num)
|
||||
{
|
||||
/*
|
||||
* While num>1 and there are fields left, skip a field & decrement num:
|
||||
*/
|
||||
while (length && num>1) {
|
||||
if (!*data)
|
||||
num--;
|
||||
length--;
|
||||
data++;
|
||||
}
|
||||
|
||||
/*
|
||||
* If any more fields left, the first field is the one we want.
|
||||
* Otherwise, there is no such field as num -- return "".
|
||||
*/
|
||||
if (length)
|
||||
return(get_next_field(&data, &length));
|
||||
else
|
||||
return(string_Copy(""));
|
||||
}
|
||||
|
||||
/*
|
||||
* string convert_nulls_to_newlines(data, length)
|
||||
* Requires: length>=0, malloc never returns NULL
|
||||
* Effects: Takes data[0]..data[length-1], converts all nulls to
|
||||
* newlines ('\n') and returns the result as a null-terminated
|
||||
* string on the heap. The returned string must eventually
|
||||
* be freed.
|
||||
*/
|
||||
|
||||
string
|
||||
convert_nulls_to_newlines(char *data,
|
||||
int length)
|
||||
{
|
||||
char *result, *ptr;
|
||||
char c;
|
||||
|
||||
result = (char *) malloc(length+1);
|
||||
result[length] = '\0';
|
||||
|
||||
for (ptr=result; length; data++, ptr++, length--)
|
||||
*ptr = (c = *data) ? c : '\n';
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Internal Routine:
|
||||
*
|
||||
* string z_kind_to_ascii(ZNotice_Kind_t z_kind)
|
||||
* Effects: Returns an ascii representation for z_kind.
|
||||
* The string returned is on the heap and must be freed
|
||||
* eventually.
|
||||
*/
|
||||
|
||||
static string
|
||||
z_kind_to_ascii(ZNotice_Kind_t z_kind)
|
||||
{
|
||||
string result;
|
||||
|
||||
switch (z_kind) {
|
||||
case UNSAFE:
|
||||
result = "unsafe";
|
||||
break;
|
||||
|
||||
case UNACKED:
|
||||
result = "unacked";
|
||||
break;
|
||||
|
||||
case ACKED:
|
||||
result = "acked";
|
||||
break;
|
||||
|
||||
case HMACK:
|
||||
result = "hmack";
|
||||
break;
|
||||
|
||||
case HMCTL:
|
||||
result = "hmctl";
|
||||
break;
|
||||
|
||||
case SERVACK:
|
||||
result = "servack";
|
||||
break;
|
||||
|
||||
case SERVNAK:
|
||||
result = "servnak";
|
||||
break;
|
||||
|
||||
case CLIENTACK:
|
||||
result = "clientack";
|
||||
break;
|
||||
|
||||
case STAT:
|
||||
result = "stat";
|
||||
break;
|
||||
|
||||
default:
|
||||
result = "<unknown kind>";
|
||||
break;
|
||||
}
|
||||
|
||||
return(string_Copy(result));
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal Routine:
|
||||
*
|
||||
* string z_auth_to_ascii(int z_auth)
|
||||
* Effects: Returns an ascii representation for z_auth.
|
||||
* The string returned is on the heap and must be freed
|
||||
* eventually.
|
||||
*/
|
||||
|
||||
static string
|
||||
z_auth_to_ascii(int z_auth)
|
||||
{
|
||||
string result;
|
||||
|
||||
switch (z_auth) {
|
||||
case ZAUTH_FAILED:
|
||||
result = "forged";
|
||||
break;
|
||||
|
||||
case ZAUTH_NO:
|
||||
result = "no";
|
||||
break;
|
||||
|
||||
case ZAUTH_YES:
|
||||
result = "yes";
|
||||
break;
|
||||
|
||||
default:
|
||||
result = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
return(string_Copy(result));
|
||||
}
|
||||
|
||||
/*
|
||||
* char *decode_notice(ZNotice_t *notice)
|
||||
* Modifies: various description language variables
|
||||
* Effects:
|
||||
*/
|
||||
|
||||
char *
|
||||
decode_notice(ZNotice_t *notice,
|
||||
char *hostname)
|
||||
{
|
||||
char *temp;
|
||||
string when, notyear, year, date_string, time_string;
|
||||
|
||||
/*
|
||||
* Convert useful notice fields to ascii and store away in
|
||||
* description language variables for later use by the
|
||||
* the user's program:
|
||||
*/
|
||||
var_set_variable("zephyr_version", notice->z_version);
|
||||
var_set_variable("class", notice->z_class);
|
||||
var_set_variable("instance", notice->z_class_inst);
|
||||
var_set_variable("opcode", notice->z_opcode);
|
||||
var_set_variable("default", notice->z_default_format);
|
||||
var_set_variable("notice_charset", (char *)ZCharsetToString(notice->z_charset)); /*XXX const*/
|
||||
var_set_variable("recipient",
|
||||
(notice->z_recipient[0] ? notice->z_recipient : "*"));
|
||||
var_set_variable("fullsender", notice->z_sender);
|
||||
var_set_variable_to_number("port", (int)ntohs(notice->z_port));
|
||||
var_set_variable_then_free_value("kind", z_kind_to_ascii(notice->z_kind));
|
||||
var_set_variable_then_free_value("auth", z_auth_to_ascii(notice->z_auth));
|
||||
|
||||
#ifdef CMU_ZWGCPLUS
|
||||
if ((temp=getSelectedText()) != 0)
|
||||
var_set_variable("selection", temp);
|
||||
|
||||
var_set_variable("delete_window", "none");
|
||||
var_set_variable("event_time", "none");
|
||||
var_set_variable("event_name", "event");
|
||||
#endif
|
||||
/*
|
||||
* Set $sender to the name of the notice sender except first strip off the
|
||||
* realm name if it is the local realm:
|
||||
*/
|
||||
if ( (temp=strchr(notice->z_sender,'@')) && string_Eq(temp+1, ZGetRealm()) )
|
||||
var_set_variable_then_free_value("sender",
|
||||
string_CreateFromData(notice->z_sender,
|
||||
temp-notice->z_sender));
|
||||
else
|
||||
var_set_variable("sender", notice->z_sender);
|
||||
#ifdef CMU_ZWGCPLUS
|
||||
if (get_full_names) {
|
||||
struct passwd *pwnam = getpwnam(var_get_variable("sender"));
|
||||
if (pwnam) {
|
||||
temp = string_Copy(pwnam->pw_gecos);
|
||||
var_set_variable_then_free_value("sendername", temp);
|
||||
} else {
|
||||
var_set_variable("sendername", "unknown");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Convert time & date notice was sent to ascii. The $time
|
||||
* has the format "01:03:52" while $date has the format
|
||||
* "Sun Sep 16 1973".
|
||||
*/
|
||||
{
|
||||
/* the fields of struct timeval might not be the right type to pass
|
||||
to ctime, so use a temporary */
|
||||
time_t sec = notice->z_time.tv_sec;
|
||||
when = ctime(&sec);
|
||||
}
|
||||
time_string = string_CreateFromData(when+11,8);
|
||||
var_set_variable_then_free_value("time", time_string);
|
||||
date_string = string_Concat(notyear=string_CreateFromData(when,11),
|
||||
year=string_CreateFromData(when+20,4));
|
||||
var_set_variable_then_free_value("date", date_string);
|
||||
free(notyear);
|
||||
free(year);
|
||||
|
||||
/*
|
||||
* Convert host notice sent from to ascii:
|
||||
*/
|
||||
var_set_variable("fromhost", hostname ? hostname :
|
||||
inet_ntoa(notice->z_sender_addr));
|
||||
|
||||
/*
|
||||
* Set $message to the message field of the notice with nulls changed
|
||||
* to newlines:
|
||||
*/
|
||||
var_set_variable_then_free_value("message",
|
||||
convert_nulls_to_newlines(notice->z_message,
|
||||
notice->z_message_len));
|
||||
|
||||
/*
|
||||
* Decide if its a control notice. If so, return the notice's
|
||||
* opcode. Otherwise, return NULL:
|
||||
*/
|
||||
if ((strcasecmp(notice->z_class, WG_CTL_CLASS)==0) && /* <<<>>> */
|
||||
(strcasecmp(notice->z_class_inst, WG_CTL_USER)==0))
|
||||
return(notice->z_opcode);
|
||||
return(0);
|
||||
}
|
Reference in New Issue
Block a user