00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #if HAVE_DIRENT_H
00032 # include <dirent.h>
00033 # define NAMLEN(dirent) strlen((dirent)->d_name)
00034 #else
00035 # define dirent direct
00036 # define NAMLEN(dirent) (dirent)->d_namlen
00037 # if HAVE_SYS_NDIR_H
00038 # include <sys/ndir.h>
00039 # endif
00040 # if HAVE_SYS_DIR_H
00041 # include <sys/dir.h>
00042 # endif
00043 # if HAVE_NDIR_H
00044 # include <ndir.h>
00045 # endif
00046 #endif
00047
00048 static void show_queued_files(int idx)
00049 {
00050 int i, cnt = 0, len;
00051 char spaces[] = " ";
00052 fileq_t *q;
00053
00054 for (q = fileq; q; q = q->next) {
00055 if (!strcasecmp(q->nick, dcc[idx].nick)) {
00056 if (!cnt) {
00057 spaces[HANDLEN - 9] = 0;
00058 dprintf(idx, " Send to %s Filename\n", spaces);
00059 dprintf(idx, " ---------%s --------------------\n", spaces);
00060 spaces[HANDLEN - 9] = ' ';
00061 }
00062 cnt++;
00063 spaces[len = HANDLEN - strlen(q->to)] = 0;
00064 if (q->dir[0] == '*')
00065 dprintf(idx, " %s%s %s/%s\n", q->to, spaces, &q->dir[1],
00066 q->file);
00067 else
00068 dprintf(idx, " %s%s /%s%s%s\n", q->to, spaces, q->dir,
00069 q->dir[0] ? "/" : "", q->file);
00070 spaces[len] = ' ';
00071 }
00072 }
00073 for (i = 0; i < dcc_total; i++) {
00074 if ((dcc[i].type == &DCC_GET_PENDING || dcc[i].type == &DCC_GET) &&
00075 (!strcasecmp(dcc[i].nick, dcc[idx].nick) ||
00076 !strcasecmp(dcc[i].u.xfer->from, dcc[idx].nick))) {
00077 char *nfn;
00078
00079 if (!cnt) {
00080 spaces[HANDLEN - 9] = 0;
00081 dprintf(idx, " Send to %s Filename\n", spaces);
00082 dprintf(idx, " ---------%s --------------------\n", spaces);
00083 spaces[HANDLEN - 9] = ' ';
00084 }
00085 nfn = strrchr(dcc[i].u.xfer->origname, '/');
00086 if (nfn == NULL)
00087 nfn = dcc[i].u.xfer->origname;
00088 else
00089 nfn++;
00090 cnt++;
00091 spaces[len = HANDLEN - strlen(dcc[i].nick)] = 0;
00092 if (dcc[i].type == &DCC_GET_PENDING)
00093 dprintf(idx, " %s%s %s [WAITING]\n", dcc[i].nick, spaces,
00094 nfn);
00095 else
00096 dprintf(idx, " %s%s %s (%.1f%% done)\n", dcc[i].nick, spaces,
00097 nfn, (100.0 * ((float) dcc[i].status /
00098 (float) dcc[i].u.xfer->length)));
00099 spaces[len] = ' ';
00100 }
00101 }
00102 if (!cnt)
00103 dprintf(idx, "No files queued up.\n");
00104 else
00105 dprintf(idx, "Total: %d\n", cnt);
00106 }
00107
00108
00109
00110 static int too_many_filers()
00111 {
00112 int i, n = 0;
00113
00114 if (dcc_users == 0)
00115 return 0;
00116 for (i = 0; i < dcc_total; i++)
00117 if (dcc[i].type == &DCC_FILES)
00118 n++;
00119 return (n >= dcc_users);
00120 }
00121
00122
00123
00124 static void add_file(char *dir, char *file, char *nick)
00125 {
00126 FILE *f;
00127
00128
00129
00130
00131 if (!strncmp(dccdir, dir, strlen(dccdir)) &&
00132 (f = filedb_open(&dir[strlen(dccdir)], 2))) {
00133 filedb_add(f, file, nick);
00134 filedb_close(f);
00135 }
00136 }
00137
00138 static int welcome_to_files(int idx)
00139 {
00140 struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
00141 FILE *f;
00142 char *p = get_user(&USERENTRY_DCCDIR, dcc[idx].user);
00143
00144 dprintf(idx, "\n");
00145 if (fr.global & USER_JANITOR)
00146 fr.global |= USER_MASTER;
00147
00148
00149
00150
00151 if (!(dcc[idx].status & STAT_CHAT))
00152 show_motd(idx);
00153 sub_lang(idx, _("Welcome to the %B file server\n"));
00154 sub_lang(idx, _("All file transfers will be sent to '%N' by default.\n(You can specify an alternate nick with the 'get' command.)\nType 'help' for help.\n"));
00155 if (p)
00156 strcpy(dcc[idx].u.file->dir, p);
00157 else
00158 dcc[idx].u.file->dir[0] = 0;
00159
00160 f = filedb_open(dcc[idx].u.file->dir, 0);
00161 if (f == NULL) {
00162 dcc[idx].u.file->dir[0] = 0;
00163 f = filedb_open(dcc[idx].u.file->dir, 0);
00164 if (f == NULL) {
00165 dprintf(idx, _("\nThe file system seems to be broken right now.\n"));
00166 dprintf(idx, _("(The files-path is set to an invalid directory.)\n"));
00167 dprintf(idx, "\n\n");
00168 dccdir[0] = 0;
00169 chanout_but(-1, dcc[idx].u.file->chat->channel,
00170 "*** %s rejoined the party line.\n",
00171 dcc[idx].nick);
00172 botnet_send_join_idx(idx, dcc[idx].u.file->chat->channel);
00173 return 0;
00174 }
00175 }
00176 filedb_close(f);
00177 dprintf(idx, "%s: /%s\n\n", _("Current directory"), dcc[idx].u.file->dir);
00178 return 1;
00179 }
00180
00181 static void cmd_optimize(int idx, char *par)
00182 {
00183 struct userrec *u = get_user_by_handle(userlist, dcc[idx].nick);
00184 FILE *fdb = NULL;
00185 char *p = NULL;
00186
00187 putlog(LOG_FILES, "*", "files: #%s# optimize", dcc[idx].nick);
00188 p = get_user(&USERENTRY_DCCDIR, u);
00189
00190 if (p) {
00191 fdb = filedb_open(p, 1);
00192 if (!fdb) {
00193 set_user(&USERENTRY_DCCDIR, u, NULL);
00194 p = NULL;
00195 }
00196 }
00197 if (!p)
00198 fdb = filedb_open("", 1);
00199 if (!fdb) {
00200 dprintf(idx, _("Illegal directory.\n"));
00201 return;
00202 }
00203 filedb_close(fdb);
00204 dprintf(idx, "Current directory is now optimized.\n");
00205 }
00206
00207
00208
00209
00210
00211
00212 static int resolve_dir(char *current, char *change, char **real, int idx)
00213 {
00214 char *elem = NULL, *s = NULL, *new = NULL, *work = NULL, *p = NULL;
00215 FILE *fdb = NULL;
00216 DIR *dir = NULL;
00217 filedb_entry *fdbe = NULL;
00218 struct flag_record user = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0},
00219 req = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
00220
00221 *real = NULL;
00222 realloc_strcpy(*real, current);
00223 if (!change[0])
00224 return 1;
00225 new = malloc(strlen(change) + 2);
00226 strcpy(new, change);
00227 if (new[0] == '/') {
00228
00229 (*real)[0] = 0;
00230 strcpy(new, &new[1]);
00231 }
00232
00233 strcat(new, "/");
00234 p = strchr(new, '/');
00235 while (p) {
00236 *p = 0;
00237 p++;
00238 realloc_strcpy(elem, new);
00239 strcpy(new, p);
00240 if (!elem[0] || !strcmp(elem, ".")) {
00241 p = strchr(new, '/');
00242 continue;
00243 }
00244 else if (!strcmp(elem, "..")) {
00245
00246 p = strrchr(*real, '/');
00247 if (p == NULL) {
00248
00249 if (!(*real)[0]) {
00250 free_null(elem);
00251 free_null(new);
00252 realloc_strcpy(*real, current);
00253 return 0;
00254 }
00255 (*real)[0] = 0;
00256 } else
00257 *p = 0;
00258 } else {
00259
00260 fdb = filedb_open(*real, 0);
00261 if (!fdb) {
00262
00263 free_null(elem);
00264 free_null(new);
00265 realloc_strcpy(*real, current);
00266 return 0;
00267 }
00268 filedb_readtop(fdb, NULL);
00269 fdbe = filedb_matchfile(fdb, ftell(fdb), elem);
00270 filedb_close(fdb);
00271 if (!fdbe) {
00272
00273 free_null(elem);
00274 free_null(new);
00275 free_null(s);
00276 realloc_strcpy(*real, current);
00277 return 0;
00278 }
00279 if (!(fdbe->stat & FILE_DIR)) {
00280
00281 free_fdbe(&fdbe);
00282 free_null(elem);
00283 free_null(new);
00284 free_null(s);
00285 realloc_strcpy(*real, current);
00286 return 0;
00287 }
00288 if (idx >= 0)
00289 get_user_flagrec(dcc[idx].user, &user, fdbe->chan);
00290 else
00291 user.global = USER_OWNER | USER_BOT | USER_MASTER | USER_OP |
00292 USER_FRIEND;
00293
00294 if (fdbe->flags_req) {
00295 break_down_flags(fdbe->flags_req, &req, NULL);
00296 if (!flagrec_ok(&req, &user)) {
00297 free_fdbe(&fdbe);
00298 free_null(elem);
00299 free_null(new);
00300 free_null(s);
00301 realloc_strcpy(*real, current);
00302 return 0;
00303 }
00304 }
00305 free_fdbe(&fdbe);
00306 realloc_strcpy(s, *real);
00307 if (s[0] && s[strlen(s) - 1] != '/') {
00308 s = nrealloc(s, strlen(s) + 2);
00309 strcat(s, "/");
00310 }
00311 work = malloc(strlen(s) + strlen(elem) + 1);
00312 sprintf(work, "%s%s", s, elem);
00313 realloc_strcpy(*real, work);
00314 s = realloc(s, strlen(dccdir) + strlen(*real) + 1);
00315 sprintf(s, "%s%s", dccdir, *real);
00316 }
00317 p = strchr(new, '/');
00318 }
00319 free_null(new);
00320 if (elem)
00321 free_null(elem);
00322 if (work)
00323 free_null(work);
00324
00325 s = realloc(s, strlen(dccdir) + strlen(*real) + 1);
00326 sprintf(s, "%s%s", dccdir, *real);
00327 dir = opendir(s);
00328 free_null(s);
00329 if (!dir)
00330 return 0;
00331 closedir(dir);
00332 return 1;
00333 }
00334
00335 static void incr_file_gots(char *ppath)
00336 {
00337 char *p, *path = NULL, *destdir = NULL, *fn = NULL;
00338 filedb_entry *fdbe;
00339 FILE *fdb;
00340
00341
00342
00343
00344 if ((ppath[0] == '*') || (ppath[0] == '/'))
00345 return;
00346 realloc_strcpy(path, ppath);
00347 p = strrchr(path, '/');
00348 if (p != NULL) {
00349 *p = 0;
00350 realloc_strcpy(destdir, path);
00351 realloc_strcpy(fn, p + 1);
00352 *p = '/';
00353 } else {
00354 realloc_strcpy(destdir, "");
00355 realloc_strcpy(fn, path);
00356 }
00357 fdb = filedb_open(destdir, 0);
00358 if (!fdb) {
00359 free_null(path);
00360 free_null(destdir);
00361 free_null(fn);
00362 return;
00363 }
00364 free_null(path);
00365 free_null(destdir);
00366 filedb_readtop(fdb, NULL);
00367 fdbe = filedb_matchfile(fdb, ftell(fdb), fn);
00368 free_null(fn);
00369 if (fdbe) {
00370 fdbe->gots++;
00371 filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_HEADER);
00372 free_fdbe(&fdbe);
00373 }
00374 filedb_close(fdb);
00375 }
00376
00377
00378
00379 static void cmd_pwd(int idx, char *par)
00380 {
00381 putlog(LOG_FILES, "*", "files: #%s# pwd", dcc[idx].nick);
00382 dprintf(idx, "%s: /%s\n", _("Current directory"), dcc[idx].u.file->dir);
00383 }
00384
00385 static void cmd_pending(int idx, char *par)
00386 {
00387 show_queued_files(idx);
00388 putlog(LOG_FILES, "*", "files: #%s# pending", dcc[idx].nick);
00389 }
00390
00391 static void cmd_cancel(int idx, char *par)
00392 {
00393 if (!par[0]) {
00394 dprintf(idx, "%s: cancel <file-mask>\n", _("Usage"));
00395 return;
00396 }
00397 fileq_cancel(idx, par);
00398 putlog(LOG_FILES, "*", "files: #%s# cancel %s", dcc[idx].nick, par);
00399 }
00400
00401 static void cmd_chdir(int idx, char *msg)
00402 {
00403 char *s = NULL;
00404
00405 if (!msg[0]) {
00406 dprintf(idx, "%s: cd <new-dir>\n", _("Usage"));
00407 return;
00408 }
00409 if (!resolve_dir(dcc[idx].u.file->dir, msg, &s, idx)) {
00410 dprintf(idx, _("No such directory.\n"));
00411 free_null(s);
00412 return;
00413 }
00414 strlcpy(dcc[idx].u.file->dir, s, sizeof dcc[idx].u.file->dir);
00415 free_null(s);
00416 set_user(&USERENTRY_DCCDIR, dcc[idx].user, dcc[idx].u.file->dir);
00417 putlog(LOG_FILES, "*", "files: #%s# cd /%s", dcc[idx].nick,
00418 dcc[idx].u.file->dir);
00419 dprintf(idx, "%s: /%s\n", _("New current directory"), dcc[idx].u.file->dir);
00420 }
00421
00422 static void files_ls(int idx, char *par, int showall)
00423 {
00424 char *p, *s = NULL, *destdir = NULL, *mask = NULL;
00425 FILE *fdb;
00426
00427 if (par[0]) {
00428 putlog(LOG_FILES, "*", "files: #%s# ls %s", dcc[idx].nick, par);
00429 p = strrchr(par, '/');
00430 if (p != NULL) {
00431 *p = 0;
00432 realloc_strcpy(s, par);
00433 realloc_strcpy(mask, p + 1);
00434 if (!resolve_dir(dcc[idx].u.file->dir, s, &destdir, idx)) {
00435 dprintf(idx, _("Illegal directory.\n"));
00436 free_null(s);
00437 free_null(mask);
00438 free_null(destdir);
00439 return;
00440 }
00441 free_null(s);
00442 } else {
00443 realloc_strcpy(destdir, dcc[idx].u.file->dir);
00444 realloc_strcpy(mask, par);
00445 }
00446
00447 if (resolve_dir(destdir, mask, &s, idx)) {
00448
00449 realloc_strcpy(destdir, s);
00450 realloc_strcpy(mask, "*");
00451 }
00452 free_null(s);
00453 fdb = filedb_open(destdir, 0);
00454 if (!fdb) {
00455 dprintf(idx, _("Illegal directory.\n"));
00456 free_null(destdir);
00457 free_null(mask);
00458 return;
00459 }
00460 filedb_ls(fdb, idx, mask, showall);
00461 filedb_close(fdb);
00462 free_null(destdir);
00463 free_null(mask);
00464 } else {
00465 putlog(LOG_FILES, "*", "files: #%s# ls", dcc[idx].nick);
00466 fdb = filedb_open(dcc[idx].u.file->dir, 0);
00467 if (fdb) {
00468 filedb_ls(fdb, idx, "*", showall);
00469 filedb_close(fdb);
00470 } else
00471 dprintf(idx, _("Illegal directory.\n"));
00472 }
00473 }
00474
00475 static void cmd_ls(int idx, char *par)
00476 {
00477 files_ls(idx, par, 0);
00478 }
00479
00480 static void cmd_lsa(int idx, char *par)
00481 {
00482 files_ls(idx, par, 1);
00483 }
00484
00485
00486 static void cmd_reget_get(int idx, char *par, int resend)
00487 {
00488 int ok = 0, i;
00489 char *p, *what, *destdir = NULL, *s = NULL;
00490 filedb_entry *fdbe;
00491 FILE *fdb;
00492 long where = 0;
00493 int nicklen = NICKLEN;
00494
00495
00496 if (NICKLEN > 9) {
00497 module_entry *me = module_find("server", 1, 1);
00498
00499 if (me && me->funcs)
00500 nicklen = (int) me->funcs[SERVER_NICKLEN];
00501 }
00502 if (!par[0]) {
00503 dprintf(idx, "%s: %sget <file(s)> [nickname]\n", _("Usage"),
00504 resend ? "re" : "");
00505 return;
00506 }
00507 what = newsplit(&par);
00508 if (strlen(par) > nicklen) {
00509 dprintf(idx, _("Be reasonable.\n"));
00510 return;
00511 }
00512 p = strrchr(what, '/');
00513 if (p != NULL) {
00514 *p = 0;
00515 realloc_strcpy(s, what);
00516 strcpy(what, p + 1);
00517 if (!resolve_dir(dcc[idx].u.file->dir, s, &destdir, idx)) {
00518 free_null(destdir);
00519 free_null(s);
00520 dprintf(idx, _("Illegal directory.\n"));
00521 return;
00522 }
00523 free_null(s);
00524 } else
00525 realloc_strcpy(destdir, dcc[idx].u.file->dir);
00526 fdb = filedb_open(destdir, 0);
00527 if (!fdb)
00528 return;
00529 filedb_readtop(fdb, NULL);
00530 fdbe = filedb_matchfile(fdb, ftell(fdb), what);
00531 if (!fdbe) {
00532 filedb_close(fdb);
00533 free_fdbe(&fdbe);
00534 free_null(destdir);
00535 dprintf(idx, _("No matching files.\n"));
00536 return;
00537 }
00538 while (fdbe) {
00539 where = ftell(fdb);
00540 if (!(fdbe->stat & (FILE_HIDDEN | FILE_DIR))) {
00541 ok = 1;
00542 do_dcc_send(idx, destdir, fdbe->filename, par, resend);
00543 }
00544 free_fdbe(&fdbe);
00545 fdbe = filedb_matchfile(fdb, where, what);
00546 }
00547 filedb_close(fdb);
00548 free_null(destdir);
00549 if (!ok)
00550 dprintf(idx, _("No matching files.\n"));
00551 else
00552 putlog(LOG_FILES, "*", "files: #%s# %sget %s %s", dcc[idx].nick,
00553 resend ? "re" : "", what, par);
00554 }
00555
00556 static void cmd_reget(int idx, char *par)
00557 {
00558 cmd_reget_get(idx, par, 1);
00559 }
00560
00561 static void cmd_get(int idx, char *par)
00562 {
00563 cmd_reget_get(idx, par, 0);
00564 }
00565
00566 static void cmd_file_help(int idx, char *par)
00567 {
00568 char *s;
00569 struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
00570
00571 get_user_flagrec(dcc[idx].user, &fr, dcc[idx].u.file->chat->con_chan);
00572 if (par[0]) {
00573 putlog(LOG_FILES, "*", "files: #%s# help %s", dcc[idx].nick, par);
00574 s = malloc(strlen(par) + 9);
00575 sprintf(s, "filesys/%s", par);
00576 s[256] = 0;
00577 tellhelp(idx, s, &fr, 0);
00578 free_null(s);
00579 } else {
00580 putlog(LOG_FILES, "*", "files: #%s# help", dcc[idx].nick);
00581 tellhelp(idx, "filesys/help", &fr, 0);
00582 }
00583 }
00584
00585 static void cmd_hide(int idx, char *par)
00586 {
00587 FILE *fdb;
00588 filedb_entry *fdbe;
00589 long where = 0;
00590 int ok = 0;
00591
00592 if (!par[0]) {
00593 dprintf(idx, "%s: hide <file(s)>\n", _("Usage"));
00594 return;
00595 }
00596 fdb = filedb_open(dcc[idx].u.file->dir, 0);
00597 if (!fdb)
00598 return;
00599 filedb_readtop(fdb, NULL);
00600 fdbe = filedb_matchfile(fdb, ftell(fdb), par);
00601 if (!fdbe) {
00602 filedb_close(fdb);
00603 dprintf(idx, _("No matching files.\n"));
00604 return;
00605 }
00606 while (fdbe) {
00607 where = ftell(fdb);
00608 if (!(fdbe->stat & FILE_HIDDEN)) {
00609 fdbe->stat |= FILE_HIDDEN;
00610 ok++;
00611 dprintf(idx, "%s: %s\n", _("Hid"), fdbe->filename);
00612 filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_HEADER);
00613 }
00614 free_fdbe(&fdbe);
00615 fdbe = filedb_matchfile(fdb, where, par);
00616 }
00617 filedb_close(fdb);
00618 if (!ok)
00619 dprintf(idx, _("No matching files.\n"));
00620 else {
00621 putlog(LOG_FILES, "*", "files: #%s# hide %s", dcc[idx].nick, par);
00622 if (ok > 1)
00623 dprintf(idx, "%s %d file%s.\n", _("Hid"), ok, ok == 1 ? "" : "s");
00624 }
00625 }
00626
00627 static void cmd_unhide(int idx, char *par)
00628 {
00629 FILE *fdb;
00630 filedb_entry *fdbe;
00631 long where;
00632 int ok = 0;
00633
00634 if (!par[0]) {
00635 dprintf(idx, "%s: unhide <file(s)>\n", _("Usage"));
00636 return;
00637 }
00638 fdb = filedb_open(dcc[idx].u.file->dir, 0);
00639 if (!fdb)
00640 return;
00641 filedb_readtop(fdb, NULL);
00642 fdbe = filedb_matchfile(fdb, ftell(fdb), par);
00643 if (!fdbe) {
00644 filedb_close(fdb);
00645 dprintf(idx, _("No matching files.\n"));
00646 return;
00647 }
00648 while (fdbe) {
00649 where = ftell(fdb);
00650 if (fdbe->stat & FILE_HIDDEN) {
00651 fdbe->stat &= ~FILE_HIDDEN;
00652 ok++;
00653 dprintf(idx, "%s: %s\n", _("Unhid"), fdbe->filename);
00654 filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_HEADER);
00655 }
00656 free_fdbe(&fdbe);
00657 fdbe = filedb_matchfile(fdb, where, par);
00658 }
00659 filedb_close(fdb);
00660 if (!ok)
00661 dprintf(idx, _("No matching files.\n"));
00662 else {
00663 putlog(LOG_FILES, "*", "files: #%s# unhide %s", dcc[idx].nick, par);
00664 if (ok > 1)
00665 dprintf(idx, "%s %d file%s.\n", _("Unhid"), ok, ok == 1 ? "" : "s");
00666 }
00667 }
00668
00669 static void cmd_desc(int idx, char *par)
00670 {
00671 char *fn, *desc, *p, *q;
00672 int ok = 0, lin;
00673 FILE *fdb;
00674 filedb_entry *fdbe;
00675 long where;
00676
00677 fn = newsplit(&par);
00678 if (!fn[0]) {
00679 dprintf(idx, "%s: desc <filename> <new description>\n", _("Usage"));
00680 return;
00681 }
00682
00683 desc = malloc(strlen(par) + 2);
00684 strcpy(desc, par);
00685 strcat(desc, "|");
00686
00687 lin = 0;
00688 q = desc;
00689 while ((*q <= 32) && (*q))
00690 strcpy(q, &q[1]);
00691 p = strchr(q, '|');
00692 while (p != NULL) {
00693
00694 *p = 0;
00695 if (strlen(q) > 60) {
00696
00697 *p = '|';
00698 p = q + 60;
00699 while ((*p != ' ') && (p != q))
00700 p--;
00701 if (p == q)
00702 *(q + 60) = '|';
00703 else
00704 *p = '|';
00705 p = strchr(q, '|');
00706 }
00707 *p = '\n';
00708 q = p + 1;
00709 lin++;
00710 while ((*q <= 32) && (*q))
00711 strcpy(q, &q[1]);
00712 if (lin == 5) {
00713 *p = 0;
00714 p = NULL;
00715 } else
00716 p = strchr(q, '|');
00717 }
00718 if (desc[strlen(desc) - 1] == '\n')
00719 desc[strlen(desc) - 1] = 0;
00720 fdb = filedb_open(dcc[idx].u.file->dir, 0);
00721 if (!fdb) {
00722 free_null(desc);
00723 return;
00724 }
00725 filedb_readtop(fdb, NULL);
00726 fdbe = filedb_matchfile(fdb, ftell(fdb), fn);
00727 if (!fdbe) {
00728 filedb_close(fdb);
00729 dprintf(idx, _("No matching files.\n"));
00730 free_null(desc);
00731 return;
00732 }
00733 while (fdbe) {
00734 where = ftell(fdb);
00735 if (!(fdbe->stat & FILE_HIDDEN)) {
00736 ok = 1;
00737 if ((!(dcc[idx].user->flags & USER_JANITOR)) &&
00738 (strcasecmp(fdbe->uploader, dcc[idx].nick)))
00739 dprintf(idx, _("You didnt upload %s\n"), fdbe->filename);
00740 else {
00741 if (desc[0]) {
00742
00743
00744
00745 if (fdbe->desc && !strcmp(fdbe->desc, desc)) {
00746 free_fdbe(&fdbe);
00747 fdbe = filedb_matchfile(fdb, where, fn);
00748 continue;
00749 }
00750 realloc_strcpy(fdbe->desc, desc);
00751 } else if (fdbe->desc) {
00752 free_null(fdbe->desc);
00753 }
00754 filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_ALL);
00755 if (par[0])
00756 dprintf(idx, "%s: %s\n", _("Changed"), fdbe->filename);
00757 else
00758 dprintf(idx, "%s: %s\n", _("Blanked"), fdbe->filename);
00759 }
00760 }
00761 free_fdbe(&fdbe);
00762 fdbe = filedb_matchfile(fdb, where, fn);
00763 }
00764 filedb_close(fdb);
00765 if (!ok)
00766 dprintf(idx, _("No matching files.\n"));
00767 else
00768 putlog(LOG_FILES, "*", "files: #%s# desc %s", dcc[idx].nick, fn);
00769 free_null(desc);
00770 }
00771
00772 static void cmd_rm(int idx, char *par)
00773 {
00774 FILE *fdb;
00775 filedb_entry *fdbe;
00776 long where;
00777 int ok = 0;
00778 char *s;
00779
00780 if (!par[0]) {
00781 dprintf(idx, "%s: rm <file(s)>\n", _("Usage"));
00782 return;
00783 }
00784 fdb = filedb_open(dcc[idx].u.file->dir, 0);
00785 if (!fdb)
00786 return;
00787 filedb_readtop(fdb, NULL);
00788 fdbe = filedb_matchfile(fdb, ftell(fdb), par);
00789 if (!fdbe) {
00790 filedb_close(fdb);
00791 dprintf(idx, _("No matching files.\n"));
00792 return;
00793 }
00794 while (fdbe) {
00795 where = ftell(fdb);
00796 if (!(fdbe->stat & (FILE_HIDDEN | FILE_DIR))) {
00797 s = malloc(strlen(dccdir) + strlen(dcc[idx].u.file->dir)
00798 + strlen(fdbe->filename) + 2);
00799 sprintf(s, "%s%s/%s", dccdir, dcc[idx].u.file->dir, fdbe->filename);
00800 ok++;
00801 filedb_delfile(fdb, fdbe->pos);
00802 unlink(s);
00803 dprintf(idx, "%s: %s\n", _("Erased"), fdbe->filename);
00804 free_null(s);
00805 }
00806 free_fdbe(&fdbe);
00807 fdbe = filedb_matchfile(fdb, where, par);
00808 }
00809 filedb_close(fdb);
00810 if (!ok)
00811 dprintf(idx, _("No matching files.\n"));
00812 else {
00813 putlog(LOG_FILES, "*", "files: #%s# rm %s", dcc[idx].nick, par);
00814 if (ok > 1)
00815 dprintf(idx, "%s %d file%s.\n", _("Erased"), ok, ok == 1 ? "" : "s");
00816 }
00817 }
00818
00819 static void cmd_mkdir(int idx, char *par)
00820 {
00821 char *name, *flags, *chan, *s;
00822 FILE *fdb;
00823 filedb_entry *fdbe;
00824 int ret;
00825 struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
00826
00827 if (!par[0]) {
00828 dprintf(idx, "%s: mkdir <dir> [required-flags] [channel]\n", _("Usage"));
00829 return;
00830 }
00831 name = newsplit(&par);
00832 ret = strlen(name);
00833 if (ret > 60)
00834 name[(ret = 60)] = 0;
00835 if (name[ret] == '/')
00836 name[ret] = 0;
00837 if (strchr(name, '/'))
00838 dprintf(idx, "You can only create directories in the current directory\n");
00839 else {
00840 flags = newsplit(&par);
00841 chan = newsplit(&par);
00842 if (!chan[0] && flags[0] && (strchr(CHANMETA, flags[0]) != NULL)) {
00843
00844
00845
00846 if(!findchan(flags) && flags[0] != '+') {
00847 dprintf(idx, "Invalid channel!\n");
00848 return;
00849 } else if(findchan(flags)) {
00850
00851 chan = flags;
00852 flags = par;
00853 }
00854
00855 }
00856 if (chan[0] && !findchan(chan)) {
00857 dprintf(idx, "Invalid channel!\n");
00858 return;
00859 }
00860 fdb = filedb_open(dcc[idx].u.file->dir, 0);
00861 if (!fdb)
00862 return;
00863 filedb_readtop(fdb, NULL);
00864 fdbe = filedb_matchfile(fdb, ftell(fdb), name);
00865 if (!fdbe) {
00866 s = malloc(strlen(dccdir) + strlen(dcc[idx].u.file->dir)
00867 + strlen(name) + 2);
00868 sprintf(s, "%s%s/%s", dccdir, dcc[idx].u.file->dir, name);
00869 if (mkdir(s, 0755) != 0) {
00870 dprintf(idx, _("Failed.\n"));
00871 filedb_close(fdb);
00872 free_null(s);
00873 return;
00874 }
00875 free_null(s);
00876 fdbe = malloc_fdbe();
00877 fdbe->stat = FILE_DIR;
00878 realloc_strcpy(fdbe->filename, name);
00879 fdbe->uploaded = now;
00880 dprintf(idx, "%s /%s%s%s\n", _("Created directory"), dcc[idx].u.file->dir,
00881 dcc[idx].u.file->dir[0] ? "/" : "", name);
00882 } else if (!(fdbe->stat & FILE_DIR)) {
00883 dprintf(idx, _("No such directory.\n"));
00884 free_fdbe(&fdbe);
00885 filedb_close(fdb);
00886 return;
00887 }
00888 if (flags[0]) {
00889 char buffer[100];
00890
00891 break_down_flags(flags, &fr, NULL);
00892 build_flags(buffer, &fr, NULL);
00893 realloc_strcpy(fdbe->flags_req, buffer);
00894 dprintf(idx, _("Changed %s/ to require +%s to access\n"), name, buffer);
00895 } else if (!chan[0]) {
00896 free_null(fdbe->flags_req);
00897 dprintf(idx, _("Changes %s/ to require no flags to access\n"), name);
00898 }
00899 if (chan[0]) {
00900 realloc_strcpy(fdbe->chan, chan);
00901 dprintf(idx, "Access set to channel: %s\n", chan);
00902 } else if (!flags[0]) {
00903 free_null(fdbe->chan);
00904 dprintf(idx, "Access set to all channels.\n");
00905 }
00906 if (!fdbe->pos)
00907 fdbe->pos = POS_NEW;
00908 filedb_updatefile(fdb, fdbe->pos, fdbe, UPDATE_ALL);
00909 filedb_close(fdb);
00910 free_fdbe(&fdbe);
00911 putlog(LOG_FILES, "*", "files: #%s# mkdir %s %s", dcc[idx].nick, name, par);
00912 }
00913 }
00914
00915 static void cmd_rmdir(int idx, char *par)
00916 {
00917 FILE *fdb;
00918 filedb_entry *fdbe;
00919 char *s, *name = NULL;
00920
00921 realloc_strcpy(name, par);
00922 if (name[strlen(name) - 1] == '/')
00923 name[strlen(name) - 1] = 0;
00924 if (strchr(name, '/'))
00925 dprintf(idx, "You can only create directories in the current directory\n");
00926 else {
00927 fdb = filedb_open(dcc[idx].u.file->dir, 0);
00928 if (!fdb) {
00929 free_null(name);
00930 return;
00931 }
00932 filedb_readtop(fdb, NULL);
00933 fdbe = filedb_matchfile(fdb, ftell(fdb), name);
00934 if (!fdbe) {
00935 dprintf(idx, _("No such directory.\n"));
00936 filedb_close(fdb);
00937 free_null(name);
00938 return;
00939 }
00940 if (!(fdbe->stat & FILE_DIR)) {
00941 dprintf(idx, _("No such directory.\n"));
00942 filedb_close(fdb);
00943 free_null(name);
00944 free_fdbe(&fdbe);
00945 return;
00946 }
00947
00948 s = malloc(strlen(dccdir) + strlen(dcc[idx].u.file->dir)
00949 + strlen(name) + 10);
00950 sprintf(s, "%s%s/%s/.filedb", dccdir, dcc[idx].u.file->dir, name);
00951 unlink(s);
00952 sprintf(s, "%s%s/%s/.files", dccdir, dcc[idx].u.file->dir, name);
00953 unlink(s);
00954 sprintf(s, "%s%s/%s", dccdir, dcc[idx].u.file->dir, name);
00955 if (rmdir(s) == 0) {
00956 dprintf(idx, "%s /%s%s%s\n", _("Removed directory"), dcc[idx].u.file->dir,
00957 dcc[idx].u.file->dir[0] ? "/" : "", name);
00958 filedb_delfile(fdb, fdbe->pos);
00959 filedb_close(fdb);
00960 free_fdbe(&fdbe);
00961 free_null(s);
00962 free_null(name);
00963 putlog(LOG_FILES, "*", "files: #%s# rmdir %s", dcc[idx].nick, name);
00964 return;
00965 }
00966 dprintf(idx, _("Failed.\n"));
00967 filedb_close(fdb);
00968 free_fdbe(&fdbe);
00969 free_null(s);
00970 free_null(name);
00971 }
00972 }
00973
00974 static void cmd_mv_cp(int idx, char *par, int copy)
00975 {
00976 char *p, *fn, *oldpath = NULL, *s = NULL, *s1, *newfn = NULL;
00977 char *newpath = NULL;
00978 int ok = 0, only_first = 0, skip_this = 0;
00979 FILE *fdb_old = NULL, *fdb_new = NULL;
00980 filedb_entry *fdbe_old = NULL, *fdbe_new = NULL;
00981 long where = 0;
00982
00983 fn = newsplit(&par);
00984 if (!par[0]) {
00985 dprintf(idx, "%s: %s <oldfilepath> <newfilepath>\n",
00986 _("Usage"), copy ? "cp" : "mv");
00987 return;
00988 }
00989 p = strrchr(fn, '/');
00990 if (p != NULL) {
00991 *p = 0;
00992 realloc_strcpy(s, fn);
00993 strcpy(fn, p + 1);
00994 if (!resolve_dir(dcc[idx].u.file->dir, s, &oldpath, idx)) {
00995 dprintf(idx, _("Illegal source directory.\n"));
00996 free_null(s);
00997 free_null(oldpath);
00998 return;
00999 }
01000 free_null(s);
01001 } else
01002 realloc_strcpy(oldpath, dcc[idx].u.file->dir);
01003 realloc_strcpy(s, par);
01004 if (!resolve_dir(dcc[idx].u.file->dir, s, &newpath, idx)) {
01005 free_null(newpath);
01006
01007 p = strrchr(s, '/');
01008 if (p == NULL) {
01009 realloc_strcpy(newfn, s);
01010 s[0] = 0;
01011 } else {
01012 *p = 0;
01013 realloc_strcpy(newfn, p + 1);
01014 }
01015 if (!resolve_dir(dcc[idx].u.file->dir, s, &newpath, idx)) {
01016 dprintf(idx, _("Illegal destination directory.\n"));
01017 free_null(newfn);
01018 free_null(s);
01019 free_null(oldpath);
01020 free_null(newpath);
01021 return;
01022 }
01023 } else
01024 realloc_strcpy(newfn, "");
01025 free_null(s);
01026
01027 if ((!strcmp(oldpath, newpath)) &&
01028 ((!newfn[0]) || (!strcmp(newfn, fn)))) {
01029 dprintf(idx, _("You cant %s files on top of themselves.\n"), copy ? _("copy") : _("move"));
01030 free_null(oldpath);
01031 free_null(newpath);
01032 free_null(newfn);
01033 return;
01034 }
01035
01036 if ((strchr(fn, '?') || strchr(fn, '*')) && newfn[0])
01037 only_first = 1;
01038 else
01039 only_first = 0;
01040
01041 fdb_old = filedb_open(oldpath, 0);
01042 if (!strcmp(oldpath, newpath))
01043 fdb_new = fdb_old;
01044 else
01045 fdb_new = filedb_open(newpath, 0);
01046 if (!fdb_old || !fdb_new) {
01047 free_null(oldpath);
01048 free_null(newpath);
01049 free_null(newfn);
01050 return;
01051 }
01052
01053 filedb_readtop(fdb_old, NULL);
01054 fdbe_old = filedb_matchfile(fdb_old, ftell(fdb_old), fn);
01055 if (!fdbe_old) {
01056 if (fdb_new != fdb_old)
01057 filedb_close(fdb_new);
01058 filedb_close(fdb_old);
01059 free_null(oldpath);
01060 free_null(newpath);
01061 free_null(newfn);
01062 return;
01063 }
01064 while (fdbe_old) {
01065 where = ftell(fdb_old);
01066 skip_this = 0;
01067 if (!(fdbe_old->stat & (FILE_HIDDEN | FILE_DIR))) {
01068 s = malloc(strlen(dccdir) + strlen(oldpath)
01069 + strlen(fdbe_old->filename) + 2);
01070 s1 = malloc(strlen(dccdir) + strlen(newpath)
01071 + strlen(newfn[0] ? newfn : fdbe_old->filename) + 2);
01072 sprintf(s, "%s%s%s%s", dccdir, oldpath,
01073 oldpath[0] ? "/" : "", fdbe_old->filename);
01074 sprintf(s1, "%s%s%s%s", dccdir, newpath,
01075 newpath[0] ? "/" : "", newfn[0] ? newfn : fdbe_old->filename);
01076 if (!strcmp(s, s1)) {
01077 dprintf(idx, "%s /%s%s%s %s\n", _("onto itself? Nuh uh."),
01078 copy ? _("copy") : _("move"), newpath,
01079 newpath[0] ? "/" : "", newfn[0] ? newfn : fdbe_old->filename);
01080 skip_this = 1;
01081 }
01082
01083 filedb_readtop(fdb_new, NULL);
01084 fdbe_new = filedb_matchfile(fdb_new, ftell(fdb_new),
01085 newfn[0] ? newfn : fdbe_old->filename);
01086 if (fdbe_new) {
01087
01088
01089
01090
01091 if (fdbe_new->stat & FILE_DIR) {
01092
01093 skip_this = 1;
01094 } else {
01095 filedb_delfile(fdb_new, fdbe_new->pos);
01096 }
01097 free_fdbe(&fdbe_new);
01098 }
01099 if (!skip_this) {
01100 if ((copy ? copyfile(s, s1) : movefile(s, s1)) == 0) {
01101
01102 ok++;
01103 fdbe_new = malloc_fdbe();
01104 fdbe_new->stat = fdbe_old->stat;
01105
01106
01107
01108 realloc_strcpy(fdbe_new->flags_req, fdbe_old->flags_req);
01109 realloc_strcpy(fdbe_new->chan, fdbe_old->chan);
01110 realloc_strcpy(fdbe_new->filename, fdbe_old->filename);
01111 realloc_strcpy(fdbe_new->desc, fdbe_old->desc);
01112 if (newfn[0])
01113 realloc_strcpy(fdbe_new->filename, newfn);
01114 realloc_strcpy(fdbe_new->uploader, fdbe_old->uploader);
01115 fdbe_new->uploaded = fdbe_old->uploaded;
01116 fdbe_new->size = fdbe_old->size;
01117 fdbe_new->gots = fdbe_old->gots;
01118 filedb_addfile(fdb_new, fdbe_new);
01119 if (!copy)
01120 filedb_delfile(fdb_old, fdbe_old->pos);
01121 free_fdbe(&fdbe_new);
01122 }
01123 }
01124 free_null(s);
01125 free_null(s1);
01126 }
01127 free_fdbe(&fdbe_old);
01128 fdbe_old = filedb_matchfile(fdb_old, where, fn);
01129 if (ok && only_first)
01130 free_fdbe(&fdbe_old);
01131 }
01132 if (fdb_old != fdb_new)
01133 filedb_close(fdb_new);
01134 filedb_close(fdb_old);
01135 if (!ok)
01136 dprintf(idx, _("No matching files.\n"));
01137 else {
01138 putlog(LOG_FILES, "*", "files: #%s# %s %s%s%s %s", dcc[idx].nick,
01139 copy ? "cp" : "mv", oldpath, oldpath[0] ? "/" : "", fn, par);
01140 if (ok > 1)
01141 dprintf(idx, "%s %d file%s.\n",
01142 copy ? _("Copied") : _("Moved"), ok, ok == 1 ? "" : "s");
01143 }
01144 free_null(oldpath);
01145 free_null(newpath);
01146 free_null(newfn);
01147 }
01148
01149 static void cmd_mv(int idx, char *par)
01150 {
01151 cmd_mv_cp(idx, par, 0);
01152 }
01153
01154 static void cmd_cp(int idx, char *par)
01155 {
01156 cmd_mv_cp(idx, par, 1);
01157 }
01158
01159 static int cmd_stats(int idx, char *par)
01160 {
01161 putlog(LOG_FILES, "*", "#%s# stats", dcc[idx].nick);
01162 my_tell_file_stats(idx, dcc[idx].nick);
01163 return 0;
01164 }
01165
01166 static int cmd_filestats(int idx, char *par)
01167 {
01168 char *nick;
01169 struct userrec *u;
01170
01171 if (!par[0]) {
01172 dprintf(idx, "Usage: filestats <user>\n");
01173 return 0;
01174 }
01175 nick = newsplit(&par);
01176 putlog(LOG_FILES, "*", "#%s# filestats %s", dcc[idx].nick, nick);
01177 if (nick[0] == 0)
01178 my_tell_file_stats(idx, dcc[idx].nick);
01179 else if (!(u = get_user_by_handle(userlist, nick)))
01180 dprintf(idx, "No such user.\n");
01181 else if (!strcmp(par, "clear") && dcc[idx].user &&
01182 (dcc[idx].user->flags & USER_JANITOR)) {
01183 set_user(&USERENTRY_FSTAT, u, NULL);
01184 dprintf(idx, "Cleared filestats for %s.\n", nick);
01185 } else
01186 my_tell_file_stats(idx, nick);
01187 return 0;
01188 }
01189
01190
01191
01192
01193 static void filesys_note(int idx, char *par)
01194 {
01195 struct userrec *u = get_user_by_handle(userlist, dcc[idx].nick);
01196 module_entry *me = module_find("notes", 2, 1);
01197
01198 if (me && me->funcs) {
01199 Function f = me->funcs[NOTES_CMD_NOTE];
01200
01201 (f) (u, idx, par);
01202 } else {
01203 dprintf(idx, "Sending of notes is not supported.\n");
01204 }
01205 }
01206
01207 static cmd_t myfiles[] =
01208 {
01209 {"cancel", "", (Function) cmd_cancel, NULL},
01210 {"cd", "", (Function) cmd_chdir, NULL},
01211 {"chdir", "", (Function) cmd_chdir, NULL},
01212 {"cp", "j", (Function) cmd_cp, NULL},
01213 {"desc", "", (Function) cmd_desc, NULL},
01214 {"filestats", "j", (Function) cmd_filestats, NULL},
01215 {"get", "", (Function) cmd_get, NULL},
01216 {"reget", "", (Function) cmd_reget, NULL},
01217 {"help", "", (Function) cmd_file_help, NULL},
01218 {"hide", "j", (Function) cmd_hide, NULL},
01219 {"ls", "", (Function) cmd_ls, NULL},
01220 {"lsa", "j", (Function) cmd_lsa, NULL},
01221 {"mkdir", "j", (Function) cmd_mkdir, NULL},
01222 {"mv", "j", (Function) cmd_mv, NULL},
01223 {"note", "", (Function) filesys_note, NULL},
01224 {"pending", "", (Function) cmd_pending, NULL},
01225 {"pwd", "", (Function) cmd_pwd, NULL},
01226 {"quit", "", (Function) CMD_LEAVE, NULL},
01227 {"rm", "j", (Function) cmd_rm, NULL},
01228 {"rmdir", "j", (Function) cmd_rmdir, NULL},
01229 {"optimize", "j", (Function) cmd_optimize, NULL},
01230 {"stats", "", (Function) cmd_stats, NULL},
01231 {"unhide", "j", (Function) cmd_unhide, NULL},
01232 {NULL, NULL, NULL, NULL}
01233 };
01234
01235
01236
01237
01238
01239
01240 static int files_reget(int idx, char *fn, char *nick, int resend)
01241 {
01242 int i = 0;
01243 char *p = NULL, *what = NULL, *destdir, *s = NULL;
01244 filedb_entry *fdbe = NULL;
01245 FILE *fdb = NULL;
01246
01247 p = strrchr(fn, '/');
01248 if (p != NULL) {
01249 *p = 0;
01250 realloc_strcpy(s, fn);
01251 realloc_strcpy(what, p + 1);
01252 if (!resolve_dir(dcc[idx].u.file->dir, s, &destdir, idx)) {
01253 free_null(s);
01254 free_null(what);
01255 free_null(destdir);
01256 return 0;
01257 }
01258 free_null(s);
01259 } else {
01260 realloc_strcpy(destdir, dcc[idx].u.file->dir);
01261 realloc_strcpy(what, fn);
01262 }
01263 fdb = filedb_open(destdir, 0);
01264 if (!fdb) {
01265 free_null(what);
01266 free_null(destdir);
01267 return 0;
01268 }
01269 filedb_readtop(fdb, NULL);
01270 fdbe = filedb_matchfile(fdb, ftell(fdb), what);
01271 if (!fdbe) {
01272 filedb_close(fdb);
01273 free_null(what);
01274 free_null(destdir);
01275 return 0;
01276 }
01277 if (fdbe->stat & (FILE_HIDDEN | FILE_DIR)) {
01278 filedb_close(fdb);
01279 free_null(what);
01280 free_null(destdir);
01281 free_fdbe(&fdbe);
01282 return 0;
01283 }
01284 filedb_close(fdb);
01285 do_dcc_send(idx, destdir, fdbe->filename, nick, resend);
01286 free_null(what);
01287 free_null(destdir);
01288 free_fdbe(&fdbe);
01289
01290 return 1;
01291 }
01292
01293 static void files_setpwd(int idx, char *where)
01294 {
01295 char *s;
01296
01297 if (!resolve_dir(dcc[idx].u.file->dir, where, &s, idx))
01298 return;
01299 strcpy(dcc[idx].u.file->dir, s);
01300 set_user(&USERENTRY_DCCDIR, get_user_by_handle(userlist, dcc[idx].nick),
01301 dcc[idx].u.file->dir);
01302 free_null(s);
01303 }