Merge tag 'nfs-for-5.2-1' of git://git.linux-nfs.org/projects/anna/linux-nfs
[sfrench/cifs-2.6.git] / tools / iio / lsiio.c
1 /*
2  * Industrial I/O utilities - lsiio.c
3  *
4  * Copyright (c) 2010 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 as published by
8  * the Free Software Foundation.
9  */
10
11 #include <string.h>
12 #include <dirent.h>
13 #include <stdio.h>
14 #include <errno.h>
15 #include <stdint.h>
16 #include <stdlib.h>
17 #include <unistd.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <sys/dir.h>
21 #include "iio_utils.h"
22
23 static enum verbosity {
24         VERBLEVEL_DEFAULT,      /* 0 gives lspci behaviour */
25         VERBLEVEL_SENSORS,      /* 1 lists sensors */
26 } verblevel = VERBLEVEL_DEFAULT;
27
28 const char *type_device = "iio:device";
29 const char *type_trigger = "trigger";
30
31 static inline int check_prefix(const char *str, const char *prefix)
32 {
33         return strlen(str) > strlen(prefix) &&
34                strncmp(str, prefix, strlen(prefix)) == 0;
35 }
36
37 static inline int check_postfix(const char *str, const char *postfix)
38 {
39         return strlen(str) > strlen(postfix) &&
40                strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
41 }
42
43 static int dump_channels(const char *dev_dir_name)
44 {
45         DIR *dp;
46         const struct dirent *ent;
47
48         dp = opendir(dev_dir_name);
49         if (!dp)
50                 return -errno;
51
52         while (ent = readdir(dp), ent)
53                 if (check_prefix(ent->d_name, "in_") &&
54                    (check_postfix(ent->d_name, "_raw") ||
55                     check_postfix(ent->d_name, "_input")))
56                         printf("   %-10s\n", ent->d_name);
57
58         return (closedir(dp) == -1) ? -errno : 0;
59 }
60
61 static int dump_one_device(const char *dev_dir_name)
62 {
63         char name[IIO_MAX_NAME_LENGTH];
64         int dev_idx;
65         int ret;
66
67         ret = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_device), "%i",
68                      &dev_idx);
69         if (ret != 1)
70                 return -EINVAL;
71
72         ret = read_sysfs_string("name", dev_dir_name, name);
73         if (ret < 0)
74                 return ret;
75
76         printf("Device %03d: %s\n", dev_idx, name);
77
78         if (verblevel >= VERBLEVEL_SENSORS)
79                 return dump_channels(dev_dir_name);
80
81         return 0;
82 }
83
84 static int dump_one_trigger(const char *dev_dir_name)
85 {
86         char name[IIO_MAX_NAME_LENGTH];
87         int dev_idx;
88         int ret;
89
90         ret = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_trigger),
91                      "%i", &dev_idx);
92         if (ret != 1)
93                 return -EINVAL;
94
95         ret = read_sysfs_string("name", dev_dir_name, name);
96         if (ret < 0)
97                 return ret;
98
99         printf("Trigger %03d: %s\n", dev_idx, name);
100
101         return 0;
102 }
103
104 static int dump_devices(void)
105 {
106         const struct dirent *ent;
107         int ret;
108         DIR *dp;
109
110         dp = opendir(iio_dir);
111         if (!dp) {
112                 fprintf(stderr, "No industrial I/O devices available\n");
113                 return -ENODEV;
114         }
115
116         while (ent = readdir(dp), ent) {
117                 if (check_prefix(ent->d_name, type_device)) {
118                         char *dev_dir_name;
119
120                         if (asprintf(&dev_dir_name, "%s%s", iio_dir,
121                                      ent->d_name) < 0) {
122                                 ret = -ENOMEM;
123                                 goto error_close_dir;
124                         }
125
126                         ret = dump_one_device(dev_dir_name);
127                         if (ret) {
128                                 free(dev_dir_name);
129                                 goto error_close_dir;
130                         }
131
132                         free(dev_dir_name);
133                         if (verblevel >= VERBLEVEL_SENSORS)
134                                 printf("\n");
135                 }
136         }
137         rewinddir(dp);
138         while (ent = readdir(dp), ent) {
139                 if (check_prefix(ent->d_name, type_trigger)) {
140                         char *dev_dir_name;
141
142                         if (asprintf(&dev_dir_name, "%s%s", iio_dir,
143                                      ent->d_name) < 0) {
144                                 ret = -ENOMEM;
145                                 goto error_close_dir;
146                         }
147
148                         ret = dump_one_trigger(dev_dir_name);
149                         if (ret) {
150                                 free(dev_dir_name);
151                                 goto error_close_dir;
152                         }
153
154                         free(dev_dir_name);
155                 }
156         }
157
158         return (closedir(dp) == -1) ? -errno : 0;
159
160 error_close_dir:
161         if (closedir(dp) == -1)
162                 perror("dump_devices(): Failed to close directory");
163
164         return ret;
165 }
166
167 int main(int argc, char **argv)
168 {
169         int c, err = 0;
170
171         while ((c = getopt(argc, argv, "v")) != EOF) {
172                 switch (c) {
173                 case 'v':
174                         verblevel++;
175                         break;
176
177                 case '?':
178                 default:
179                         err++;
180                         break;
181                 }
182         }
183         if (err || argc > optind) {
184                 fprintf(stderr, "Usage: lsiio [options]...\n"
185                         "List industrial I/O devices\n"
186                         "  -v  Increase verbosity (may be given multiple times)\n");
187                 exit(1);
188         }
189
190         return dump_devices();
191 }