1 /*
2  * %CopyrightBegin%
3  *
4  * Copyright Ericsson AB 1998-2016. All Rights Reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * %CopyrightEnd%
19  */
20 #include <string.h>
21 #include "eidef.h"
22 #include "eiext.h"
23 #include "eisend.h"
24 #include "eirecv.h"
25 #include "ei.h"
26 #include "ei_internal.h"
27 
ei_global_register(int fd,const char * name,erlang_pid * self)28 int ei_global_register(int fd, const char *name, erlang_pid *self)
29 {
30   char buf[EISMALLBUF];
31   char *bufp=buf;
32   char tmpbuf[64];
33   int index = 0;
34   erlang_msg msg;
35   int needlink, needatom, needmonitor;
36   int arity;
37   int version;
38   int msglen;
39   int i;
40 
41   /* set up rpc arguments */
42   /* { PidFrom, { call, Mod, Fun, Args, user }}  */
43   index = 0;
44   if (ei_encode_version(buf,&index)
45       || ei_encode_tuple_header(buf,&index,2)
46       || ei_encode_pid(buf,&index,self)               /* PidFrom */
47       || ei_encode_tuple_header(buf,&index,5)
48       || ei_encode_atom(buf,&index,"call")            /* call */
49       || ei_encode_atom(buf,&index,"global")          /* Mod */
50       || ei_encode_atom(buf,&index,"register_name_external")/* Fun */
51       || ei_encode_list_header(buf,&index,3) /* Args: [ name, self(), cnode ] */
52       || ei_encode_atom(buf,&index,name)
53       || ei_encode_pid(buf,&index,self)
54       || ei_encode_tuple_header(buf,&index,2)
55       || ei_encode_atom(buf,&index,"global") /* special "resolve" treatment */
56       || ei_encode_atom(buf,&index,"cnode")  /* i.e. we get a SEND when conflict */
57       || ei_encode_empty_list(buf,&index)
58       || ei_encode_atom(buf,&index,"user")) {           /* user */
59       EI_CONN_SAVE_ERRNO__(EINVAL);
60       return ERL_ERROR;
61   }
62 
63   /* make the rpc call */
64   if (ei_send_reg_encoded(fd,self,"rex",buf,index)) return ERL_ERROR;
65 
66   /* get the reply: expect link and an atom, or just an atom */
67   needlink = needatom = needmonitor = 1;
68   while (1) {
69     /* get message */
70     while (1) {
71       index = EISMALLBUF;
72       if (!(i = ei_recv_internal(fd,&bufp,&index,&msg,&msglen,1,0))) continue;
73       else break;
74     }
75 
76     switch (i) {
77     case ERL_LINK:
78       /* got link */
79       if (!needlink) {
80           EI_CONN_SAVE_ERRNO__(EBADMSG);
81           return ERL_ERROR;
82       }
83       needlink = 0;
84       break;
85 
86     case ERL_MONITOR_P-10:
87       /* got monitor */
88 	if (!needmonitor) {
89             EI_CONN_SAVE_ERRNO__(EBADMSG);
90             return ERL_ERROR;
91         }
92 	needmonitor = 0;
93       break;
94 
95     case ERL_SEND:
96       /* got message - does it contain our atom? */
97       if (!needatom) {
98           EI_CONN_SAVE_ERRNO__(EBADMSG);
99           return ERL_ERROR;
100       }
101       else {
102 	/* expecting { rex, yes } */
103 	index = 0;
104 	if (ei_decode_version(buf,&index,&version)
105 	    || ei_decode_tuple_header(buf,&index,&arity)
106 	    || (arity != 2)
107 	    || ei_decode_atom(buf,&index,tmpbuf)
108 	    || strcmp(tmpbuf,"rex")
109 	    || ei_decode_atom(buf,&index,tmpbuf)
110 	    || strcmp(tmpbuf,"yes")) {
111             EI_CONN_SAVE_ERRNO__(EBADMSG);
112             return ERL_ERROR; /* bad response from other side */
113         }
114 
115 	/* we're done */
116 	return 0;
117       }
118       break;
119 
120     default:
121       EI_CONN_SAVE_ERRNO__(EBADMSG);
122       return ERL_ERROR; /* something else */
123     }
124   }
125   return 0;
126 }
127 
128