tandem.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890
  1. /*
  2. Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
  3. See the accompanying file LICENSE, version 2000-Apr-09 or later
  4. (the contents of which are also included in zip.h) for terms of use.
  5. If, for some reason, all these files are missing, the Info-ZIP license
  6. also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
  7. */
  8. /*
  9. * routines common to TANDEM (ZIP and UNZIP)
  10. */
  11. #include "zip.h" /* This sets up ZIP / UNZIP define */
  12. #include <tal.h>
  13. #include "$system.zsysdefs.zsysc" nolist
  14. #include <cextdecs> nolist
  15. #include "tannsk.h"
  16. static time_t gmt_to_time_t (long long *);
  17. int isatty (fnum)
  18. int fnum;
  19. {
  20. return 1;
  21. }
  22. /********************/
  23. /* Function in2ex() */
  24. /********************/
  25. #ifdef UNZIP
  26. char *in2ex(__G__ n)
  27. __GDEF
  28. #else
  29. char *in2ex(n)
  30. #endif
  31. char *n; /* internal file name */
  32. /* Convert the zip file name to an external file name, returning the malloc'ed
  33. string or NULL if not enough memory. */
  34. {
  35. char *x; /* external file name buffer */
  36. char *y; /* pointer to external buffer */
  37. char *max; /* pointer to max end of next file part */
  38. char *t; /* pointer to internal - start of substring */
  39. char *p; /* pointer to internal - TANDEM delimiter */
  40. char *e; /* pointer to internal - DOS extension delimiter */
  41. char *z; /* pointer to internal - end of substring */
  42. int len; /* length of substring to copy to external name */
  43. int allow_dollar; /* $ symbol allowed as next character */
  44. if ((x = malloc(strlen(n) + 4)) == NULL) /* + 4 for safety */
  45. return NULL;
  46. *x = '\0';
  47. /* Junk pathname as requested */
  48. #ifdef UNZIP
  49. if (uO.jflag && (t = strrchr(n, INTERNAL_DELIMITER)) != NULL)
  50. ++t;
  51. else
  52. t = n;
  53. #endif /* UNZIP */
  54. #ifdef ZIP
  55. if (!pathput)
  56. t = last(n, INTERNAL_DELIMITER);
  57. else
  58. t = n;
  59. #endif /* ZIP */
  60. allow_dollar = TRUE;
  61. while (*t != '\0') { /* File part could be sys, vol, subvol or file */
  62. if (*t == INTERNAL_DELIMITER) { /* System, Volume or Subvol Name */
  63. t++;
  64. if (*t == INTERNAL_DELIMITER) { /* System */
  65. strcat(x, TANDEM_NODE_STR);
  66. t++;
  67. }
  68. else {
  69. strcat(x, TANDEM_DELIMITER_STR);
  70. allow_dollar = FALSE;
  71. }
  72. }
  73. /* Work out where end of current external string is */
  74. y = x + strlen(x);
  75. /* Work out substring to copy and externalise */
  76. p = strchr(t, INTERNAL_DELIMITER);
  77. e = strchr(t, DOS_EXTENSION);
  78. if (p != NULL) {
  79. if (e > p)
  80. e = NULL;
  81. }
  82. z = e;
  83. if (z == NULL)
  84. z = p;
  85. if (z == NULL)
  86. z = t + strlen(t);
  87. /* can't have Tandem name longer than 8 characters */
  88. max = y + MAXFILEPARTLEN;
  89. /* Allow $ symbol as first character in some cases */
  90. if (*t == '$') {
  91. if (allow_dollar)
  92. *y++ = *t++;
  93. else;
  94. *t++;
  95. }
  96. /* Make sure first real character is alpha */
  97. if (! isalpha(*t) )
  98. *y++ = 'A';
  99. /* Characters left to process */
  100. len = z - t;
  101. while ( len > 0 ) {
  102. if ( isalnum(*t) ) {
  103. *y++ = toupper(*t++);
  104. if (y >= max)
  105. break;
  106. }
  107. else
  108. t++;
  109. len--;
  110. }
  111. *y = '\0';
  112. t = p;
  113. if (p == NULL) {
  114. /* Last part of filename, store pseudo extension if available */
  115. if (e != NULL) {
  116. strcat(x, TANDEM_EXTENSION_STR);
  117. y = x + strlen(x);
  118. /* no restriction on extension length as its virtual */
  119. z = e + 1;
  120. while ( *z != '\0' ) {
  121. *y++ = toupper(*z++);
  122. }
  123. *y = '\0';
  124. }
  125. break;
  126. }
  127. }
  128. return x;
  129. }
  130. void zexit(status)
  131. int status;
  132. {
  133. /* Exit(>0) creates saveabend files */
  134. terminate_program (0,0,(short)status,,,);
  135. }
  136. /************************/
  137. /* Function zputc() */
  138. /************************/
  139. #ifdef putc
  140. # undef putc
  141. #endif
  142. int zputc(ch, fptr)
  143. int ch;
  144. FILE *fptr;
  145. {
  146. int err;
  147. err = putc(ch,fptr);
  148. fflush(fptr);
  149. return err;
  150. }
  151. #define putc zputc
  152. #ifdef LICENSED
  153. _tal _priv short FILE_CHANGELABEL_ (
  154. short, /* IN */
  155. short, /* IN */
  156. const short _far * /* IN */
  157. );
  158. _c _callable int changelabel OF((short, const short *, const short *));
  159. _c _callable int changelabel(fnum, modtime, actime)
  160. short fnum;
  161. const short *modtime;
  162. const short *actime;
  163. {
  164. int err;
  165. err = FILE_CHANGELABEL_(fnum, 16, modtime);
  166. if (!err)
  167. err = FILE_CHANGELABEL_(fnum, 17, actime);
  168. return err;
  169. }
  170. int islicensed(void)
  171. {
  172. #define plist_items 1
  173. #define plist_size 10
  174. short myphandle[ZSYS_VAL_PHANDLE_WLEN];
  175. short licensetag[plist_items] = {37};
  176. short licensed[plist_size];
  177. short maxlen = plist_size;
  178. short items = plist_items;
  179. short resultlen[1], err;
  180. err = PROCESSHANDLE_NULLIT_(myphandle);
  181. if (!err)
  182. err = PROCESS_GETINFO_(myphandle);
  183. if (!err)
  184. err = PROCESS_GETINFOLIST_(/*cpu*/,
  185. /*pin*/,
  186. /*nodename*/,
  187. /*nodenamelen*/,
  188. myphandle,
  189. licensetag,
  190. items,
  191. licensed,
  192. maxlen,
  193. resultlen
  194. );
  195. if (err != 0)
  196. return 0;
  197. else
  198. return licensed[0];
  199. }
  200. #endif /* LICENSED */
  201. int utime(file, time)
  202. const char *file;
  203. const ztimbuf *time;
  204. {
  205. #ifdef LICENSED
  206. int result, err;
  207. union timestamp_ov {
  208. long long fulltime;
  209. short wordtime[4];
  210. };
  211. union timestamp_ov lasttime, opentime;
  212. struct tm *modt, *opent;
  213. short datetime[8], errormask[1];
  214. short len, fnum, access, exclus, options;
  215. char fname[FILENAME_MAX + 1];
  216. short extension;
  217. char ext[EXTENSION_MAX + 1];
  218. if (islicensed() ) {
  219. /* Attempt to update file label */
  220. modt = gmtime( &time->modtime );
  221. datetime[0] = modt->tm_year + 1900;
  222. datetime[1] = modt->tm_mon + 1;
  223. datetime[2] = modt->tm_mday;
  224. datetime[3] = modt->tm_hour;
  225. datetime[4] = modt->tm_min;
  226. datetime[5] = modt->tm_sec;
  227. datetime[6] = datetime[7] = 0;
  228. errormask[0] = 0;
  229. lasttime.fulltime = COMPUTETIMESTAMP (datetime, errormask);
  230. opent = gmtime( &time->actime );
  231. datetime[0] = opent->tm_year + 1900;
  232. datetime[1] = opent->tm_mon + 1;
  233. datetime[2] = opent->tm_mday;
  234. datetime[3] = opent->tm_hour;
  235. datetime[4] = opent->tm_min;
  236. datetime[5] = opent->tm_sec;
  237. datetime[6] = datetime[7] = 0;
  238. errormask[0] = 0;
  239. opentime.fulltime = COMPUTETIMESTAMP (datetime, errormask);
  240. /* Remove any (pseudo) file extension */
  241. extension = parsename (file,fname,ext);
  242. len = strlen(fname);
  243. access = NSK_WRONLY;
  244. exclus = NSK_SHARED;
  245. options = NSK_NOUPDATEOPENTIME;
  246. extension = parsename (file,fname,ext);
  247. len = strlen(fname);
  248. err = FILE_OPEN_((char *)fname, len, &fnum, access, exclus,,,options,,,);
  249. result = changelabel(fnum,lasttime.wordtime,opentime.wordtime);
  250. err = FILE_CLOSE_(fnum);
  251. return result;
  252. }
  253. return -1;
  254. #else /* !LICENSED */
  255. return 0; /* "no error", to suppress annoying failure messages */
  256. #endif /* ?LICENSED */
  257. }
  258. /* TANDEM version of chmod() function */
  259. int chmod(file, unix_sec)
  260. const char *file;
  261. mode_t unix_sec;
  262. {
  263. FILE *stream;
  264. struct nsk_sec_type {
  265. unsigned progid : 1;
  266. unsigned clear : 1;
  267. unsigned null : 2;
  268. unsigned read : 3;
  269. unsigned write : 3;
  270. unsigned execute: 3;
  271. unsigned purge : 3;
  272. };
  273. union nsk_sec_ov {
  274. struct nsk_sec_type bit_ov;
  275. short int_ov;
  276. };
  277. union nsk_sec_ov nsk_sec;
  278. short fnum, err, nsk_sec_int;
  279. short len, access, exclus, extension, options;
  280. char fname[FILENAME_MAX + 1];
  281. char ext[EXTENSION_MAX + 1];
  282. nsk_sec.bit_ov.progid = 0;
  283. nsk_sec.bit_ov.clear = 0;
  284. nsk_sec.bit_ov.null = 0;
  285. /* 4="N", 5="C", 6="U", 7="-" */
  286. if (unix_sec & S_IROTH) nsk_sec.bit_ov.read = 4;
  287. else if (unix_sec & S_IRGRP) nsk_sec.bit_ov.read = 5;
  288. else if (unix_sec & S_IRUSR) nsk_sec.bit_ov.read = 6;
  289. else nsk_sec.bit_ov.read = 7;
  290. if (unix_sec & S_IWOTH) nsk_sec.bit_ov.write = 4;
  291. else if (unix_sec & S_IWGRP) nsk_sec.bit_ov.write = 5;
  292. else if (unix_sec & S_IWUSR) nsk_sec.bit_ov.write = 6;
  293. else nsk_sec.bit_ov.write = 7;
  294. if (unix_sec & S_IXOTH) nsk_sec.bit_ov.execute = 4;
  295. else if (unix_sec & S_IXGRP) nsk_sec.bit_ov.execute = 5;
  296. else if (unix_sec & S_IXUSR) nsk_sec.bit_ov.execute = 6;
  297. else nsk_sec.bit_ov.execute = 7;
  298. nsk_sec.bit_ov.purge = nsk_sec.bit_ov.write;
  299. nsk_sec_int = nsk_sec.int_ov;
  300. access = NSK_RDONLY;
  301. exclus = NSK_SHARED;
  302. options = NSK_NOUPDATEOPENTIME;
  303. extension = parsename (file,fname,ext);
  304. len = strlen(fname);
  305. err = FILE_OPEN_((char *)fname, len, &fnum, access, exclus,,,options,,,);
  306. err = (SETMODE(fnum, SET_FILE_SECURITY, nsk_sec_int) != CCE);
  307. err = FILE_CLOSE_(fnum);
  308. return (err != 0 ? -1 : 0);
  309. }
  310. /* TANDEM version of chown() function */
  311. int chown(file, uid, gid)
  312. const char *file;
  313. uid_t uid;
  314. gid_t gid;
  315. {
  316. FILE *stream;
  317. struct nsk_own_type {
  318. unsigned group : 8;
  319. unsigned user : 8;
  320. };
  321. union nsk_own_ov {
  322. struct nsk_own_type bit_ov;
  323. short int_ov;
  324. };
  325. union nsk_own_ov nsk_own;
  326. short fnum, err, nsk_own_int;
  327. short len, access, exclus, extension, options;
  328. char fname[FILENAME_MAX + 1];
  329. char ext[EXTENSION_MAX + 1];
  330. nsk_own.bit_ov.group = gid;
  331. nsk_own.bit_ov.user = uid;
  332. nsk_own_int = nsk_own.int_ov;
  333. access = NSK_RDONLY;
  334. exclus = NSK_SHARED;
  335. options = NSK_NOUPDATEOPENTIME;
  336. extension = parsename (file,fname,ext);
  337. len = strlen(fname);
  338. err = FILE_OPEN_((char *)fname, len, &fnum, access, exclus,,,options,,,);
  339. err = (SETMODE(fnum, SET_FILE_OWNER, nsk_own_int) != CCE);
  340. err = FILE_CLOSE_(fnum);
  341. return (err != 0 ? -1 : 0);
  342. }
  343. /* TANDEM version of getch() - non-echo character reading */
  344. int zgetch(void)
  345. {
  346. char ch;
  347. short f, err, count, fnum, rlen;
  348. rlen = 1;
  349. f = (short)fileno(stdin);
  350. fnum = fdtogfn (f);
  351. #define ECHO_MODE 20
  352. err = (SETMODE(fnum, ECHO_MODE, 0) != CCE);
  353. err = (READX(fnum, &ch, rlen, (short *) &count) != CCE);
  354. err = (SETMODE(fnum, ECHO_MODE, 1) != CCE);
  355. if (err)
  356. if (err != 1)
  357. return EOF;
  358. else
  359. ch = 'q';
  360. else
  361. if (count == 0)
  362. ch = '\r';
  363. return (int)ch;
  364. }
  365. short parsename(srce, fname, ext)
  366. const char *srce;
  367. char *fname;
  368. char *ext;
  369. {
  370. /* As a way of supporting DOS extensions from Tandem we look for a space
  371. separated extension string after the Guardian filename
  372. e.g. ZIP ZIPFILE "$DATA4.TESTING.INVOICE TXT"
  373. */
  374. char *fstart;
  375. char *fptr;
  376. short extension = 0;
  377. *fname = *ext = '\0'; /* set to null string */
  378. fstart = (char *) srce;
  379. if ((fptr = strrchr(fstart, TANDEM_EXTENSION)) != NULL) {
  380. extension = 1;
  381. fptr++;
  382. strncat(ext, fptr, _min(EXTENSION_MAX, strlen(fptr)));
  383. fptr = strchr(fstart, TANDEM_EXTENSION); /* End of filename */
  384. strncat(fname, fstart, _min(FILENAME_MAX, (fptr - fstart)));
  385. }
  386. else {
  387. /* just copy string */
  388. strncat(fname, srce, _min(FILENAME_MAX, strlen(srce)));
  389. }
  390. return extension;
  391. }
  392. static time_t gmt_to_time_t (gmt)
  393. long long *gmt;
  394. {
  395. #define GMT_TO_LCT 0
  396. #define GMT_TO_LST 1
  397. struct tm temp_tm;
  398. short date_time[8];
  399. long julian_dayno;
  400. long long lct, lst, itime;
  401. short err[1], type;
  402. type = GMT_TO_LCT;
  403. lct = CONVERTTIMESTAMP(*gmt, type,, err);
  404. if (!err[0]) {
  405. type = GMT_TO_LST;
  406. lst = CONVERTTIMESTAMP(*gmt, type,, err);
  407. }
  408. itime = (err[0] ? *gmt : lct);
  409. /* If we have no DST in force then make sure we give it a value,
  410. else mktime screws up if we set the isdst flag to -1 */
  411. temp_tm.tm_isdst = (err[0] ? 0 : ((lct == lst) ? 0 : 1));
  412. julian_dayno = INTERPRETTIMESTAMP(itime, date_time);
  413. temp_tm.tm_sec = date_time[5];
  414. temp_tm.tm_min = date_time[4];
  415. temp_tm.tm_hour = date_time[3];
  416. temp_tm.tm_mday = date_time[2];
  417. temp_tm.tm_mon = date_time[1] - 1; /* C's so sad */
  418. temp_tm.tm_year = date_time[0] - 1900; /* it's almost funny */
  419. return (mktime(&temp_tm));
  420. }
  421. /* TANDEM version of stat() function */
  422. int stat(n, s)
  423. const char *n;
  424. struct stat *s;
  425. {
  426. #define ilist_items 26
  427. #define klist_items 4
  428. #define slist_items 3
  429. #define ulist_items 1
  430. #define flist_size 100
  431. short err, i, extension;
  432. char fname[FILENAME_MAX + 1];
  433. short fnamelen;
  434. char ext[EXTENSION_MAX + 1];
  435. /* #0 #1 #2 #3 #4 #5 #6 #7 #8 #9 */
  436. short ilist[ilist_items]={56,144, 54,142, 58, 62, 60, 41, 42, 44,
  437. 50, 51, 52, 61, 63, 66, 67, 70, 72, 73,
  438. 74, 75, 76, 77, 78, 79 };
  439. short ilen[ilist_items] ={ 4, 4, 4, 2, 1, 2, 1, 1, 1, 1,
  440. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  441. 1, 1, 1, 1, 1, 1 };
  442. short ioff[ilist_items];
  443. /* #0 #1 #2 #3 #4 #5 #6 #7 #8 #9 */
  444. short klist[klist_items]={45, 46, 68, 69 };
  445. short klen[klist_items] ={ 1, 1, 1, 1 };
  446. short koff[klist_items];
  447. /* #0 #1 #2 #3 #4 #5 #6 #7 #8 #9 */
  448. short slist[slist_items]={43, 80, 90 };
  449. short slen[slist_items] ={ 1, 1, 1 };
  450. short soff[slist_items];
  451. /* #0 #1 #2 #3 #4 #5 #6 #7 #8 #9 */
  452. short ulist[ulist_items]={65 };
  453. short ulen[ulist_items] ={ 1 };
  454. short uoff[ulist_items];
  455. short flist[flist_size];
  456. short extra[2];
  457. short *rlen=&extra[0];
  458. short *err_item=&extra[1];
  459. unsigned short *fowner;
  460. unsigned short *fprogid;
  461. char *fsec;
  462. nsk_stat_ov *nsk_ov;
  463. nsk_file_attrs *nsk_attr;
  464. short end, count, kind, level, options, searchid;
  465. short info[5];
  466. /* Initialise stat structure */
  467. s->st_dev = _S_GUARDIANOBJECT;
  468. s->st_ino = 0;
  469. s->st_nlink = 0;
  470. s->st_rdev = 0;
  471. s->st_uid = s->st_gid = 0;
  472. s->st_size = 0;
  473. s->st_atime = s->st_ctime = s->st_mtime = 0;
  474. s->st_reserved[0] = 0;
  475. s->st_reserved[1] = 0;
  476. s->st_reserved[2] = 0;
  477. nsk_ov = (nsk_stat_ov *)&s->st_reserved[0];
  478. nsk_attr = (nsk_file_attrs *)&nsk_ov->ov.nsk_ef_region;
  479. /* Check to see if name contains a (pseudo) file extension */
  480. extension = parsename (n,fname,ext);
  481. fnamelen = strlen(fname);
  482. options = 3; /* Allow Subvols and Templates */
  483. err = FILENAME_SCAN_( fname,
  484. fnamelen,
  485. &count,
  486. &kind,
  487. &level,
  488. options
  489. );
  490. /* allow kind == 2 (DEFINE names) */
  491. if (err != 0) return -1;
  492. if (kind == 1 || (kind == 0 && level < 2)) {
  493. /* Pattern, Subvol Name or One part Filename - lets see if it exists */
  494. err = FILENAME_FINDSTART_ ( &searchid,
  495. fname,
  496. fnamelen,
  497. ,
  498. DISK_DEVICE
  499. );
  500. if (err != 0) {
  501. end = FILENAME_FINDFINISH_ ( searchid );
  502. return -1;
  503. }
  504. err = FILENAME_FINDNEXT_ ( searchid,
  505. fname,
  506. FILENAME_MAX,
  507. &fnamelen,
  508. info
  509. );
  510. end = FILENAME_FINDFINISH_ ( searchid );
  511. if (err != 0)
  512. return -1; /* Non existing template, subvol or file */
  513. if (kind == 1 || info[2] == -1) {
  514. s->st_mode = S_IFDIR; /* Its an existing template or directory */
  515. return 0;
  516. }
  517. /* Must be a real file so drop to code below to get info on it */
  518. }
  519. err = FILE_GETINFOLISTBYNAME_( fname,
  520. fnamelen,
  521. ilist,
  522. ilist_items,
  523. flist,
  524. flist_size,
  525. rlen,
  526. err_item
  527. );
  528. if (err != 0) return -1;
  529. ioff[0] = 0;
  530. /* Build up table of offets into result list */
  531. for (i=1; i < ilist_items; i++)
  532. ioff[i] = ioff[i-1] + ilen[i-1];
  533. /* Set up main stat fields */
  534. /* Setup timestamps */
  535. s->st_atime = gmt_to_time_t ((long long *)&flist[ioff[0]]);
  536. s->st_mtime = s->st_ctime = gmt_to_time_t ((long long *)&flist[ioff[1]]);
  537. nsk_ov->ov.creation_time = gmt_to_time_t ((long long *)&flist[ioff[2]]);
  538. s->st_size = *(off_t *)&flist[ioff[3]];
  539. fowner = (unsigned short *)&flist[ioff[4]];
  540. s->st_uid = *fowner & 0x00ff;
  541. s->st_gid = *fowner >> 8;
  542. /* Note that Purge security (fsec[3]) in NSK has no relevance to stat() */
  543. fsec = (char *)&flist[ioff[5]];
  544. fprogid = (unsigned short *)&flist[ioff[6]];
  545. s->st_mode = S_IFREG | /* Regular File */
  546. /* Parse Read Flag */
  547. ((fsec[0] & 0x03) == 0x00 ? S_IROTH : 0) |
  548. ((fsec[0] & 0x02) == 0x00 ? S_IRGRP : 0) |
  549. ((fsec[0] & 0x03) != 0x03 ? S_IRUSR : 0) |
  550. /* Parse Write Flag */
  551. ((fsec[1] & 0x03) == 0x00 ? S_IWOTH : 0) |
  552. ((fsec[1] & 0x02) == 0x00 ? S_IWGRP : 0) |
  553. ((fsec[1] & 0x03) != 0x03 ? S_IWUSR : 0) |
  554. /* Parse Execute Flag */
  555. ((fsec[2] & 0x03) == 0x00 ? S_IXOTH : 0) |
  556. ((fsec[2] & 0x02) == 0x00 ? S_IXGRP : 0) |
  557. ((fsec[2] & 0x03) != 0x03 ? S_IXUSR : 0) |
  558. /* Parse Progid */
  559. (*fprogid == 1 ? (S_ISUID | S_ISGID) : 0) ;
  560. /* Set up NSK additional stat fields */
  561. nsk_attr->progid = (unsigned) flist[ioff[6]];
  562. nsk_attr->filetype = (unsigned) flist[ioff[7]];
  563. nsk_attr->filecode = (unsigned) flist[ioff[8]];
  564. nsk_attr->block = (unsigned short) flist[ioff[9]];
  565. nsk_attr->priext = (unsigned short) flist[ioff[10]];
  566. nsk_attr->secext = (unsigned short) flist[ioff[11]];
  567. nsk_attr->maxext = (unsigned short) flist[ioff[12]];
  568. nsk_attr->flags.clearonpurge = (unsigned) flist[ioff[13]];
  569. nsk_attr->licensed = (unsigned) flist[ioff[14]];
  570. nsk_attr->flags.audited = (unsigned) flist[ioff[15]];
  571. nsk_attr->flags.acompress = (unsigned) flist[ioff[16]];
  572. nsk_attr->flags.refresheof = (unsigned) flist[ioff[17]];
  573. nsk_attr->flags.buffered = (unsigned) (flist[ioff[18]] == 0 ? 1 : 0);
  574. nsk_attr->flags.verified = (unsigned) flist[ioff[19]];
  575. nsk_attr->flags.serial = (unsigned) flist[ioff[20]];
  576. nsk_attr->flags.crashopen = (unsigned) flist[ioff[22]];
  577. nsk_attr->flags.rollforward = (unsigned) flist[ioff[23]];
  578. nsk_attr->flags.broken = (unsigned) flist[ioff[24]];
  579. nsk_attr->flags.corrupt = (unsigned) flist[ioff[25]];
  580. nsk_attr->fileopen = (unsigned) flist[ioff[21]];
  581. if (nsk_attr->filetype == NSK_UNSTRUCTURED) {
  582. /* extra info for Unstructured files */
  583. err = FILE_GETINFOLISTBYNAME_( fname,
  584. fnamelen,
  585. ulist,
  586. ulist_items,
  587. flist,
  588. flist_size,
  589. rlen,
  590. err_item
  591. );
  592. if (err != 0) return -1;
  593. uoff[0] = 0;
  594. /* Build up table of offets into result list */
  595. for (i=1; i < ulist_items; i++)
  596. uoff[i] = uoff[i-1] + ulen[i-1];
  597. }
  598. else {
  599. /* extra info for Structured files */
  600. err = FILE_GETINFOLISTBYNAME_( fname,
  601. fnamelen,
  602. slist,
  603. slist_items,
  604. flist,
  605. flist_size,
  606. rlen,
  607. err_item
  608. );
  609. if (err != 0) return -1;
  610. soff[0] = 0;
  611. /* Build up table of offets into result list */
  612. for (i=1; i < slist_items; i++)
  613. soff[i] = soff[i-1] + slen[i-1];
  614. nsk_attr->reclen = (unsigned) flist[soff[0]];
  615. nsk_attr->flags.secpart = (unsigned) flist[soff[1]];
  616. nsk_attr->flags.primpart = (unsigned)
  617. ( (flist[soff[2]] > 0 && nsk_attr->flags.secpart == 0) ? 1 : 0 );
  618. if (nsk_attr->filetype == NSK_KEYSEQUENCED) {
  619. /* extra info for Key Sequenced files */
  620. err = FILE_GETINFOLISTBYNAME_( fname,
  621. fnamelen,
  622. klist,
  623. klist_items,
  624. flist,
  625. flist_size,
  626. rlen,
  627. err_item
  628. );
  629. if (err != 0) return -1;
  630. koff[0] = 0;
  631. /* Build up table of offets into result list */
  632. for (i=1; i < klist_items; i++)
  633. koff[i] = koff[i-1] + klen[i-1];
  634. nsk_attr->keyoff = (unsigned) flist[koff[0]];
  635. nsk_attr->keylen = (unsigned) flist[koff[1]];
  636. nsk_attr->flags.dcompress = (unsigned) flist[koff[2]];
  637. nsk_attr->flags.icompress = (unsigned) flist[koff[3]];
  638. }
  639. }
  640. return 0;
  641. }
  642. #ifndef SFX
  643. /* TANDEM Directory processing */
  644. DIR *opendir(const char *dirname)
  645. {
  646. short i, resolve;
  647. char sname[FILENAME_MAX + 1];
  648. short snamelen;
  649. char fname[FILENAME_MAX + 1];
  650. short fnamelen;
  651. char *p;
  652. short searchid, err, end;
  653. struct dirent *entry;
  654. DIR *dirp;
  655. char ext[EXTENSION_MAX + 1];
  656. short extension;
  657. extension = parsename(dirname, sname, ext);
  658. snamelen = strlen(sname);
  659. /* First we work out how detailed the template is...
  660. * e.g. If the template is DAVES*.* we want the search result
  661. * in the same format
  662. */
  663. p = sname;
  664. i = 0;
  665. while ((p = strchr(p, TANDEM_DELIMITER)) != NULL){
  666. i++;
  667. p++;
  668. };
  669. resolve = 2 - i;
  670. /* Attempt to start a filename template */
  671. err = FILENAME_FINDSTART_ ( &searchid,
  672. sname,
  673. snamelen,
  674. resolve,
  675. DISK_DEVICE
  676. );
  677. if (err != 0) {
  678. end = FILENAME_FINDFINISH_(searchid);
  679. return NULL;
  680. }
  681. /* Create DIR structure */
  682. if ((dirp = malloc(sizeof(DIR))) == NULL ) {
  683. end = FILENAME_FINDFINISH_(searchid);
  684. return NULL;
  685. }
  686. dirp->D_list = dirp->D_curpos = NULL;
  687. strcpy(dirp->D_path, dirname);
  688. while ((err = FILENAME_FINDNEXT_(searchid,
  689. fname,
  690. FILENAME_MAX,
  691. &fnamelen
  692. )
  693. ) == 0 ){
  694. /* Create space for entry */
  695. if ((entry = malloc (sizeof(struct dirent))) == NULL) {
  696. end = FILENAME_FINDFINISH_(searchid);
  697. return NULL;
  698. }
  699. /* Link to last entry */
  700. if (dirp->D_curpos == NULL)
  701. dirp->D_list = dirp->D_curpos = entry; /* First name */
  702. else {
  703. dirp->D_curpos->d_next = entry; /* Link */
  704. dirp->D_curpos = entry;
  705. };
  706. /* Add directory entry */
  707. *dirp->D_curpos->d_name = '\0';
  708. strncat(dirp->D_curpos->d_name,fname,fnamelen);
  709. if (extension) {
  710. strcat(dirp->D_curpos->d_name,TANDEM_EXTENSION_STR);
  711. strcat(dirp->D_curpos->d_name,ext);
  712. };
  713. dirp->D_curpos->d_next = NULL;
  714. };
  715. end = FILENAME_FINDFINISH_(searchid);
  716. if (err == 1) { /* Should return EOF at end of search */
  717. dirp->D_curpos = dirp->D_list; /* Set current pos to start */
  718. return dirp;
  719. }
  720. else
  721. return NULL;
  722. }
  723. struct dirent *readdir(DIR *dirp)
  724. {
  725. struct dirent *cur;
  726. cur = dirp->D_curpos;
  727. dirp->D_curpos = dirp->D_curpos->d_next;
  728. return cur;
  729. }
  730. void rewinddir(DIR *dirp)
  731. {
  732. dirp->D_curpos = dirp->D_list;
  733. }
  734. int closedir(DIR *dirp)
  735. {
  736. struct dirent *node;
  737. while (dirp->D_list != NULL) {
  738. node = dirp->D_list;
  739. dirp->D_list = dirp->D_list->d_next;
  740. free( node );
  741. }
  742. free( dirp );
  743. return 0;
  744. }
  745. #endif /* !SFX */