154 |
} |
} |
155 |
|
|
156 |
/* Get the PR at PATH. PR is the PR entry to be filled in. |
/* Get the PR at PATH. PR is the PR entry to be filled in. |
|
|
|
157 |
If PRUNE is non-zero, don't read any multitext fields. */ |
If PRUNE is non-zero, don't read any multitext fields. */ |
158 |
static int |
static int |
159 |
get_pr (PR *pr, const char *path, int prune) |
get_pr (PR *pr, const char *path, int prune) |
210 |
} |
} |
211 |
} |
} |
212 |
|
|
213 |
|
static PR * |
214 |
|
get_pr_from_index (const DatabaseInfo database, const char *prnum, |
215 |
|
ErrorDesc *err) |
216 |
|
{ |
217 |
|
PR *pr = getFirstPR (database, err); |
218 |
|
|
219 |
|
/* If they gave it to us with the category, remove it. */ |
220 |
|
if (( strrchr (prnum, '/')) != NULL) |
221 |
|
{ |
222 |
|
prnum = strrchr (prnum, '/') + 1; |
223 |
|
} |
224 |
|
|
225 |
|
while (pr != NULL && strcmp (prnum, field_value (pr, NUMBER (database))) != 0) |
226 |
|
{ |
227 |
|
pr = getNextPR (pr); |
228 |
|
} |
229 |
|
|
230 |
|
if (pr == NULL) |
231 |
|
{ |
232 |
|
setError (err, CODE_NONEXISTENT_PR, |
233 |
|
"No PR %s listed in the index.", prnum); |
234 |
|
return NULL; |
235 |
|
} |
236 |
|
|
237 |
|
return pr; |
238 |
|
} |
239 |
|
|
240 |
/* Initializes PR for reading. Each line of the PR should be passed |
/* Initializes PR for reading. Each line of the PR should be passed |
241 |
in via addLineToPR (). */ |
in via addLineToPR (). */ |
242 |
|
|
1374 |
} |
} |
1375 |
|
|
1376 |
static char * |
static char * |
1377 |
get_pr_path (const DatabaseInfo database,const char *prnum, ErrorDesc *err) |
get_pr_path (const DatabaseInfo database, PR *pr, const char *prnum, |
1378 |
|
ErrorDesc *err) |
1379 |
{ |
{ |
1380 |
char *path = NULL; |
char *path = NULL; |
1381 |
const char *category = NULL; |
const char *category = NULL; |
|
PR *curr_pr_chain = getFirstPR (database, err); |
|
1382 |
char *categoryFromIndex = NULL; |
char *categoryFromIndex = NULL; |
1383 |
|
|
1384 |
if (curr_pr_chain != NULL) |
if (pr != NULL) |
1385 |
{ |
{ |
1386 |
PR *j; |
category = field_value (pr, CATEGORY (database)); |
|
for (j = curr_pr_chain ; j != NULL ; j = getNextPR (j)) |
|
|
{ |
|
|
if (strcmp (prnum, field_value (j, NUMBER (database))) == 0) |
|
|
{ |
|
|
category = field_value (j, CATEGORY (database)); |
|
|
break; |
|
|
} |
|
|
} |
|
|
if (category == NULL) |
|
|
{ |
|
|
setError (err, CODE_NONEXISTENT_PR, |
|
|
"No PR %s listed in the index.", prnum); |
|
|
} |
|
1387 |
} |
} |
1388 |
else |
else |
1389 |
{ |
{ |
1404 |
} |
} |
1405 |
|
|
1406 |
int |
int |
1407 |
prExists (const DatabaseInfo database, const char *prID, ErrorDesc *err) |
prExists (const DatabaseInfo database, const char *prnum, ErrorDesc *err) |
1408 |
{ |
{ |
1409 |
char *path = get_pr_path (database, prID, err); |
PR *pr = get_pr_from_index (database, prnum, err); |
1410 |
|
char *path = get_pr_path (database, pr, prnum, err); |
1411 |
int res = 0; |
int res = 0; |
1412 |
if (path != NULL) |
if (path != NULL) |
1413 |
{ |
{ |
1421 |
return res; |
return res; |
1422 |
} |
} |
1423 |
|
|
1424 |
char * |
static bool |
1425 |
lookup_pr_path (const DatabaseInfo database, const char *prnum, ErrorDesc *err) |
pr_file_readable (const char *path, ErrorDesc *err) |
1426 |
{ |
{ |
|
char *path; |
|
1427 |
FILE *fp; |
FILE *fp; |
1428 |
|
|
1429 |
/* If they gave it to us with the category, remove it. */ |
if (path == NULL) |
|
if (( strrchr (prnum, '/')) != NULL) |
|
1430 |
{ |
{ |
1431 |
prnum = strrchr (prnum, '/') + 1; |
return FALSE; |
1432 |
} |
} |
1433 |
path = get_pr_path (database, prnum, err); |
|
1434 |
if ((path == NULL) || ((fp = fopen (path, "r")) == NULL)) |
if ((fp = fopen (path, "r")) == NULL) |
1435 |
{ |
{ |
1436 |
if (path != NULL) |
setError (err, CODE_FILE_ERROR, "Can't open file `%s'", path); |
1437 |
{ |
return FALSE; |
|
setError (err, CODE_FILE_ERROR, "Can't open file `%s'", path); |
|
|
} |
|
|
return NULL; |
|
1438 |
} |
} |
1439 |
|
|
1440 |
fclose (fp); |
fclose (fp); |
1441 |
return path; |
return TRUE; |
1442 |
} |
} |
1443 |
|
|
1444 |
PR * |
PR * |
1445 |
readPRWithNum (const DatabaseInfo database, const char *prID, |
readPRWithNum (const DatabaseInfo database, const char *prnum, |
1446 |
int prune, ErrorDesc *err) |
int prune, ErrorDesc *err) |
1447 |
{ |
{ |
1448 |
PR *pr = NULL; |
PR *pr = NULL; |
1449 |
char *path = lookup_pr_path (database, prID, err); |
PR *index_pr = get_pr_from_index (database, prnum, err); |
1450 |
|
char *path = get_pr_path (database, index_pr, prnum, err); |
1451 |
|
|
1452 |
if (path != NULL) |
if (path != NULL) |
1453 |
{ |
{ |
1454 |
pr = allocPR (database); |
if (pr_file_readable (path, err)) |
1455 |
if (get_pr (pr, path, prune) == 0) |
{ |
1456 |
|
pr = allocPR (database); |
1457 |
|
setPrevPR (pr, getPrevPR (index_pr)); |
1458 |
|
setNextPR (pr, getNextPR (index_pr)); |
1459 |
|
if (get_pr (pr, path, prune) == 0) |
1460 |
|
{ |
1461 |
|
free_pr (pr); |
1462 |
|
pr = NULL; |
1463 |
|
} |
1464 |
|
} |
1465 |
|
free (path); |
1466 |
|
} |
1467 |
|
return pr; |
1468 |
|
} |
1469 |
|
|
1470 |
|
int |
1471 |
|
pr_delete (const DatabaseInfo database, const char *prnum, ErrorDesc *err) |
1472 |
|
{ |
1473 |
|
PR *pr; |
1474 |
|
char *path = NULL; |
1475 |
|
|
1476 |
|
pr = get_pr_from_index (database, prnum, err); |
1477 |
|
path = get_pr_path (database, pr, prnum, err); |
1478 |
|
|
1479 |
|
if (path == NULL || !pr_file_readable (path, err)) |
1480 |
|
{ |
1481 |
|
if (path != NULL) |
1482 |
{ |
{ |
1483 |
free_pr (pr); |
free (path); |
|
pr = NULL; |
|
1484 |
} |
} |
1485 |
|
return -1; |
1486 |
} |
} |
1487 |
return pr; |
|
1488 |
|
if (removePRFromIndex (database, prnum, err)) |
1489 |
|
{ |
1490 |
|
free (path); |
1491 |
|
return -5; |
1492 |
|
} |
1493 |
|
|
1494 |
|
if (unlink (path)) |
1495 |
|
{ |
1496 |
|
setError (err, CODE_FILE_ERROR, "Unable to unlink file %s\n", path); |
1497 |
|
free (path); |
1498 |
|
return -6; |
1499 |
|
} |
1500 |
|
|
1501 |
|
free (path); |
1502 |
|
return 1; |
1503 |
} |
} |
1504 |
|
|
1505 |
void |
void |