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" /* Has to be first */
22 #include "eiext.h"
23 #include "eisend.h"
24 #include "eirecv.h"
25 #include "ei_connect_int.h"
26 #include "ei_connect.h"
27 #include "ei.h"
28 #include "ei_internal.h"
29
30 /* remove the association between name and its pid */
31 /* global:unregister_name(name) -> ok */
ei_global_unregister(ei_cnode * ec,int fd,const char * name)32 int ei_global_unregister(ei_cnode *ec, int fd, const char *name)
33 {
34 char buf[EISMALLBUF];
35 char *bufp=buf;
36 char tmpbuf[64];
37 int index = 0;
38 erlang_pid *self = ei_self(ec);
39 erlang_msg msg;
40 int i;
41 int version,arity,msglen;
42 int needunlink, needatom, needdemonitor;
43
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,"unregister_name_external") /* Fun */
51 || ei_encode_list_header(buf,&index,1) /* Args: [ name ] */
52 || ei_encode_atom(buf,&index,name)
53 || ei_encode_empty_list(buf,&index)
54 || ei_encode_atom(buf,&index,"user")) { /* user */
55 EI_CONN_SAVE_ERRNO__(EINVAL);
56 return ERL_ERROR;
57 }
58
59 /* make the rpc call */
60 if (ei_send_reg_encoded(fd,self,"rex",buf,index)) return ERL_ERROR;
61
62 /* get the reply: expect unlink and an atom, or just an atom */
63 needunlink = needatom = needdemonitor = 1;
64 while (1) {
65 /* get message */
66 while (1) {
67 index = EISMALLBUF;
68 if (!(i = ei_recv_internal(fd,&bufp,&index,&msg,&msglen,1,0))) continue;
69 else break;
70 }
71
72 switch (i) {
73 case ERL_UNLINK:
74 /* got unlink */
75 if (!needunlink) {
76 EI_CONN_SAVE_ERRNO__(EBADMSG);
77 return ERL_ERROR;
78 }
79 needunlink = 0;
80 break;
81
82 case ERL_DEMONITOR_P-10:
83 /* got demonitor */
84 if (!needdemonitor) {
85 EI_CONN_SAVE_ERRNO__(EBADMSG);
86 return ERL_ERROR;
87 }
88 needdemonitor = 0;
89 break;
90
91 case ERL_SEND:
92 /* got message - does it contain our atom? */
93 if (!needatom) {
94 EI_CONN_SAVE_ERRNO__(EBADMSG);
95 return ERL_ERROR;
96 }
97 else {
98 /* expecting { rex, ok } */
99 index = 0;
100 if (ei_decode_version(buf,&index,&version)
101 || ei_decode_tuple_header(buf,&index,&arity)
102 || (arity != 2)
103 || ei_decode_atom(buf,&index,tmpbuf)
104 || strcmp(tmpbuf,"rex")
105 || ei_decode_atom(buf,&index,tmpbuf)
106 || strcmp(tmpbuf,"ok")) {
107 EI_CONN_SAVE_ERRNO__(EBADMSG);
108 return ERL_ERROR; /* bad response from other side */
109 }
110
111 /* we're done here */
112 return 0;
113 }
114 break;
115
116 default:
117 EI_CONN_SAVE_ERRNO__(EBADMSG);
118 return ERL_ERROR;
119 }
120 }
121
122 return 0;
123 }
124