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