]> git.ipfire.org Git - thirdparty/util-linux.git/blame - lsfd-cmd/sock.c
Merge branch 'PR/libsmartcols-fix-wrap' of github.com:karelzak/util-linux-work
[thirdparty/util-linux.git] / lsfd-cmd / sock.c
CommitLineData
2da06d3c
MY
1/*
2 * lsfd-sock.c - handle associations opening socket objects
3 *
4 * Copyright (C) 2021 Red Hat, Inc. All rights reserved.
5 * Written by Masatake YAMATO <yamato@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it would be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software Foundation,
19 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
2dfe2e4d
MY
22#include <sys/types.h>
23#include <sys/xattr.h>
24
2da06d3c 25#include "lsfd.h"
ac8be186 26#include "sock.h"
2da06d3c 27
0ee16e43
MY
28static void attach_sock_xinfo(struct file *file)
29{
30 struct sock *sock = (struct sock *)file;
046c5d5a 31
0ee16e43 32 sock->xinfo = get_sock_xinfo(file->stat.st_ino);
046c5d5a
MY
33 if (sock->xinfo) {
34 struct ipc *ipc = get_ipc(file);
35 if (ipc)
36 add_endpoint(&sock->endpoint, ipc);
37 }
38}
39
40static const struct ipc_class *sock_get_ipc_class(struct file *file)
41{
42 struct sock *sock = (struct sock *)file;
43
44 if (sock->xinfo && sock->xinfo->class->get_ipc_class)
45 return sock->xinfo->class->get_ipc_class(sock->xinfo, sock);
46
47 return NULL;
0ee16e43
MY
48}
49
2da06d3c 50static bool sock_fill_column(struct proc *proc __attribute__((__unused__)),
2dfe2e4d 51 struct file *file,
2da06d3c
MY
52 struct libscols_line *ln,
53 int column_id,
54 size_t column_index)
55{
cb6a617d 56 char *str = NULL;
2dfe2e4d 57 struct sock *sock = (struct sock *)file;
f4479119
MY
58
59 if (sock->xinfo && sock->xinfo->class
60 && sock->xinfo->class->fill_column) {
61 if (sock->xinfo->class->fill_column(proc, sock->xinfo, sock, ln,
62 column_id, column_index,
63 &str))
64 goto out;
65 }
66
2da06d3c
MY
67 switch(column_id) {
68 case COL_TYPE:
be019f66
MY
69 if (!sock->protoname)
70 return false;
71 /* FALL THROUGH */
e193602a 72 case COL_SOCK_PROTONAME:
2dfe2e4d
MY
73 if (sock->protoname)
74 if (scols_line_set_data(ln, column_index, sock->protoname))
75 err(EXIT_FAILURE, _("failed to add output data"));
76 return true;
7b50bd25
MY
77 case COL_NAME:
78 if (sock->xinfo
79 && sock->xinfo->class && sock->xinfo->class->get_name) {
b3649945 80 str = sock->xinfo->class->get_name(sock->xinfo, sock);
7b50bd25
MY
81 if (str)
82 break;
83 }
84 return false;
618db964 85 case COL_SOURCE:
a500de34
MY
86 if (major(file->stat.st_dev) == 0
87 && strncmp(file->name, "socket:", 7) == 0) {
e0dc84da 88 str = xstrdup("sockfs");
a500de34
MY
89 break;
90 }
91 return false;
86a7e471 92 case COL_SOCK_NETNS:
7b50bd25
MY
93 if (sock->xinfo) {
94 xasprintf(&str, "%llu",
95 (unsigned long long)sock->xinfo->netns_inode);
96 break;
97 }
98 return false;
86a7e471 99 case COL_SOCK_TYPE:
7b50bd25
MY
100 if (sock->xinfo
101 && sock->xinfo->class && sock->xinfo->class->get_type) {
102 str = sock->xinfo->class->get_type(sock->xinfo, sock);
103 if (str)
104 break;
105 }
106 return false;
86a7e471 107 case COL_SOCK_STATE:
7b50bd25
MY
108 if (sock->xinfo
109 && sock->xinfo->class && sock->xinfo->class->get_state) {
110 str = sock->xinfo->class->get_state(sock->xinfo, sock);
111 if (str)
112 break;
113 }
114 return false;
86a7e471 115 case COL_SOCK_LISTENING:
45d61bff
MY
116 str = xstrdup((sock->xinfo
117 && sock->xinfo->class
118 && sock->xinfo->class->get_listening
119 && sock->xinfo->class->get_listening(sock->xinfo, sock))
120 ? "1"
121 : "0");
122 break;
426ff07f
MY
123 case COL_SOCK_SHUTDOWN:
124 str = xstrdup("??");
125 break;
2da06d3c
MY
126 default:
127 return false;
128 }
cb6a617d 129
f4479119 130 out:
cb6a617d
MY
131 if (!str)
132 err(EXIT_FAILURE, _("failed to add output data"));
133 if (scols_line_refer_data(ln, column_index, str))
134 err(EXIT_FAILURE, _("failed to add output data"));
135 return true;
2da06d3c
MY
136}
137
99ce4250 138static void init_sock_content(struct file *file)
2dfe2e4d 139{
f9fa97d3 140 int fd;
046c5d5a 141 struct sock *sock = (struct sock *)file;
f9fa97d3
KZ
142
143 assert(file);
f9fa97d3
KZ
144
145 fd = file->association;
146
1e9880a8 147 if (fd >= 0 || fd == -ASSOC_MEM || fd == -ASSOC_SHM) {
34f3fd1a 148 char path[PATH_MAX] = {'\0'};
2dfe2e4d
MY
149 char buf[256];
150 ssize_t len;
f9fa97d3 151
34f3fd1a 152 assert(file->proc);
2dfe2e4d 153
c0f84bd1 154 if (is_opened_file(file))
34f3fd1a 155 sprintf(path, "/proc/%d/fd/%d", file->proc->pid, fd);
99ce4250 156 else
174ab64a 157 sprintf(path, "/proc/%d/map_files/%"PRIx64 "-%" PRIx64,
34f3fd1a 158 file->proc->pid,
99ce4250
KZ
159 file->map_start,
160 file->map_end);
161
2dfe2e4d
MY
162 len = getxattr(path, "system.sockprotoname", buf, sizeof(buf) - 1);
163 if (len > 0) {
164 buf[len] = '\0';
165 sock->protoname = xstrdup(buf);
166 }
167 }
046c5d5a
MY
168
169 init_endpoint(&sock->endpoint);
2dfe2e4d
MY
170}
171
172static void free_sock_content(struct file *file)
2da06d3c 173{
2dfe2e4d
MY
174 struct sock *sock = (struct sock *)file;
175 if (sock->protoname) {
176 free(sock->protoname);
177 sock->protoname = NULL;
178 }
2da06d3c 179}
14e16696 180
0ee16e43
MY
181static void initialize_sock_class(void)
182{
183 initialize_sock_xinfos();
184}
185
186static void finalize_sock_class(void)
187{
188 finalize_sock_xinfos();
189}
190
14e16696
MY
191const struct file_class sock_class = {
192 .super = &file_class,
2dfe2e4d 193 .size = sizeof(struct sock),
14e16696 194 .fill_column = sock_fill_column,
0ee16e43 195 .attach_xinfo = attach_sock_xinfo,
f9fa97d3 196 .initialize_content = init_sock_content,
2dfe2e4d 197 .free_content = free_sock_content,
0ee16e43
MY
198 .initialize_class = initialize_sock_class,
199 .finalize_class = finalize_sock_class,
046c5d5a 200 .get_ipc_class = sock_get_ipc_class,
14e16696 201};