Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libcs/cspath.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1990-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* Glenn Fowler
23
* AT&T Research
24
*
25
* return a pointer to a pathname for an open fd
26
*/
27
28
#include "cslib.h"
29
30
#include <ast_dir.h>
31
32
/*
33
* someone thinks FIFO and SOCK are the same (bsd, eh?)
34
*/
35
36
#if defined(S_IFMT) && defined(S_IFIFO)
37
#undef S_ISFIFO
38
#define S_ISFIFO(m) (((m)&S_IFMT)==S_IFIFO)
39
#endif
40
41
/*
42
* scan /dev for path matching st
43
*/
44
45
static char*
46
devpath(char* path, int size, int blk, register struct stat* st)
47
{
48
register DIR* dirp;
49
register struct dirent* entry;
50
DIR* subp = 0;
51
char* base;
52
int n;
53
int t;
54
struct stat tst;
55
56
strcpy(path, "/dev");
57
if (!(dirp = opendir(path))) return 0;
58
path[4] = '/';
59
base = path + 5;
60
for (n = 1;;)
61
{
62
while (entry = readdir(dirp))
63
{
64
#ifdef D_FILENO
65
if (n && D_FILENO(entry) != st->st_ino)
66
continue;
67
#endif
68
if (*entry->d_name == '.' || D_NAMLEN(entry) + (base - path) + 1 > size)
69
continue;
70
strcpy(base, entry->d_name);
71
if (stat(path, &tst))
72
continue;
73
if (!subp && S_ISDIR(tst.st_mode) && !streq(path, "/dev/fd"))
74
{
75
subp = dirp;
76
if (dirp = opendir(path))
77
{
78
base = path + strlen(path);
79
*base++ = '/';
80
}
81
else
82
{
83
dirp = subp;
84
subp = 0;
85
}
86
continue;
87
}
88
#ifndef D_FILENO
89
if (n && tst.st_ino != st->st_ino)
90
continue;
91
#endif
92
if (idevice(&tst) == idevice(st) && ((t = S_ISBLK(tst.st_mode)) || S_ISCHR(tst.st_mode)) && t == blk && (!n || tst.st_dev == st->st_dev && tst.st_ino == st->st_ino))
93
{
94
closedir(dirp);
95
if (subp) closedir(subp);
96
return path;
97
}
98
}
99
if (subp)
100
{
101
closedir(dirp);
102
dirp = subp;
103
subp = 0;
104
base = path + 5;
105
}
106
else if (!n--) break;
107
else rewinddir(dirp);
108
}
109
closedir(dirp);
110
return 0;
111
}
112
113
/*
114
* return a pointer to a pathname for an open fd
115
*/
116
117
char*
118
cspath(register Cs_t* state, register int fd, int flags)
119
{
120
register char* s;
121
char num[16];
122
struct stat st;
123
int typ;
124
125
#if CS_LIB_V10
126
127
struct tcpuser tcp;
128
129
#else
130
131
#if CS_LIB_SOCKET
132
133
struct sockaddr_in lcl;
134
struct sockaddr_in rmt;
135
Sock_size_t namlen = sizeof(lcl);
136
#ifdef SO_TYPE
137
Sock_size_t typlen = sizeof(typ);
138
#endif
139
140
#endif
141
142
#endif
143
144
if (fstat(fd, &st)) return "/dev/fd/-1";
145
else if (S_ISFIFO(st.st_mode)) sfsprintf(state->path, sizeof(state->path), "/dev/pipe/%u", st.st_ino);
146
#if CS_LIB_V10
147
else if (!ioctl(fd, TCPGETADDR, &tcp))
148
{
149
if (tcp.raddr) sfsprintf(state->path, sizeof(state->path), "/dev/tcp/%s/%d.%d", (flags & CS_PATH_NAME) ? csname(state, tcp.raddr) : csntoa(state, tcp.raddr), ntohs(tcp.rport), ntohs(tcp.lport));
150
else
151
{
152
if (!tcp.laddr) tcp.laddr = csaddr(state, NiL);
153
sfsprintf(state->path, sizeof(state->path), "/dev/tcp/%s/%d", (flags & CS_PATH_NAME) ? csname(state, tcp.laddr) : csntoa(state, tcp.laddr), ntohs(tcp.lport));
154
}
155
}
156
#endif
157
#if CS_LIB_SOCKET
158
else if (!getsockname(fd, (struct sockaddr*)&lcl, &namlen) && namlen == sizeof(lcl) && lcl.sin_family == AF_INET)
159
{
160
s = "tcp";
161
#ifdef SO_TYPE
162
if (!getsockopt(fd, SOL_SOCKET, SO_TYPE, (char*)&typ, &typlen)) switch (typ)
163
{
164
case SOCK_DGRAM:
165
s = "udp";
166
break;
167
case SOCK_STREAM:
168
break;
169
default:
170
sfsprintf(s = num, sizeof(num), "%d.p", typ);
171
break;
172
}
173
#endif
174
namlen = sizeof(rmt);
175
if (!getpeername(fd, (struct sockaddr*)&rmt, &namlen) && namlen == sizeof(rmt) && rmt.sin_family == AF_INET)
176
{
177
if (!rmt.sin_addr.s_addr) rmt.sin_addr.s_addr = csaddr(state, NiL);
178
sfsprintf(state->path, sizeof(state->path), "/dev/%s/%s/%d.%d", s, (flags & CS_PATH_NAME) ? csname(state, (unsigned long)rmt.sin_addr.s_addr) : csntoa(state, (unsigned long)rmt.sin_addr.s_addr), ntohs((unsigned short)rmt.sin_port), ntohs((unsigned short)lcl.sin_port));
179
}
180
else
181
{
182
if (!lcl.sin_addr.s_addr) lcl.sin_addr.s_addr = csaddr(state, NiL);
183
sfsprintf(state->path, sizeof(state->path), "/dev/%s/%s/%d", s, (flags & CS_PATH_NAME) ? csname(state, (unsigned long)lcl.sin_addr.s_addr) : csntoa(state, (unsigned long)lcl.sin_addr.s_addr), ntohs((unsigned short)lcl.sin_port));
184
}
185
}
186
#endif
187
else if ((typ = S_ISBLK(st.st_mode)) || S_ISCHR(st.st_mode))
188
{
189
if (s = devpath(state->path, sizeof(state->path), typ, &st))
190
return s;
191
sfsprintf(state->path, sizeof(state->path), "/dev/%s-%u,%u", typ ? "blk" : "chr", major(idevice(&st)), minor(idevice(&st)));
192
}
193
else
194
sfsprintf(state->path, sizeof(state->path), "/dev/ino/%u/%u", st.st_dev, st.st_ino);
195
return state->path;
196
}
197
198
char*
199
_cs_path(int fd, int flags)
200
{
201
return cspath(&cs, fd, flags);
202
}
203
204