File: protocol.c

package info (click to toggle)
youbin 2.13-12
  • links: PTS
  • area: main
  • in suites: potato
  • size: 556 kB
  • ctags: 416
  • sloc: ansic: 2,830; makefile: 60; sh: 24
file content (160 lines) | stat: -rw-r--r-- 4,883 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
 * Program:     $RCSfile: protocol.c,v $  $Revision: 4.5 $
 *
 * Purpose:     Protocol routines of internet "youbin" service.
 *
 * Author:      K.Agusa     agusa@nuie.nagoya-u.ac.jp
 *              S.Yamamoto  yamamoto@nuie.nagoya-u.ac.jp
 *
 * Date:        1993/07/24
 * Modified:    $Date: 1995/01/07 10:35:34 $
 *
 * Copyright:   K.Agusa and S.Yamamoto  1993 - 94
 *
 * The X Consortium, and any party obtaining a copy of these files from
 * the X Consortium, directly or indirectly, is granted, free of charge,
 * a full and unrestricted irrevocable, world-wide, paid up, royalty-free,
 * nonexclusive right and license to deal in this software and documentation
 * files (the "Software"), including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons who receive copies from any such
 * party to do so. This license includes without limitation a license to do
 * the foregoing actions under any patents of the party supplying this
 * software to the X Consortium.
 */

#ifndef lint
static char rcsid[] =
    "$Id: protocol.c,v 4.5 1995/01/07 10:35:34 yamamoto Exp $";
#endif /* not lint */

#include <sys/types.h>          /* Must be included before "sys/socket.h". */
#include <sys/socket.h>         /* For struct sockaddr. */ 
#include <netinet/in.h>         /* For struct sockaddr_in. */
#include <arpa/inet.h>          /* For inet_ntoa(). */ 
#include <netdb.h>              /* For gethostbyname() and gethostbyaddr(). */
#include <stdio.h>

#include "youbin.h"
#include "server.h"

void
do_Wakeup(mess, endp)
char    *mess, *endp;
{
    /* 
     * mess := "<user name> <protocol version>"
     *       | "<user name> <protocol version> <options>"
     */
    char        *cp;                        /* Pointer to <protocol version>. */
    char        *cp1;                       /* Pointer to <option>. */
    StateP      id;                         /* User ID. */

    if ((cp = strchr(mess, ' ')) == NULL) {
        strcpy(NAK_reason, "Invalid version");
        send_packet(NAK_buff, CA_ADDR);
        return;
    }
    *cp++ = '\0';                           /* Trim protocol version. */
    if ((cp1 = strchr(cp, ' ')) == NULL) {
        cp1 = endp;                         /* No options. */
    } else {
        *cp1++ = '\0';                      /* Trim options. */
    }
    
    if (strcmp(cp, PROTOCOL_VERSION) != 0) {    /* Check protocol version. */
        strcpy(NAK_reason, "Invalid version");
        send_packet(NAK_buff, CA_ADDR);
        return;
    }

    if ((id = make_user(mess, cp1, NAK_reason)) != NULL) {
        if (debug_mode || trace_mode) {
            char            buff_log[LOG_LEN];  /* Only for log. */
            struct hostent  *hp;

            if ((hp = gethostbyaddr((char *)&ca.sin_addr,
                        sizeof(ca.sin_addr), ca.sin_family)) == NULL) {
                sys_error_log("gethostbyaddr");
            } 
            sprintf(buff_log, "Wakeup packet: %s [%ld]: host = %s, port = %d\n",
                    mess, (long)id,
                    ((hp != NULL) ? hp->h_name : inet_ntoa(ca.sin_addr)),
                    ntohs(ca.sin_port));
            debug_log("    %s", buff_log);
            trace(buff_log);
        }
        send_Registerd(id);
        send_Status(id);
    } else {                            /* Invalid user. */
        send_packet(NAK_buff, CA_ADDR); /* Send to global ca. */
    }
}

void
do_Update(mess)
char    *mess;
{
    /*
     * Value of mess is one of below:
     * (1) packet = "U <user name>", mess = "<user name>"
     * (2) packet = "U /<user id>", mess = "/<user id>"
     * (3) packet = "<user name>@<mailbox offset>", mess = "<user name>".
     */
    UserP   up;
    StateP  sp;
    
    if (*mess == '/') {         /* Case (2). */
        if ((sp = get_id(mess + 1)) != NULL) {
            up = sp->parent;
        } else {
            up = NULL;
        }
    } else {                    /* Case (1) or (3). */
        up = find_user(mess);
    }
    if (up != NULL) {
        check_spool(up);
        for (sp = up->stat; sp != NULL; sp = sp->next) {
            send_Status(sp);
        }
    }
}

void
send_Registerd(sp)
StateP  sp;
{
    char    buff[MESS_LEN + 1];

    sprintf(buff, "R %ld %d", (long)sp, CLIENT_TIME_OUT); 
    send_packet(buff, sp);
}

void
send_Status(sp)
StateP  sp;
{
    UserP   up;
    char    buff[MESS_LEN + 1];
    
    up = sp->parent;
    sprintf(buff, "S %d %d", up->size, up->time);
    send_packet(buff, sp);
}

void
send_Quit(reason)
char    *reason;
{
    StateP  sp;
    UserP   up;
    char    buff[MESS_LEN + 1];
    
    sprintf(buff, "Q %s", reason);
    for (up = UserList.next; up != NULL; up = up->next) {
        for (sp = up->stat; sp != NULL; sp = sp->next) {
            send_packet(buff, sp);
        }
    }
}