Not yet working stack checking (symbol STACKCHECK)
[gnokii.git] / common / misc.c
1 /*
2
3   G N O K I I
4
5   A Linux/Unix toolset and driver for Nokia mobile phones.
6
7   Released under the terms of the GNU GPL, see file COPYING for more details.
8
9 */
10
11 #include "config.h"
12
13 #include <string.h>\r
14 #include <ctype.h>\r
15 #include <time.h>\r
16
17 #ifndef WIN32
18   #include <sys/types.h>
19   #include <sys/stat.h>
20   #include <stdlib.h>
21   #include <fcntl.h>
22   #include <signal.h>
23   #include <unistd.h>
24   #include <errno.h>
25 #endif\r
26 \r
27 #include "misc.h"\r
28 #include "gsm-common.h"\r
29
30 #ifndef HAVE_TIMEOPS
31
32 /* FIXME: I have timersub defined in sys/time.h :-( PJ
33    FIXME: Jano wants this function too... PJ
34
35 int timersub(struct timeval *a, struct timeval *b, struct timeval *result) {
36   do {
37     (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;
38     (result)->tv_usec = (a)->tv_usec - (b)->tv_usec;
39     if ((result)->tv_usec < 0) {
40       --(result)->tv_sec;
41       (result)->tv_usec += 1000000;
42     }
43   } while (0);
44 }
45 */
46
47 #endif
48
49 int GetLine(FILE *File, char *Line, int count) {
50
51   char *ptr;
52
53   if (fgets(Line, count, File)) {
54     ptr=Line+strlen(Line)-1;
55
56     while ( (*ptr == '\n' || *ptr == '\r') && ptr>=Line) *ptr--='\0';
57
58     return strlen(Line);
59   } else return -1;
60 }
61
62 #ifndef UCLINUX
63
64 /*
65  * like atoi, but of a non-null-terminated string of a specified portion
66  */
67 int mem_to_int(const char str[], int len)
68 {
69   char aux[81];
70
71   strncpy(aux, str, len);
72   aux[len]=0;
73   return( atoi(aux) );
74
75
76 #endif /* UCLINUX */
77
78 /*
79  * make hexdump of Message
80  */
81 #ifdef DEBUG
82 void hexdump(u16 MessageLength, u8 *MessageBuffer)
83 {
84  
85   int count;
86   int n=0;
87   char string1[80]="";
88   char string2[80]="";
89   char hex1[10];
90   char hex2[10];
91  
92   for (count = 0; count < MessageLength; count ++)
93   {
94     n++;
95
96     switch (MessageBuffer[count]) {
97       case 0x09:
98         sprintf(hex1,"%02x  ",MessageBuffer[count]);
99         strcpy(hex2,".");
100         break;
101       default:
102         if (isprint(MessageBuffer[count]))
103           sprintf(hex1,"%02x%c ",MessageBuffer[count],MessageBuffer[count]);
104         else
105           sprintf(hex1,"%02x  ",MessageBuffer[count]);
106
107         if (isprint(MessageBuffer[count])) sprintf(hex2,"%c",MessageBuffer[count]);
108                                       else strcpy(hex2,".");
109         break;
110     }
111
112     if ( n!=15 && count != MessageLength-1 ) hex1[3]='|';
113  
114     strcat(string1,hex1);
115     strcat(string2,hex2);
116  
117     if ( n==15 || count == MessageLength-1 )
118     {      
119       fprintf(stdout,"%-60s%03x %s\n",string1,count+1,string2);
120       strcpy(string1,"");
121       strcpy(string2,"");
122       n=0;
123     }
124   }//for count
125
126   if (n!=0) fprintf (stdout,_("\n")); 
127  
128   fflush(stdout);
129 }
130
131 void txhexdump(u16 MessageLength, u8 *MessageBuffer)
132
133   int count;
134   int n=0;
135  
136   for (count = 0; count < MessageLength; count ++)
137    {
138     n++;
139     fprintf(stdout,_("%02x"),MessageBuffer[count]);
140     switch (MessageBuffer[count]) {
141       case 0x09:
142         fprintf(stdout,_(" |"));
143         break;
144       default:
145         if (isprint(MessageBuffer[count])) fprintf(stdout, _("%c|"),MessageBuffer[count]);
146                                       else fprintf(stdout,_(" |"));
147         break;
148     }
149
150     if (n==18)
151     { 
152       fprintf (stdout,_("\n"));
153       n=0;
154     }
155    }//for count
156
157   if (n!=0) fprintf (stdout,_("\n")); 
158
159   fflush(stdout);
160 }
161 #endif
162
163 #ifndef WIN32
164
165 #ifndef UCLINUX
166
167 #define max_buf_len 128
168 #define lock_path "/var/lock/LCK.."
169
170 /* Lock the device. Return allocated string with a lock name */
171 char *lock_device(const char* port)
172 {
173         char *lock_file = NULL;
174         char buffer[max_buf_len];
175         char *aux = rindex(port, '/');
176         int fd, len = strlen(aux) + strlen(lock_path);
177
178         memset(buffer, 0, sizeof(buffer));
179         lock_file = calloc(len + 1, 1);
180         if (!lock_file) {
181                 fprintf(stderr, _("Cannot lock device\n"));
182                 return NULL;
183         }
184         /* I think we don't need to use strncpy, as we should have enough
185          * buffer due to strlen results
186          */
187         strcpy(lock_file, lock_path);
188         strcat(lock_file, aux);
189
190         /* Check for the stale lockfile.
191          * The code taken from minicom by Miquel van Smoorenburg */
192         if ((fd = open(lock_file, O_RDONLY)) >= 0) {
193                 char buf[max_buf_len];
194                 int pid, n = 0;
195
196                 n = read(fd, buf, sizeof(buf) - 1);
197                 close(fd);
198                 if (n > 0) {
199                         pid = -1;
200                         if (n == 4)
201                                 /* Kermit-style lockfile. */
202                                 pid = *(int *)buf;
203                         else {
204                                 /* Ascii lockfile. */
205                                 buf[n] = 0;
206                                 sscanf(buf, "%d", &pid);
207                         }
208                         if (pid > 0 && kill((pid_t)pid, 0) < 0 && errno == ESRCH) {
209                                 fprintf(stderr, _("Lockfile is stale. Overriding it..\n"));
210                                 sleep(1);
211                                 unlink(lock_file);
212                         } else
213                                 n = 0;
214                 }
215                 if (n == 0) {
216                         free(lock_file);
217                         fprintf(stderr, _("Device is already locked.\n"));
218                         return NULL;
219                 }
220         }
221
222         /* Try to create a new file, with 0644 mode */
223         fd = open(lock_file, O_CREAT | O_EXCL, 0644);
224         if (fd == -1) {
225                 free(lock_file);
226                 fprintf(stderr, _("Cannot lock device\n"));
227                 return NULL;
228         }
229         sprintf(buffer, "%10ld gnokii\n", (long)getpid());
230         write(fd, buffer, strlen(buffer));
231         close(fd);
232         return lock_file;
233 }
234
235 /* Removes lock and frees memory */
236 static bool unlock_device(char *lock_file)
237 {
238         int err;
239
240         if (!lock_file) {
241                 fprintf(stderr, _("Cannot unlock device\n"));
242                 return false;
243         }
244         err = unlink(lock_file);
245         free(lock_file);
246         return (err + 1);
247 }
248
249 #endif /* UCLINUX */
250
251 #endif /* WIN32 */