WhiteBoard Project using C RPC
A Project in Distributed Computing at IIIT-Delhi
server.c
Go to the documentation of this file.
1 
2 /* server.c */
3 
4 #include "wb.h"
5 
6 /*
7  * Generic node in a singly-linked list
8  */
9 typedef struct ListNode {
10  struct ListNode *next;
11 } ListNode;
12 
13 static void insert(ListNode ** hdr, ListNode * p)
14 {
15  if (hdr == NULL)
16  return;
17  p->next = *hdr;
18  *hdr = p;
19 }
20 
21 static void delete(ListNode ** hdr, ListNode * d)
22 {
23  ListNode *p, *q;
24 
25  if (hdr == NULL || *hdr == NULL)
26  return;
27  for (p = (ListNode *) hdr, q = p->next; q; p = q, q = q->next) {
28  if (q == d) {
29  p->next = q->next;
30  free(q);
31  return;
32  }
33  }
34 }
35 
36 typedef struct AClient {
37  struct AClient *next;
38  ClientData clientdata;
39  CLIENT *callback; /* rpc.h */
40 } AClient;
41 
42 typedef struct ABoard {
43  struct ABoard *next;
44  /* name of the board is in clients->clientdata.boardnm */
45  AClient *clients; /* list of clients on one board */
46  ALine *lines; /* list of LINEs that it has */
47 } ABoard;
48 
49 static ABoard *boards = NULL; /* list of boards that server has */
50 
51 /* Find the white board with name nm[]. */
52 
53 static ABoard *find_wbp(char *nm)
54 {
55  ABoard *p;
56 
57  for (p = boards; p; p = p->next) {
58  if (strcmp(nm, p->clients->clientdata.boardnm) == 0)
59  break;
60  }
61  return p;
62 }
63 
64 /*
65  * Add a client. May start a new white board. We clnt_create once
66  * for each client.
67  */
68 int *addclient_1_svc(ClientData * cd, struct svc_req *srq)
69 {
70  static int result; /* note: static */
71  ABoard *ab = find_wbp(cd->boardnm);
72  AClient *q = (AClient *) malloc(sizeof(AClient));
73 
74  printf("addclient_1_svc(%p, %p)\n", (void *) cd, (void *) srq);
75 
76  if (q == NULL)
77  goto error;
78  q->clientdata = *cd;
79  q->callback =
80  clnt_create(cd->machinenm, cd->nprogram, cd->nversion, "tcp");
81  if (q->callback == NULL) {
82  free(q);
83  goto error;
84  }
85  if (ab == NULL) {
86  /* new white board */
87  ab = (ABoard *) malloc(sizeof(ABoard));
88  if (ab == NULL)
89  goto error;
90  ab->lines = NULL;
91  ab->clients = NULL;
92  insert((ListNode **) & boards, (ListNode *) ab);
93  }
94  insert((ListNode **) & ab->clients, (ListNode *) q);
95  result = 0;
96  return &result;
97 error:
98  result = -1;
99  return &result;
100 }
101 
102 /*
103  * Commit suicide! Unregister yourself. Invoked as SIGALRM handler.
104  */
105 static void die(int dummy)
106 {
107  int x = pmap_unset(WhiteBoardServer, WhiteBoardServerVersion);
108  exit(x != 1);
109 }
110 
111 static void delboard(ABoard * ab)
112 {
113  ALine *lp, *lq;
114 
115  for (lp = ab->lines; lp; lp = lq) {
116  lq = lp->next;
117  free(lp);
118  }
119  delete((ListNode **) & boards, (ListNode *) ab);
120 }
121 
122 /*
123  * Delete a client. If this is the last client on a whiteboard, delete the
124  * board too. If no more boards left, kill yourself.
125  */
126 int *delclient_1_svc(ClientData * cd, struct svc_req *srq)
127 {
128  static int result; /* note: static */
129  AClient *p;
130  ABoard *ab = find_wbp(cd->boardnm);
131 
132  if (ab == NULL)
133  goto error;
134 
135  /* delete the client; search on nprogram and machinenm */
136  for (p = ab->clients; p; p = p->next) {
137  if (p->clientdata.nprogram == cd->nprogram
138  && strcmp(p->clientdata.machinenm, cd->machinenm) == 0) {
139  clnt_destroy(p->callback);
140  delete((ListNode **) & ab->clients, (ListNode *) p);
141  if (ab->clients == NULL)
142  delboard(ab);
143  break;
144  }
145  }
146  if (boards == NULL) {
147  /* server has no clients; so die *after* doing a return &i. */
148  struct sigaction asigalrm;
149  asigalrm.sa_flags = 0;
150  asigalrm.sa_handler = die;
151  sigemptyset(&asigalrm.sa_mask);
152  sigaction(SIGALRM, &asigalrm, 0); /* install the signal handler */
153  alarm(1); /* invoke die() after 1 second */
154  }
155  result = 0;
156  return &result;
157 error:
158  result = -1;
159  return &result;
160 }
161 
162 /*
163  * A clients gives us a new line. Get the coordinates of the line and
164  * distribute among the clients.
165  */
166 int *addline_1_svc(AddLineArg * ap, struct svc_req *srq)
167 {
168  static int result; /* note: static */
169  AClient *p;
170  ALine *lp = (ALine *) malloc(sizeof(ALine));
171  ABoard *ab = find_wbp(ap->clientdata.boardnm);
172 
173  if (ab == NULL || lp == NULL)
174  goto error;
175 
176  /* add the line to the list of lines on this board */
177  lp->ln = ap->ln;
178  insert((ListNode **) & ab->lines, (ListNode *) lp);
179 
180  /* tell all clients on this board of this addition */
181  for (p = ab->clients; p; p = p->next) {
182  callbackfromwbs_1(&ap->ln, p->callback);
183  }
184  result = 0;
185  return &result;
186 error:
187  result = -1;
188  return &result;
189 
190 }
191 
192 /*
193  * A client wants to know all the lines present on his white board.
194  */
195 Linep *sendallmylines_1_svc(ClientData * cd, struct svc_req * srq)
196 {
197  static ALine *lp = NULL; /* note: static */
198  ABoard *ab = find_wbp(cd->boardnm);
199  return (ab ? &ab->lines : &lp);
200 }
201 
202 /* -eof- */
struct ABoard ABoard
int sigemptyset(sigset_t *set)
int sigaction(int, const struct sigaction *, struct sigaction *)
struct AClient * next
Definition: server.c:37
int pmap_unset(unsigned long, unsigned long)
static ABoard * find_wbp(char *nm)
Definition: server.c:53
struct ListNode ListNode
static void die(int dummy)
Definition: server.c:105
ALine * lines
Definition: server.c:46
Definition: server.c:36
int sa_flags
Definition: wb.h:33
static ABoard * boards
Definition: server.c:49
void(* sa_handler)(int)
Definition: wb.h:30
CLIENT * callback
Definition: server.c:39
struct AClient AClient
AClient * clients
Definition: server.c:45
int * addline_1_svc(AddLineArg *ap, struct svc_req *srq)
Definition: server.c:166
static void insert(ListNode **hdr, ListNode *p)
Definition: server.c:13
struct ListNode * next
Definition: server.c:10
int * addclient_1_svc(ClientData *cd, struct svc_req *srq)
Definition: server.c:68
Linep * sendallmylines_1_svc(ClientData *cd, struct svc_req *srq)
Definition: server.c:195
static void delboard(ABoard *ab)
Definition: server.c:111
Definition: server.c:42
Definition: wb.h:28
sigset_t sa_mask
Definition: wb.h:32
struct ABoard * next
Definition: server.c:43
int * delclient_1_svc(ClientData *cd, struct svc_req *srq)
Definition: server.c:126
void * callbackfromwbs_1(OneLn *argp, CLIENT *clnt)
Definition: server.c:9
ClientData clientdata
Definition: server.c:38