ctdb-server: Use find_public_ip_vnn() in a couple of extra places
[samba4-gss.git] / lib / util / server_id.c
blob2370163da80da64c6f9378ec1706177f4f76c5be
1 /*
2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Bartlett 2011
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "replace.h"
21 #include "lib/util/debug.h"
22 #include "lib/util/fault.h"
23 #include "lib/util/server_id.h"
24 #include "lib/util/byteorder.h"
25 #include "librpc/gen_ndr/server_id.h"
27 bool server_id_same_process(const struct server_id *p1,
28 const struct server_id *p2)
30 return ((p1->pid == p2->pid) && (p1->vnn == p2->vnn));
33 int server_id_cmp(const struct server_id *p1, const struct server_id *p2)
35 if (p1->vnn != p2->vnn) {
36 return (p1->vnn < p2->vnn) ? -1 : 1;
38 if (p1->pid != p2->pid) {
39 return (p1->pid < p2->pid) ? -1 : 1;
41 if (p1->task_id != p2->task_id) {
42 return (p1->task_id < p2->task_id) ? -1 : 1;
44 if (p1->unique_id != p2->unique_id) {
45 return (p1->unique_id < p2->unique_id) ? -1 : 1;
47 return 0;
50 bool server_id_equal(const struct server_id *p1, const struct server_id *p2)
52 int cmp = server_id_cmp(p1, p2);
53 return (cmp == 0);
56 char *server_id_str_buf(struct server_id id, struct server_id_buf *dst)
58 return server_id_str_buf_unique_ex(id, '\0', dst);
61 char *server_id_str_buf_unique_ex(struct server_id id,
62 char unique_delimiter,
63 struct server_id_buf *dst)
65 if (id.unique_id == SERVERID_UNIQUE_ID_NOT_TO_VERIFY) {
66 unique_delimiter = '\0';
69 if (server_id_is_disconnected(&id)) {
70 strlcpy(dst->buf, "disconnected", sizeof(dst->buf));
71 } else if ((id.vnn == NONCLUSTER_VNN) && (id.task_id == 0)) {
72 snprintf(dst->buf, sizeof(dst->buf),
73 "%"PRIu64"%c%"PRIu64"",
74 id.pid, unique_delimiter, id.unique_id);
75 } else if (id.vnn == NONCLUSTER_VNN) {
76 snprintf(dst->buf, sizeof(dst->buf),
77 "%"PRIu64".%"PRIu32"%c%"PRIu64"",
78 id.pid, id.task_id,
79 unique_delimiter, id.unique_id);
80 } else if (id.task_id == 0) {
81 snprintf(dst->buf, sizeof(dst->buf),
82 "%"PRIu32":%"PRIu64"%c%"PRIu64"",
83 id.vnn, id.pid,
84 unique_delimiter, id.unique_id);
85 } else {
86 snprintf(dst->buf, sizeof(dst->buf),
87 "%"PRIu32":%"PRIu64".%"PRIu32"%c%"PRIu64"",
88 id.vnn, id.pid, id.task_id,
89 unique_delimiter, id.unique_id);
91 return dst->buf;
94 char *server_id_str_buf_unique(struct server_id id, struct server_id_buf *dst)
96 return server_id_str_buf_unique_ex(id, '/', dst);
99 struct server_id server_id_from_string(uint32_t local_vnn,
100 const char *pid_string)
102 return server_id_from_string_ex(local_vnn, '/', pid_string);
105 struct server_id server_id_from_string_ex(uint32_t local_vnn,
106 char unique_delimiter,
107 const char *pid_string)
109 struct server_id templ = {
110 .vnn = NONCLUSTER_VNN, .pid = UINT64_MAX
112 struct server_id result;
113 char unique_delimiter_found = '\0';
114 int ret;
117 * We accept various forms with 1, 2 or 3 component forms
118 * because the server_id_str_buf() can print different forms, and
119 * we want backwards compatibility for scripts that may call
120 * smbclient.
123 result = templ;
124 ret = sscanf(pid_string, "%"SCNu32":%"SCNu64".%"SCNu32"%c%"SCNu64,
125 &result.vnn, &result.pid, &result.task_id,
126 &unique_delimiter_found, &result.unique_id);
127 if (ret == 5 && unique_delimiter_found == unique_delimiter) {
128 return result;
131 result = templ;
132 ret = sscanf(pid_string, "%"SCNu32":%"SCNu64".%"SCNu32,
133 &result.vnn, &result.pid, &result.task_id);
134 if (ret == 3) {
135 return result;
138 result = templ;
139 ret = sscanf(pid_string, "%"SCNu32":%"SCNu64"%c%"SCNu64,
140 &result.vnn, &result.pid,
141 &unique_delimiter_found, &result.unique_id);
142 if (ret == 4 && unique_delimiter_found == unique_delimiter) {
143 return result;
146 result = templ;
147 ret = sscanf(pid_string, "%"SCNu32":%"SCNu64,
148 &result.vnn, &result.pid);
149 if (ret == 2) {
150 return result;
153 result = templ;
154 ret = sscanf(pid_string, "%"SCNu64".%"SCNu32"%c%"SCNu64,
155 &result.pid, &result.task_id,
156 &unique_delimiter_found, &result.unique_id);
157 if (ret == 4 && unique_delimiter_found == unique_delimiter) {
158 result.vnn = local_vnn;
159 return result;
162 result = templ;
163 ret = sscanf(pid_string, "%"SCNu64".%"SCNu32,
164 &result.pid, &result.task_id);
165 if (ret == 2) {
166 result.vnn = local_vnn;
167 return result;
170 result = templ;
171 ret = sscanf(pid_string, "%"SCNu64"%c%"SCNu64,
172 &result.pid, &unique_delimiter_found, &result.unique_id);
173 if (ret == 3 && unique_delimiter_found == unique_delimiter) {
174 result.vnn = local_vnn;
175 return result;
178 result = templ;
179 ret = sscanf(pid_string, "%"SCNu64, &result.pid);
180 if (ret == 1) {
181 result.vnn = local_vnn;
182 return result;
185 if (strcmp(pid_string, "disconnected") == 0) {
186 server_id_set_disconnected(&result);
187 return result;
190 return templ;
194 * Set the serverid to the special value that represents a disconnected
195 * client for (e.g.) durable handles.
197 void server_id_set_disconnected(struct server_id *id)
199 *id = (struct server_id) {
200 .pid = UINT64_MAX,
201 .task_id = UINT32_MAX,
202 .vnn = NONCLUSTER_VNN,
203 .unique_id = SERVERID_UNIQUE_ID_NOT_TO_VERIFY,
208 * check whether a serverid is the special placeholder for
209 * a disconnected client
211 bool server_id_is_disconnected(const struct server_id *id)
213 struct server_id dis;
215 SMB_ASSERT(id != NULL);
217 server_id_set_disconnected(&dis);
219 return server_id_equal(id, &dis);
222 void server_id_put(uint8_t buf[SERVER_ID_BUF_LENGTH],
223 const struct server_id id)
225 SBVAL(buf, 0, id.pid);
226 SIVAL(buf, 8, id.task_id);
227 SIVAL(buf, 12, id.vnn);
228 SBVAL(buf, 16, id.unique_id);
231 void server_id_get(struct server_id *id,
232 const uint8_t buf[SERVER_ID_BUF_LENGTH])
234 id->pid = BVAL(buf, 0);
235 id->task_id = IVAL(buf, 8);
236 id->vnn = IVAL(buf, 12);
237 id->unique_id = BVAL(buf, 16);