]> CyberLeo.Net >> Repos - SourceForge/eyefi-config.git/blob - eyefi-linux.c
more portability improvements
[SourceForge/eyefi-config.git] / eyefi-linux.c
1 #include "eyefi-config.h"
2
3 #define O_DIRECT        00040000        /* direct disk access hint */
4
5 static int atoo(char o)
6 {
7         if ((o >= '0') && (o <= '7'))
8                 return atoh(o);
9         return -1;
10 }
11
12 static int octal_esc_to_chr(char *input)
13 {
14         int i=0;
15         int ret = 0;
16         int len = strlen(input);
17
18         //intf("%s('%s')\n", __func__, input);
19         if (input[0] != '\\')
20                 return -1;
21         if (len < 4)
22                 return -1;
23
24         for (i=1; i < len ; i++) {
25                 if (i > 3)
26                         break;
27                 int tmp = atoo(input[i]);
28                 //intf("tmp: %d\n", tmp);
29                 if (tmp < 0)
30                         return tmp;
31                 ret <<= 3;
32                 ret += tmp;
33         }
34         return ret;
35 }
36
37 static char *replace_escapes(char *str)
38 {
39         int i;
40         int output = 0;
41         debug_printf(4, "%s(%s)\n", __func__, str);
42         for (i=0; i < strlen(str); i++) {
43                 int esc = octal_esc_to_chr(&str[i]);
44                 if (esc >= 0) {
45                         str[output++] = esc;
46                         i += 3;
47                         continue;
48                 }
49                 str[output++] = str[i];
50         }
51         str[output] = '\0';
52         debug_printf(4, "replaced escapes in: '%s' bytes of output: %d\n", str, output);
53         return str;
54 }
55
56 int fd_dont_cache(int fd)
57 {
58         return fcntl(fd, F_SETFL, O_DIRECT);
59 }
60
61
62 #define LINEBUFSZ 1024
63 char *locate_eyefi_mount(void)
64 {
65         static char eyefi_mount[PATHNAME_MAX]; // PATH_MAX anyone?
66         char line[LINEBUFSZ];
67         FILE *mounts = fopen("/proc/mounts", "r");
68
69         char dev[LINEBUFSZ];
70         char mnt[LINEBUFSZ];
71         char fs[LINEBUFSZ];
72         char opt[LINEBUFSZ];
73         int foo;
74         int bar;
75         
76         if (strlen(eyefi_mount))
77                 return &eyefi_mount[0];
78
79         while (fgets(&line[0], 1023, mounts)) {
80                 int read;
81                 read = sscanf(&line[0], "%s %s %s %s %d %d",
82                                 &dev[0], &mnt[0], &fs[0], &opt[0],
83                                 &foo, &bar);
84                 // only look at fat filesystems:
85                 if (strcmp(fs, "msdos") && strcmp(fs, "vfat")) {
86                         debug_printf(2, "fs at '%s' is not fat, skipping...\n", mnt);
87                         continue;
88                 }
89                 // Linux's /proc/mounts has spaces like this \040
90                 replace_escapes(&mnt[0]);
91                 char *file = eyefi_file_on(REQM, &mnt[0]);
92                 debug_printf(2, "looking for EyeFi file here: '%s'\n", file);
93
94                 struct stat statbuf;
95                 int statret;
96                 statret = stat(file, &statbuf);
97                 free(file);
98                 if (statret) {
99                         debug_printf(2, "fs at: %s is not an Eye-Fi card, skipping...\n",
100                                         eyefi_mount);
101                         continue;
102                 }
103                 strcpy(&eyefi_mount[0], &mnt[0]);
104                 debug_printf(1, "located EyeFi card at: '%s'\n", eyefi_mount);
105                 break;
106         }
107         fclose(mounts);
108
109         if (strlen(eyefi_mount))
110                 return &eyefi_mount[0];
111
112         debug_printf(0, "unable to locate Eye-Fi card\n");
113         if (eyefi_debug_level < 5)
114                 debug_printf(0, "please run with '-d5' option and report the output\n");
115         else {
116                 debug_printf(0, "----------------------------------------------\n");
117                 debug_printf(0, "Debug information:\n");
118                 system("cat /proc/mounts >&2");
119         }
120         exit(1);
121         return NULL;
122 }