Tizen 2.1 base
[platform/upstream/hplip.git] / pcard / ptest.c
1 /*****************************************************************************\
2
3   ptest.c - HP MFP photo card file manager
4  
5   (c) 2004 Copyright Hewlett-Packard Development Company, LP
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 2 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program; if not, write to the Free Software
19   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
20
21 \*****************************************************************************/
22
23 #include <sys/stat.h>
24 #include <sys/socket.h>
25 #include <sys/ioctl.h>
26 #include <sys/types.h>
27 #include <netinet/in.h>
28 #include <netdb.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <fcntl.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <syslog.h>
35 #include <stdarg.h>
36 #include <signal.h>
37 #include <arpa/inet.h>
38 #include <errno.h>
39 #include <ctype.h>
40 #include "ptest.h"
41 #include "fat.h"
42 #include "hpmud.h"
43
44 #define EXCEPTION_TIMEOUT 45 /* seconds */
45 #define DEV_ACK 0x0100
46
47 typedef struct
48 {
49    short cmd;
50    unsigned short nsector;
51 } __attribute__((packed)) CMD_READ_REQUEST;
52
53 typedef struct{
54    short cmd;
55    unsigned short nsector;
56    short cs;         /* check sum is not used */
57 } __attribute__((packed)) CMD_WRITE_REQUEST;
58
59 typedef struct
60 {
61    short cmd;
62    uint32_t nsector;
63    short ver;
64 } __attribute__((packed)) RESPONSE_SECTOR;
65
66 static int hd=-1, channel=-1;
67
68 int verbose=0;
69  
70 int bug(const char *fmt, ...)
71 {
72    char buf[256];
73    va_list args;
74    int n;
75
76    va_start(args, fmt);
77
78    if ((n = vsnprintf(buf, 256, fmt, args)) == -1)
79       buf[255] = 0;     /* output was truncated */
80
81    fprintf(stderr, "%s", buf);
82    syslog(LOG_WARNING, "%s", buf);
83
84    fflush(stderr);
85    va_end(args);
86    return n;
87 }
88
89 int last_slash(const char *path, int *number_found, int *path_size)
90 {
91    int i, found=0, lasti=0;
92
93    /* Find last '/'. */
94    for (i=0; path[i] && i<HPMUD_LINE_SIZE; i++)
95       if (path[i] == '/')
96       {
97          found++;
98          lasti=i;
99       }
100
101    *number_found = found;
102    *path_size = i;
103
104    return lasti;
105
106
107 int nth_slash(const char *path, int n)
108 {
109    int i, found=0, lasti=0;
110
111    /* Find nth '/'. */
112    for (i=0; path[i] && i<HPMUD_LINE_SIZE; i++)
113       if (path[i] == '/')
114       {
115          found++;
116          lasti=i;
117          if (found == n)
118            break;
119       }
120
121    return lasti;
122
123
124 char *basename(const char *path)
125 {
126    int len, found=0, slash_index=0;
127
128    slash_index = last_slash(path, &found, &len);
129    return found ? (char *)path+slash_index+1 : (char *)path; 
130 }
131
132 int dirname(const char *path, char *dir)
133 {
134    int len, found=0, slash_index=0;
135
136    slash_index = last_slash(path, &found, &len);
137
138    if (found == 0)
139       strcpy(dir, ".");              /* no '/' */
140    else if (path[slash_index+1]==0 && found==1)
141       strcpy(dir, "/");              /* '/' only */
142    else if (path[slash_index+1]==0 && found>1)
143    {
144       slash_index = nth_slash(path, found-1);   /* trailing '/', backup */
145       strncpy(dir, path, slash_index);
146       dir[slash_index]=0;
147    }
148    else
149    {
150       strncpy(dir, path, slash_index);      /* normal '/' */
151       dir[slash_index]=0;
152    }
153    return slash_index;  /* return length of dir */
154 }
155
156 int GetDir(char *path, char *dir, char **tail)
157 {
158    int i=0;
159
160    dir[0] = 0;
161
162    if (path[0] == 0)
163    {
164       strcpy(dir, ".");   /* end of path */
165       i = 0;
166    }
167    else if ((path[0] == '/') && (*tail != path))
168    {
169       strcpy(dir, "/");          /* found root '/' at beginning of path */
170       i=1;
171    }                 
172    else
173    {
174       for (i=0; path[i] && (path[i] != '/') && (i<HPMUD_LINE_SIZE); i++)   /* copy directory entry */
175          dir[i] = path[i];
176       if (i==0)
177          strcpy(dir, ".");   /* end of path */
178       else
179          dir[i] = 0;
180       if (path[i] == '/')
181          i++;  /* bump past '/' */
182    }
183
184    if (tail != NULL)
185       *tail = path + i;  /* tail points to next directory or 0 */
186
187    return i;
188 }
189
190 int get_uri(char *uri, int urisize)
191 {
192    char buf[HPMUD_LINE_SIZE*64];  
193    int i=0, cnt, bytes_read;  
194    char *pBeg;
195  
196    uri[0] = 0;
197
198    hpmud_probe_devices(HPMUD_BUS_USB, buf, sizeof(buf), &cnt, &bytes_read);
199
200    /* Return first uri in list. */
201    if (cnt > 0)
202    {
203       pBeg = strstr(buf, "hp:");
204       for (i=0; *pBeg != ' ' && (i < urisize); i++, pBeg++)  /* copy uri */
205          uri[i] = *pBeg;
206       uri[i] = 0;      /* zero terminate */
207    }
208
209    return i;
210 }
211
212 int ReadSector(int sector, int nsector, void *buf, int size)
213 {
214    char message[HPMUD_BUFFER_SIZE];
215    int i, len, rlen, wlen, stat=1, total=0;
216    CMD_READ_REQUEST *pC;
217    RESPONSE_SECTOR *pR;
218    uint32_t *pSect;
219    short cmd=0x0010;  /* read request */
220    
221    if (nsector <= 0 || (nsector*FAT_HARDSECT) > size)
222    {
223       bug("ReadSector invalid sector count=%d\n", nsector);
224       goto bugout;
225    }
226       
227    /* Write photo card command to device. */
228    pC = (CMD_READ_REQUEST *)message;
229    pC->cmd = htons(cmd);
230    pC->nsector = htons(nsector);
231    pSect = (uint32_t *)(message + sizeof(CMD_READ_REQUEST));
232    for (i=0; i<nsector; i++)
233      *pSect++ = htonl(sector+i);
234    wlen = sizeof(CMD_READ_REQUEST)+(4*nsector);
235    hpmud_write_channel(hd, channel, message, wlen, EXCEPTION_TIMEOUT, &len);
236
237    /* Read photo card response header from device. */
238    memset(message, 0, sizeof(RESPONSE_SECTOR));
239    rlen = sizeof(RESPONSE_SECTOR);
240    hpmud_read_channel(hd, channel, message, rlen, EXCEPTION_TIMEOUT, &len); 
241    pR = (RESPONSE_SECTOR *)message;
242    if (ntohs(pR->cmd) != (cmd | DEV_ACK))
243    {
244       bug("ReadSector invalid response header cmd=%x expected=%x\n", ntohs(pR->cmd), cmd | DEV_ACK);
245       goto bugout;
246    }      
247
248    if (verbose > 0)
249    {
250       static int cnt=0;
251       if (cnt++ < 1)
252          fprintf(stderr, "photo card firmware version=%x\n", ntohs(pR->ver));   
253    }
254
255    /* Read photo card sector data from device. */
256    rlen = nsector*FAT_HARDSECT;
257    while (total < rlen)
258    { 
259       hpmud_read_channel(hd, channel, buf+total, rlen, EXCEPTION_TIMEOUT, &len);
260       if (len == 0)
261          break;  /* timeout */
262       total+=len;
263    }
264
265    if (total != rlen)
266    {
267       bug("ReadSector invalid response data len=%d expected=%d\n", total, rlen);
268       goto bugout;
269    }      
270
271    stat = 0;
272
273 bugout:
274    return stat;    
275 }
276
277 int WriteSector(int sector, int nsector, void *buf, int size)
278 {
279    char message[HPMUD_BUFFER_SIZE];
280    int i, len, wlen, stat=1;
281    CMD_WRITE_REQUEST *pC;
282    uint32_t *pSect;
283    short response=0, cmd=0x0020;  /* write request */
284
285    if (nsector <= 0 || (nsector*FAT_HARDSECT) > size)
286    {
287       bug("WriteSector invalid sector count=%d\n", nsector);
288       goto bugout;
289    }
290       
291    /* Write photo card command header to device. */
292    pC = (CMD_WRITE_REQUEST *)message;
293    pC->cmd = htons(cmd);
294    pC->nsector = htons(nsector);
295    pC->cs = 0;
296    pSect = (uint32_t *)(message + sizeof(CMD_WRITE_REQUEST));
297    for (i=0; i<nsector; i++)
298      *pSect++ = htonl(sector+i);
299    wlen = sizeof(CMD_WRITE_REQUEST)+(4*nsector);
300    hpmud_write_channel(hd, channel, message, wlen, EXCEPTION_TIMEOUT, &len);
301
302    /* Write photo card sector data to device. */
303    hpmud_write_channel(hd, channel, buf, size, EXCEPTION_TIMEOUT, &len);
304
305    /* Read response. */
306    hpmud_read_channel(hd, channel, &response, sizeof(response), EXCEPTION_TIMEOUT, &len); 
307    if (ntohs(response) != DEV_ACK)
308    {
309       bug("WriteSector invalid response cmd=%x expected=%x\n", ntohs(response), DEV_ACK);
310       goto bugout;
311    }      
312    stat = 0;
313
314 bugout:
315    return stat;    
316 }
317
318 void usage()
319 {
320    fprintf(stdout, "HP MFP Photo Card File Manager %s\n", VERSION);
321    fprintf(stdout, "(c) 2004-2007 Copyright Hewlett-Packard Development Company, LP\n");
322    fprintf(stdout, "usage: ptest [-v] [-u uri] -c ls [-p path]  (list directory)\n");
323    fprintf(stdout, "       ptest [-v] [-u uri] -c read -p path  (read file to stdout)\n");
324    fprintf(stdout, "       ptest [-v] [-u uri] -c rm -p path    (delete file)\n");
325    //   fprintf(stdout, "       ptest [-v] -u uri -c write -p path   (write stdin to file)\n");
326 }
327
328 int main(int argc, char *argv[])
329 {
330    char cmd[16] = "", path[HPMUD_LINE_SIZE]="", uri[HPMUD_LINE_SIZE]="", dir[HPMUD_LINE_SIZE]="", spath[HPMUD_LINE_SIZE]="";
331    extern char *optarg;
332    char *tail;
333    int i, stat=-1;
334    PHOTO_CARD_ATTRIBUTES pa;
335    struct hpmud_model_attributes ma;
336
337    while ((i = getopt(argc, argv, "vhu:c:p:")) != -1)
338    {
339       switch (i)
340       {
341       case 'c':
342          strncpy(cmd, optarg, sizeof(cmd));
343          break;
344       case 'p':
345          strncpy(path, optarg, sizeof(path));
346          break;
347       case 'u':
348          strncpy(uri, optarg, sizeof(uri));
349          break;
350       case 'v':
351          verbose++;
352          break;
353       case 'h':
354          usage();
355          exit(0);
356       case '?':
357          usage();
358          fprintf(stderr, "unknown argument: %s\n", argv[1]);
359          exit(-1);
360       default:
361          break;
362       }
363    }
364
365    if (uri[0] == 0)
366       get_uri(uri, sizeof(uri));
367    if (uri[0] == 0)
368    {
369       bug("no uri found\n");
370       goto bugout;
371    }   
372
373    /* Get any parameters needed for DeviceOpen. */
374    hpmud_query_model(uri, &ma);  
375
376    if (hpmud_open_device(uri, ma.mfp_mode, &hd) != HPMUD_R_OK)
377    {
378       bug("unable to open device %s\n", uri);
379       goto bugout;
380    }   
381    if (hpmud_open_channel(hd, "HP-CARD-ACCESS", &channel) != HPMUD_R_OK)
382    {
383       bug("unable to open hp-card-access channel %s\n", uri);
384       goto bugout;
385    }
386
387    if (FatInit() != 0)
388    {
389       bug("unable to read photo card %s\n", uri);
390       goto bugout;
391    }
392
393    FatDiskAttributes(&pa);
394
395    /* If disk is write protected reopen channel to clear write error. */
396    if (pa.WriteProtect)
397    {
398       hpmud_close_channel(hd, channel);
399       if (hpmud_open_channel(hd, "HP-CARD-ACCESS", &channel) != HPMUD_R_OK)
400       {
401          bug("unable to open hp-card-access channel %s\n", uri);
402          goto bugout;
403       }
404    }
405
406    if (strcasecmp(cmd, "ls") == 0)
407    {
408       /* Walk the path for each directory entry. */
409       GetDir(path, dir, &tail);
410       FatSetCWD(dir);
411       while (tail[0] != 0)
412       {
413          GetDir(tail, dir, &tail);
414          FatSetCWD(dir);
415       }
416       FatListDir();
417    }
418    else if (strcasecmp(cmd, "read") == 0)
419    {
420       dirname(path, spath);       /* extract directory */
421       GetDir(spath, dir, &tail);
422       FatSetCWD(dir);
423       while (tail[0] != 0)
424       {
425          GetDir(tail, dir, &tail);
426          FatSetCWD(dir);
427       }    
428       if ((FatReadFile(basename(path), STDOUT_FILENO)) <= 0)
429       {
430          bug("unable to locate file %s\n", path);
431          goto bugout;
432       }
433    }
434    else if (strcasecmp(cmd, "rm") == 0)
435    {
436       dirname(path, spath);       /* extract directory */
437       GetDir(spath, dir, &tail);
438       FatSetCWD(dir);
439       while (tail[0] != 0)
440       {
441          GetDir(tail, dir, &tail);
442          FatSetCWD(dir);
443       }    
444       if (FatDeleteFile(basename(path)) != 0)
445       {
446          bug("unable to locate file %s\n", path);
447          goto bugout;
448       }
449    }
450    else
451    {
452       usage();  /* invalid command */
453       goto bugout;
454    }   
455
456    stat = 0;
457
458 bugout:
459    if (channel >= 0)
460       hpmud_close_channel(hd, channel);
461    if (hd >= 0)
462       hpmud_close_device(hd);   
463
464    exit (stat);
465 }
466