/******************************************************************* Del the share mode of a file for this process ********************************************************************/ void del_share_mode(files_struct * fsp) { TDB_DATA dbuf; struct locking_data *data; int i, del_count = 0; share_mode_entry *shares; pid_t pid = sys_getpid(); /* read in the existing share modes */ dbuf = tdb_fetch(tdb, locking_key_fsp(fsp)); if (!dbuf.dptr) return; data = (struct locking_data *)dbuf.dptr; shares = (share_mode_entry *) (dbuf.dptr + sizeof(*data)); /* find any with our pid and delete it by overwriting with the rest of the data from the record */ for (i = 0; i < data->num_share_mode_entries;) { if (shares[i].pid == pid && memcmp(&shares[i].time, &fsp->open_time, sizeof(struct timeval)) == 0) { data->num_share_mode_entries--; memmove(&shares[i], &shares[i + 1], dbuf.dsize - (sizeof(*data) + (i + 1) * sizeof(*shares))); del_count++; } else { i++; } } /* the record has shrunk a bit */ dbuf.dsize -= del_count * sizeof(*shares); /* store it back in the database */ if (data->num_share_mode_entries == 0) { tdb_delete(tdb, locking_key_fsp(fsp)); } else { tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE); } free(dbuf.dptr); }
/******************************************************************* a generic in-place modification call for share mode entries ********************************************************************/ static BOOL mod_share_mode(files_struct * fsp, void (*mod_fn) (share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *), void *param) { TDB_DATA dbuf; struct locking_data *data; int i; share_mode_entry *shares; pid_t pid = sys_getpid(); int need_store = 0; /* read in the existing share modes */ dbuf = tdb_fetch(tdb, locking_key_fsp(fsp)); if (!dbuf.dptr) return False; data = (struct locking_data *)dbuf.dptr; shares = (share_mode_entry *) (dbuf.dptr + sizeof(*data)); /* find any with our pid and call the supplied function */ for (i = 0; i < data->num_share_mode_entries; i++) { if (pid == shares[i].pid && shares[i].share_mode == fsp->share_mode && memcmp(&shares[i].time, &fsp->open_time, sizeof(struct timeval)) == 0) { mod_fn(&shares[i], fsp->sbuf.st_dev, fsp->sbuf.st_ino, param); need_store = 1; } } /* if the mod fn was called then store it back */ if (need_store) { if (data->num_share_mode_entries == 0) { tdb_delete(tdb, locking_key_fsp(fsp)); } else { tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE); } } free(dbuf.dptr); return need_store; }
/******************************************************************* Set the share mode of a file. Return False on fail, True on success. ********************************************************************/ BOOL set_share_mode(files_struct * fsp, uint16 port, uint16 op_type) { TDB_DATA dbuf; struct locking_data *data; share_mode_entry *shares; char *p = NULL; int size; /* read in the existing share modes if any */ dbuf = tdb_fetch(tdb, locking_key_fsp(fsp)); if (!dbuf.dptr) { /* we'll need to create a new record */ SMBSTR *full_path = smbstr_make_filename(fsp->conn->connectpath, fsp->fsp_name); const char *fname = smbstrA(full_path); size = sizeof(*data) + sizeof(*shares) + strlen(fname) + 1; p = (char *)malloc(size); data = (struct locking_data *)p; shares = (share_mode_entry *) (p + sizeof(*data)); data->num_share_mode_entries = 1; pstrcpy(p + sizeof(*data) + sizeof(*shares), fname); fill_share_mode(p + sizeof(*data), fsp, port, op_type); dbuf.dptr = p; dbuf.dsize = size; tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE); free(p); return True; } /* we're adding to an existing entry - this is a bit fiddly */ data = (struct locking_data *)dbuf.dptr; shares = (share_mode_entry *) (dbuf.dptr + sizeof(*data)); data->num_share_mode_entries++; size = dbuf.dsize + sizeof(*shares); p = malloc(size); memcpy(p, dbuf.dptr, sizeof(*data)); fill_share_mode(p + sizeof(*data), fsp, port, op_type); memcpy(p + sizeof(*data) + sizeof(*shares), dbuf.dptr + sizeof(*data), dbuf.dsize - sizeof(*data)); free(dbuf.dptr); dbuf.dptr = p; dbuf.dsize = size; tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE); free(p); return True; }
BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) { TDB_DATA dbuf; struct locking_data *data; char *p=NULL; int size; BOOL ret = True; /* read in the existing share modes if any */ dbuf = tdb_fetch(tdb, locking_key_fsp(fsp)); if (!dbuf.dptr) { size_t offset; /* we'll need to create a new record */ pstring fname; pstrcpy(fname, fsp->conn->connectpath); pstrcat(fname, "/"); pstrcat(fname, fsp->fsp_name); size = sizeof(*data) + sizeof(share_mode_entry) + strlen(fname) + 1; p = (char *)malloc(size); if (!p) return False; data = (struct locking_data *)p; data->u.num_share_mode_entries = 1; DEBUG(10,("set_share_mode: creating entry for file %s. num_share_modes = 1\n", fsp->fsp_name )); offset = sizeof(*data) + sizeof(share_mode_entry); safe_strcpy(p + offset, fname, size - offset - 1); fill_share_mode(p + sizeof(*data), fsp, port, op_type); dbuf.dptr = p; dbuf.dsize = size; if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1) ret = False; print_share_mode_table((struct locking_data *)p); SAFE_FREE(p); return ret; } /* we're adding to an existing entry - this is a bit fiddly */ data = (struct locking_data *)dbuf.dptr; data->u.num_share_mode_entries++; DEBUG(10,("set_share_mode: adding entry for file %s. new num_share_modes = %d\n", fsp->fsp_name, data->u.num_share_mode_entries )); size = dbuf.dsize + sizeof(share_mode_entry); p = malloc(size); if (!p) return False; memcpy(p, dbuf.dptr, sizeof(*data)); fill_share_mode(p + sizeof(*data), fsp, port, op_type); memcpy(p + sizeof(*data) + sizeof(share_mode_entry), dbuf.dptr + sizeof(*data), dbuf.dsize - sizeof(*data)); SAFE_FREE(dbuf.dptr); dbuf.dptr = p; dbuf.dsize = size; if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1) ret = False; print_share_mode_table((struct locking_data *)p); SAFE_FREE(p); return ret; }