[f6b5f0] | 1 | /**************************************** |
---|
| 2 | * Computer Algebra System SINGULAR * |
---|
| 3 | ****************************************/ |
---|
| 4 | |
---|
[92e539] | 5 | //**************************************************************************/ |
---|
[0e1846] | 6 | // |
---|
[8fda0d] | 7 | // $Id: sing_dbm.cc,v 1.8 1997-08-13 13:51:42 Singular Exp $ |
---|
[0e1846] | 8 | // |
---|
[92e539] | 9 | //**************************************************************************/ |
---|
[f6b5f0] | 10 | // 'sing_dbm.cc' containes command to handle dbm-files under |
---|
[92e539] | 11 | // Singular. |
---|
[0e1846] | 12 | // |
---|
[92e539] | 13 | //**************************************************************************/ |
---|
[0e1846] | 14 | |
---|
| 15 | #include "mod2.h" |
---|
| 16 | |
---|
| 17 | #ifdef HAVE_DBM |
---|
| 18 | |
---|
[92e539] | 19 | # include <stdio.h> |
---|
| 20 | # include <fcntl.h> |
---|
| 21 | # include <errno.h> |
---|
| 22 | # include "tok.h" |
---|
| 23 | # include "febase.h" |
---|
| 24 | # include "mmemory.h" |
---|
| 25 | # include "ipid.h" |
---|
| 26 | # include "silink.h" |
---|
| 27 | # include "sing_dbm.h" |
---|
[0e1846] | 28 | |
---|
| 29 | /* These are the routines in dbm. */ |
---|
[92e539] | 30 | # include "ndbm.h" |
---|
| 31 | typedef struct { |
---|
| 32 | DBM *db; // pointer to open database |
---|
| 33 | int first; // firstkey to look for? |
---|
| 34 | } DBM_info; |
---|
[0e1846] | 35 | |
---|
[92e539] | 36 | //**************************************************************************/ |
---|
[463fb3c] | 37 | BOOLEAN dbOpen(si_link l, short flag) |
---|
[0e1846] | 38 | { |
---|
[92e539] | 39 | char *mode = "r"; |
---|
| 40 | DBM_info *db; |
---|
| 41 | int dbm_flags = O_RDONLY | O_CREAT; // open database readonly as default |
---|
| 42 | |
---|
[8fda0d] | 43 | if((l->mode!=NULL) |
---|
| 44 | && ((l->mode[0]=='w')||(l->mode[1]=='w'))) |
---|
[573ae7] | 45 | { |
---|
| 46 | dbm_flags = O_RDWR | O_CREAT; |
---|
| 47 | mode = "rw"; |
---|
[8fda0d] | 48 | flag|=SI_LINK_WRITE|SI_LINK_READ; |
---|
| 49 | } |
---|
| 50 | else if(flag & SI_LINK_WRITE) |
---|
| 51 | { |
---|
| 52 | // request w- open, but mode is not "w" nor "rw" => fail |
---|
| 53 | return TRUE; |
---|
[92e539] | 54 | } |
---|
[1fc83c0] | 55 | if (((db = (DBM_info *)Alloc(sizeof *db)) != NULL) |
---|
| 56 | &&((db->db = dbm_open(l->name, dbm_flags, 0664 )) != NULL )) |
---|
[573ae7] | 57 | { |
---|
| 58 | db->first=1; |
---|
[1fc83c0] | 59 | if(flag & SI_LINK_WRITE) |
---|
| 60 | SI_LINK_SET_RW_OPEN_P(l); |
---|
| 61 | else |
---|
| 62 | SI_LINK_SET_R_OPEN_P(l); |
---|
[573ae7] | 63 | l->data=(void *)(db); |
---|
| 64 | FreeL(l->mode); |
---|
| 65 | l->mode=mstrdup(mode); |
---|
| 66 | return FALSE; |
---|
[0e1846] | 67 | } |
---|
| 68 | return TRUE; |
---|
| 69 | } |
---|
| 70 | |
---|
[92e539] | 71 | //**************************************************************************/ |
---|
[0e1846] | 72 | BOOLEAN dbClose(si_link l) |
---|
| 73 | { |
---|
[573ae7] | 74 | DBM_info *db = (DBM_info *)l->data; |
---|
[92e539] | 75 | |
---|
| 76 | dbm_close(db->db); |
---|
[1fc83c0] | 77 | Free((ADDRESS)db,(sizeof *db)); |
---|
[92e539] | 78 | l->data=NULL; |
---|
[0e1846] | 79 | SI_LINK_SET_CLOSE_P(l); |
---|
| 80 | return FALSE; |
---|
| 81 | } |
---|
| 82 | |
---|
[92e539] | 83 | //**************************************************************************/ |
---|
[0e1846] | 84 | static datum d_value; |
---|
[463fb3c] | 85 | leftv dbRead2(si_link l, leftv key) |
---|
[0e1846] | 86 | { |
---|
[573ae7] | 87 | DBM_info *db = (DBM_info *)l->data; |
---|
[0e1846] | 88 | leftv v=NULL; |
---|
[573ae7] | 89 | datum d_key; |
---|
[0e1846] | 90 | |
---|
[573ae7] | 91 | if(key!=NULL) |
---|
| 92 | { |
---|
| 93 | if (key->Typ()==STRING_CMD) |
---|
[0e1846] | 94 | { |
---|
[573ae7] | 95 | d_key.dptr = (char*)key->Data(); |
---|
| 96 | d_key.dsize = strlen(d_key.dptr)+1; |
---|
| 97 | d_value = dbm_fetch(db->db, d_key); |
---|
[0e1846] | 98 | v=(leftv)Alloc0(sizeof(sleftv)); |
---|
[573ae7] | 99 | if (d_value.dptr!=NULL) v->data=mstrdup(d_value.dptr); |
---|
| 100 | else v->data=mstrdup(""); |
---|
[0e1846] | 101 | v->rtyp=STRING_CMD; |
---|
[573ae7] | 102 | } |
---|
| 103 | else |
---|
| 104 | { |
---|
| 105 | WerrorS("read(`DBM link`,`string`) expected"); |
---|
[0e1846] | 106 | } |
---|
| 107 | } |
---|
| 108 | else |
---|
| 109 | { |
---|
[1fc83c0] | 110 | if(db->first) |
---|
| 111 | d_value = dbm_firstkey((DBM *)db->db); |
---|
| 112 | else |
---|
| 113 | d_value = dbm_nextkey((DBM *)db->db); |
---|
[573ae7] | 114 | |
---|
| 115 | v=(leftv)Alloc0(sizeof(sleftv)); |
---|
| 116 | v->rtyp=STRING_CMD; |
---|
| 117 | if (d_value.dptr!=NULL) |
---|
| 118 | { |
---|
| 119 | v->data=mstrdup(d_value.dptr); |
---|
| 120 | db->first = 0; |
---|
| 121 | } |
---|
| 122 | else |
---|
| 123 | { |
---|
| 124 | v->data=mstrdup(""); |
---|
| 125 | db->first = 1; |
---|
| 126 | } |
---|
| 127 | |
---|
[0e1846] | 128 | } |
---|
| 129 | return v; |
---|
| 130 | } |
---|
| 131 | leftv dbRead1(si_link l) |
---|
| 132 | { |
---|
[463fb3c] | 133 | return dbRead2(l,NULL); |
---|
[0e1846] | 134 | } |
---|
[92e539] | 135 | //**************************************************************************/ |
---|
[0e1846] | 136 | BOOLEAN dbWrite(si_link l, leftv key) |
---|
| 137 | { |
---|
[573ae7] | 138 | DBM_info *db = (DBM_info *)l->data; |
---|
[0e1846] | 139 | BOOLEAN b=TRUE; |
---|
[92e539] | 140 | register int ret; |
---|
| 141 | |
---|
[573ae7] | 142 | // database is opened |
---|
| 143 | if((key!=NULL) && (key->Typ()==STRING_CMD) ) |
---|
| 144 | { |
---|
| 145 | if (key->next!=NULL) // have a second parameter ? |
---|
| 146 | { |
---|
| 147 | if(key->next->Typ()==STRING_CMD) // replace (key,value) |
---|
| 148 | { |
---|
| 149 | datum d_key, d_value; |
---|
| 150 | |
---|
| 151 | d_key.dptr = (char *)key->Data(); |
---|
| 152 | d_key.dsize = strlen(d_key.dptr)+1; |
---|
| 153 | d_value.dptr = (char *)key->next->Data(); |
---|
| 154 | d_value.dsize = strlen(d_value.dptr)+1; |
---|
| 155 | ret = dbm_store(db->db, d_key, d_value, DBM_REPLACE); |
---|
| 156 | if(!ret ) |
---|
| 157 | b=FALSE; |
---|
| 158 | else |
---|
| 159 | { |
---|
| 160 | if(dbm_error(db->db)) |
---|
| 161 | { |
---|
| 162 | Werror("DBM link I/O error. Is '%s' readonly?", l->name); |
---|
| 163 | dbm_clearerr(db->db); |
---|
| 164 | } |
---|
| 165 | } |
---|
[92e539] | 166 | } |
---|
[573ae7] | 167 | } |
---|
| 168 | else |
---|
| 169 | { // delete (key) |
---|
| 170 | datum d_key; |
---|
| 171 | |
---|
| 172 | d_key.dptr = (char *)key->Data(); |
---|
| 173 | d_key.dsize = strlen(d_key.dptr)+1; |
---|
| 174 | dbm_delete(db->db, d_key); |
---|
| 175 | b=FALSE; |
---|
[0e1846] | 176 | } |
---|
| 177 | } |
---|
| 178 | else |
---|
| 179 | { |
---|
[1fc83c0] | 180 | WerrorS("write(`DBM link`,`key string` [,`data string`]) expected"); |
---|
[0e1846] | 181 | } |
---|
| 182 | return b; |
---|
| 183 | } |
---|
[92e539] | 184 | //**************************************************************************/ |
---|
[1fc83c0] | 185 | //char *dbStatus(si_link l, char *request) |
---|
| 186 | //{ |
---|
| 187 | // if (strcmp(request, "read") == 0) |
---|
| 188 | // { |
---|
| 189 | // if (SI_LINK_R_OPEN_P(l)) |
---|
| 190 | // return "ready"; |
---|
| 191 | // else |
---|
| 192 | // return "not ready"; |
---|
| 193 | // } |
---|
| 194 | // else if (strcmp(request, "write") == 0) |
---|
| 195 | // { |
---|
| 196 | // if (SI_LINK_W_OPEN_P(l)) |
---|
| 197 | // return "ready"; |
---|
| 198 | // else |
---|
| 199 | // return "not ready"; |
---|
| 200 | // } |
---|
| 201 | // else return "unknown status request"; |
---|
| 202 | //} |
---|
[92e539] | 203 | //**************************************************************************/ |
---|
[463fb3c] | 204 | si_link_extension slInitDBMExtension(si_link_extension s) |
---|
[0e1846] | 205 | { |
---|
[463fb3c] | 206 | s->Open=dbOpen; |
---|
[0e1846] | 207 | s->Close=dbClose; |
---|
| 208 | s->Read=dbRead1; |
---|
[463fb3c] | 209 | s->Read2=dbRead2; |
---|
[0e1846] | 210 | s->Write=dbWrite; |
---|
[463fb3c] | 211 | //s->Dump=NULL; |
---|
| 212 | //s->GetDump=NULL; |
---|
[1fc83c0] | 213 | //s->Status=dbStatus; |
---|
| 214 | s->Status=slStatusAscii; |
---|
[463fb3c] | 215 | s->type="DBM"; |
---|
[0e1846] | 216 | return s; |
---|
| 217 | } |
---|
[92e539] | 218 | #endif /* HAVE_DBM */ |
---|