// Normalize a file path. // remove relative path component (..\ and .\), // replace slashes by backslashes, // convert to long form. // // Returns a pointer to a memory allocated block containing the normalized string. // The caller is responsible for freeing the block. // Returns NULL if the file does not exist or if a memory allocation fails. // // Precondition: the file must exist on the file system. // // Note: // - the case of the root component is preserved // - the case of rest is set to the way it is stored on the file system // // e.g. suppose the a file "C:\foo\Bar.Pdf" exists on the file system then // "c:\foo\bar.pdf" becomes "c:\foo\Bar.Pdf" // "C:\foo\BAR.PDF" becomes "C:\foo\Bar.Pdf" WCHAR *Normalize(const WCHAR *path) { // convert to absolute path, change slashes into backslashes DWORD cch = GetFullPathName(path, 0, NULL, NULL); if (!cch) return str::Dup(path); ScopedMem<WCHAR> fullpath(AllocArray<WCHAR>(cch)); GetFullPathName(path, cch, fullpath, NULL); // convert to long form cch = GetLongPathName(fullpath, NULL, 0); if (!cch) return fullpath.StealData(); ScopedMem<WCHAR> normpath(AllocArray<WCHAR>(cch)); GetLongPathName(fullpath, normpath, cch); if (cch <= MAX_PATH) return normpath.StealData(); // handle overlong paths: first, try to shorten the path cch = GetShortPathName(fullpath, NULL, 0); if (cch && cch <= MAX_PATH) { ScopedMem<WCHAR> shortpath(AllocArray<WCHAR>(cch)); GetShortPathName(fullpath, shortpath, cch); if (str::Len(path::GetBaseName(normpath)) + path::GetBaseName(shortpath) - shortpath < MAX_PATH) { // keep the long filename if possible *(WCHAR *)path::GetBaseName(shortpath) = '\0'; return str::Join(shortpath, path::GetBaseName(normpath)); } return shortpath.StealData(); } // else mark the path as overlong if (str::StartsWith(normpath.Get(), L"\\\\?\\")) return normpath.StealData(); return str::Join(L"\\\\?\\", normpath); }
int main(int argc, char **argv) { char *e; if(argc<2) { puts("gruff"); return 1; } printf("before: %s\n", argv[1]); e = shortpath(argv[1], 30, getenv("HOME")); printf("shortened to max 30 chars: %s\n", e); if(strlen(e) > 30) printf("FAILED!\n"); return 0; }
int main() { int cost[MAX][MAX]= {{INFINITE,2,4,7,INFINITE,5,INFINITE}, {2,INFINITE,INFINITE,6,3,INFINITE,8}, {4,INFINITE,INFINITE,INFINITE,INFINITE,6,INFINITE}, {7,6,INFINITE,INFINITE,INFINITE,1,6}, {INFINITE,3,INFINITE,INFINITE,INFINITE,INFINITE,7}, {5,INFINITE,6,1,INFINITE,INFINITE,6}, {INFINITE,8,INFINITE,6,7,6,INFINITE}}; int i,preced[MAX]={0},distance[MAX]; shortpath(cost,preced,distance); for(i=0;i<MAX;i++) printf("%d\n",distance[i]); return 0; }
void main() { int src,dest,predecessor[MAXNODES],d,i; //initialize predecessor for(i=0;i<MAXNODES;i++) predecessor[i] = -1; //no shortest path found thus no predecessor at starting printf("Input graph\n"); input_graph(w_graph); printf("input source and destination node\n"); scanf("%d%d",&src,&dest); shortpath(w_graph,src,dest,&d,predecessor); printf("distance = %d\n",d); printf("path \n"); for(i=0;i<MAXNODES;i++) printf("%d\t",predecessor[i]); printf("\n"); }
void main() { struct arc c[10][10]; int n,s,t,preced[10],x; clrscr(); printf("\n\t ENTER HOW MANY NODES YOU WANT: "); scanf("%d",&n); printf("\n\t ENTER \"999\" IF NO EDGE EXISTS.\n"); cost(c,n); printf("\t THE ADJACENCY MATRIX OF WEIGHT IS : "); mat(c,n); getch(); printf("\n\t ENTER SOURCE AND DESTINATION : "); scanf("%d %d",&s,&t); printf("\n\t SHORTEST PATH FROM %d TO %d IS",s,t); x=shortpath(c,s-1,t-1,preced,n); printf("\n\t THE PATH LENGTH IS %d",x); getch(); }
int main(void) { int i,j,s,t; int weight[MAXNODES][MAXNODES],precede[MAXNODES],pd; printf("\n Enter weight matrix "); for(i=0;i<MAXNODES;i++) for(j=0;j<MAXNODES;j++) scanf(" %d",&weight[i][j]); for(i=0;i<MAXNODES;i++) { printf("\n"); for(j=0;j<MAXNODES;j++) printf(" %d",weight[i][j]); } printf("\n Enter the starting node and the ending node: "); scanf(" %d %d",&s,&t); shortpath(weight,s,t,&pd,precede); printf("\n The shortest path from node %d to %d is : %d",s,t,pd); return(0); }
static int print_transfer_string(char *str, FILE *fp, transfer_info *ti, float bps, unsigned int secs, unsigned long long int eta) { int i; int len = 0; char *e = str; bool leftjust; int inescape = 0; int minlen; int number_of_dots; /* used by visual progress bar (%v) */ while(e && *e) { if(*e == '%') { leftjust = false; minlen = 0; e++; if(!*e) break; if(*e == '-') { leftjust = true; e++; } if(isdigit((int)*e)) { minlen = atoi(e); while(isdigit((int)*e)) e++; } if(leftjust) minlen = -minlen; char* sp = NULL; switch(*e) { case 'r': sp = shortpath(base_name_ptr(ti->remote_name), leftjust ? -minlen : minlen, ftp->homedir); len += max_printf(fp, minlen, "%s", sp); break; case 'R': sp = shortpath(ti->remote_name, leftjust ? -minlen : minlen, ftp->homedir); len += max_printf(fp, minlen, "%s", sp); break; case 'l': sp = shortpath(base_name_ptr(ti->local_name), leftjust ? -minlen : minlen, gvLocalHomeDir); len += max_printf(fp, minlen, "%s", sp); break; case 'L': sp = shortpath(ti->local_name, leftjust ? -minlen : minlen, gvLocalHomeDir); len += max_printf(fp, minlen, "%s", sp); break; case 's': len += max_printf(fp, minlen, "%sB", human_size(ti->size)); break; case 'S': len += max_printf(fp, minlen, "%sB", (ti->total_size == -1L ? "??" : human_size(ti->total_size))); break; case 'b': len += max_printf(fp, minlen < 2 ? minlen : minlen-2, "%sB/s", human_size(bps)); break; case 'B': if(ti->stalled >= 5) len += max_printf(fp, minlen, "%s", _("stalled")); else len += max_printf(fp, minlen < 2 ? minlen : minlen-2, "%sB/s", human_size(bps)); break; case 'e': if(eta != (unsigned) -1) len += max_printf(fp, minlen, "%s", human_time(eta)); else len += max_printf(fp, minlen, "%s", "--:--"); break; case 't': len += max_printf(fp, minlen, "%s", human_time(secs)); break; case '%': len += fprintf(fp, "%%"); break; case 'p': if(ti->total_size != -1L) len += max_printf(fp, minlen, "%.1f", (double)100*ti->size / (ti->total_size + (ti->total_size ? 0 : 1))); else len += fprintf(fp, "?"); break; case 'v': if(ti->total_size != -1L) { if(ti->total_size == ti->size) number_of_dots = minlen; else number_of_dots = (double)minlen * ti->size / (ti->total_size + 1); if(number_of_dots > minlen || number_of_dots < 0) /* just in case */ number_of_dots = minlen; i = minlen - number_of_dots; while(number_of_dots--) len += fprintf(fp, "#"); while(i--) len += fprintf(fp, " "); } else { number_of_dots = minlen / 2; i = minlen - number_of_dots; while(number_of_dots--) len += fprintf(fp, " "); if(i) { i--; len += fprintf(fp, "?"); while(i--) len += fprintf(fp, " "); } } break; case '{': inescape++; break; case '}': inescape--; break; default: len += fprintf(fp, "%%%c", *e); break; } free(sp); } else { fputc(*e, fp); if (inescape <= 0) len++; } e++; } return len; }
static void getfiles(list *gl, unsigned int opt, const char *output) { listitem *li; rfile *fp, *lnfp; const char *opath, *ofile; char *link = 0; list_sort(gl, get_sort_func, false); li = gl->first; while(li && !get_quit) { fp = (rfile *)li->data; if(!ftp_connected()) return; if(gvSighupReceived) { if(!test(opt, GET_RESUME)) opt |= GET_UNIQUE; opt |= GET_FORCE; } opath = fp->path; ofile = base_name_ptr(opath); if(strcmp(ofile, ".")==0 || strcmp(ofile, "..")==0) { transfer_nextfile(gl, &li, true); continue; } if(test(opt, GET_INTERACTIVE) && !get_batch && !gvSighupReceived) { char* sp = shortpath(opath, 42, ftp->homedir); int a = ask(ASKYES|ASKNO|ASKCANCEL|ASKALL, ASKYES, _("Get '%s'?"), sp); free(sp); if(a == ASKNO) { transfer_nextfile(gl, &li, true); continue; } if(a == ASKCANCEL) { get_quit = true; break; } if(a == ASKALL) get_batch = true; /* else a==ASKYES */ } if(rislink(fp)) { link_to_link__duh: if(test(opt, GET_NO_DEREFERENCE)) { /* link the file, don't copy */ const int r = getfile(fp, opt, output, ofile); transfer_nextfile(gl, &li, r == 0); continue; } { char *xcurdir = base_dir_xptr(opath); link = path_absolute(fp->link, xcurdir, ftp->homedir); stripslash(link); free(xcurdir); ftp_trace("found link: '%s' -> '%s'\n", opath, link); } lnfp = ftp_get_file(link); if(lnfp == 0) { /* couldn't dereference the link, try to RETR it */ ftp_trace("unable to dereference link\n"); const int r = getfile(fp, opt, output, ofile); transfer_nextfile(gl, &li, r == 0); continue; } if(strncmp(opath, lnfp->path, strlen(lnfp->path)) == 0) { ftp_trace("opath == '%s', lnfp->path == '%s'\n", opath, lnfp->path); char* sp = shortpath(lnfp->path, 42, ftp->homedir); fprintf(stderr, _("%s: circular link -- skipping\n"), sp); free(sp); transfer_nextfile(gl, &li, true); continue; } fp = lnfp; if(rislink(fp)) /* found a link pointing to another link */ /* forgive me father, for I have goto'ed */ goto link_to_link__duh; } if(risdir(fp)) { if(test(opt, GET_RECURSIVE)) { char *recurs_output; char *recurs_mask; list *rgl; if((get_dir_glob_mask && fnmatch(get_dir_glob_mask, base_name_ptr(fp->path), FNM_EXTMATCH) == FNM_NOMATCH) #ifdef HAVE_REGEX || (get_dir_rx_mask_set && regexec(&get_dir_rx_mask, base_name_ptr(fp->path), 0, 0, 0) == REG_NOMATCH) #endif ) { } else { char *q_recurs_mask; bool success = true; if(!test(opt, GET_PARENTS)) success = asprintf(&recurs_output, "%s/%s", output ? output : ".", ofile) != -1; else success = asprintf(&recurs_output, "%s", output ? output : ".") != -1; if (!success) { fprintf(stderr, _("Failed to allocate memory.\n")); transfer_nextfile(gl, &li, true); continue; } if (asprintf(&recurs_mask, "%s/*", opath) == -1) { free(recurs_output); fprintf(stderr, _("Failed to allocate memory.\n")); transfer_nextfile(gl, &li, true); continue; } rgl = rglob_create(); q_recurs_mask = backslash_quote(recurs_mask); rglob_glob(rgl, q_recurs_mask, true, true, get_exclude_func); free(q_recurs_mask); if(list_numitem(rgl) > 0) getfiles(rgl, opt, recurs_output); if(test(opt, GET_PRESERVE)) get_preserve_attribs(fp, recurs_output); rglob_destroy(rgl); free(recurs_output); } } else if(test(opt, GET_VERBOSE)) { char* sp = shortpath(opath, 42, ftp->homedir); fprintf(stderr, _("%s: omitting directory\n"), sp); free(sp); } transfer_nextfile(gl, &li, true); continue; } if(!risreg(fp)) { if(test(opt, GET_VERBOSE)) { char* sp = shortpath(opath, 42, ftp->homedir); fprintf(stderr, _("%s: not a regular file\n"), sp); free(sp); } transfer_nextfile(gl, &li, true); continue; } const int r = getfile(fp, opt, output, ofile); transfer_nextfile(gl, &li, r == 0); if(gvInterrupted) { gvInterrupted = false; if(li && !get_quit && ftp_connected() && !gvSighupReceived) { int a = ask(ASKYES|ASKNO, ASKYES, _("Continue transfer?")); if(a == ASKNO) { get_quit = true; break; } /* else a == ASKYES */ fprintf(stderr, _("Excellent!!!\n")); } } } }
/* returns: * 0 ok, remove file from list * -1 failure */ static int getfile(const rfile *fi, unsigned int opt, const char *output, const char *destname) { struct stat sb; char* dest = NULL; getmode_t how = getNormal; bool mkunique = false; int r, ret = -1; if((get_glob_mask && fnmatch(get_glob_mask, base_name_ptr(fi->path), FNM_EXTMATCH) == FNM_NOMATCH) #ifdef HAVE_REGEX || (get_rx_mask_set && regexec(&get_rx_mask, base_name_ptr(fi->path), 0, 0, 0) == REG_NOMATCH) #endif ) { return 0; } if(!output) output = "."; if(test(opt, GET_PARENTS)) { char *apath = base_dir_xptr(fi->path); if (asprintf(&dest, "%s%s/%s", output, apath, destname) == -1) { free(apath); fprintf(stderr, _("Failed to allocate memory.\n")); return -1; } free(apath); } else { /* check if -o option is given, if GET_OUTPUT_FILE is set, we only * transfer one file and output is set to the filename. However, if * the destination already exists and is a directory, we assume * that the user meant a directory */ int dest_is_file = test(opt, GET_OUTPUT_FILE); if(stat(output, &sb) == 0) { if(S_ISDIR(sb.st_mode)) { dest_is_file = false; } } if(dest_is_file) dest = xstrdup(output); else if (asprintf(&dest, "%s/%s", output, destname) == -1) { fprintf(stderr, _("Failed to allocate memory.\n")); return -1; } } /* make sure destination directory exists */ { char *destdir = base_dir_xptr(dest); if(destdir) { bool r = make_path(destdir); if(!r) { if (errno == EEXIST) ftp_err("`%s' exists but is not a directory\n", destdir); else ftp_err("%s: %s\n", destdir, strerror(errno)); transfer_mail_msg(_("Couldn't create directory: %s\n"), destdir); free(destdir); return -1; } /* change permission and group, if requested */ if(test(opt, GET_CHMOD)) { if(stat(destdir, &sb) == 0) { mode_t m = sb.st_mode; m = mode_adjust(m, cmod); if(chmod(destdir, m) != 0) perror(destdir); } } if(test(opt, GET_CHGRP)) { if(chown(destdir, -1, group_change) != 0) perror(dest); } free(destdir); } } /* check if destination file exists */ if(stat(dest, &sb) == 0) { if(test(opt, GET_SKIP_EXISTING)) { if(test(opt, GET_VERBOSE)) { char* sp = shortpath(dest, 42, gvLocalHomeDir); fprintf(stderr, _("Local file '%s' exists, skipping...\n"), sp); stats_file(STATS_SKIP, 0); free(sp); } return 0; } if(test(opt, GET_UNIQUE)) mkunique = true; else if(test(opt, GET_APPEND)) how = getAppend; else if(test(opt, GET_NEWER)) { struct tm *fan = gmtime(&sb.st_mtime); time_t ft = ftp_filetime(fi->path, test(opt, GET_FORCE_NEWER)); sb.st_mtime = gmt_mktime(fan); ftp_trace("get -n: remote file: %s", ctime(&ft)); ftp_trace("get -n: local file: %s\n", ctime(&sb.st_mtime)); if(sb.st_mtime >= ft && ft != (time_t)-1) { if(test(opt, GET_VERBOSE)) { char* sp = shortpath(dest, 30, gvLocalHomeDir); ftp_err(_( "Local file '%s' is newer than remote, skipping...\n"), sp); stats_file(STATS_SKIP, 0); free(sp); } return 0; } } else if(!test(opt, GET_RESUME)) { if(!get_owbatch && !gvSighupReceived) { struct tm *fan = gmtime(&sb.st_mtime); time_t ft = ftp_filetime(fi->path, test(opt, GET_FORCE_NEWER)); int a; char *e; sb.st_mtime = gmt_mktime(fan); e = xstrdup(ctime(&sb.st_mtime)); char* sp = shortpath(dest, 42, gvLocalHomeDir); a = ask(ASKYES|ASKNO|ASKUNIQUE|ASKCANCEL|ASKALL|ASKRESUME, ASKRESUME, _("Local file '%s' exists\nLocal: %lld bytes, %sRemote: %lld bytes, %sOverwrite?"), sp, (unsigned long long) sb.st_size, e ? e : "unknown date\n", ftp_filesize(fi->path), ctime(&ft)); free(sp); free(e); if(a == ASKCANCEL) { get_quit = true; return 0; } else if(a == ASKNO) return 0; else if(a == ASKUNIQUE) mkunique = true; else if(a == ASKALL) { get_owbatch = true; } else if(a == ASKRESUME) opt |= GET_RESUME; /* for this file only */ /* else a == ASKYES */ } } if(test(opt, GET_RESUME)) how = getResume; } if(mkunique) { char* newdest = make_unique_filename(dest); free(dest); dest = newdest; } /* the file doesn't exist or we choosed to overwrite it, or changed dest */ if(rislink(fi) && test(opt, GET_NO_DEREFERENCE)) { /* remove any existing destination */ unlink(dest); ftp_err(_("symlinking '%s' to '%s'\n"), dest, fi->link); if(symlink(fi->link, dest) != 0) perror(dest); ret = 0; } else { r = do_the_get(fi->path, dest, how, opt); if(r == 0) { stats_file(STATS_SUCCESS, ftp->ti.total_size); ret = 0; if(test(opt, GET_PRESERVE)) get_preserve_attribs(fi, dest); if(test(opt, GET_CHMOD)) { mode_t m = rfile_getmode(fi); m = mode_adjust(m, cmod); if(chmod(dest, m) != 0) perror(dest); } if(test(opt, GET_CHGRP)) { if(chown(dest, -1, group_change) != 0) perror(dest); } if(test(opt, GET_DELETE_AFTER)) { bool dodel = false; char* sp = shortpath(fi->path, 42, ftp->homedir); if(!test(opt, GET_FORCE) && !get_delbatch && !gvSighupReceived) { int a = ask(ASKYES|ASKNO|ASKCANCEL|ASKALL, ASKYES, _("Delete remote file '%s'?"), sp); if(a == ASKALL) { get_delbatch = true; dodel = true; } else if(a == ASKCANCEL) get_quit = true; else if(a != ASKNO) dodel = true; } else dodel = true; if(dodel) { ftp_unlink(fi->path); if(ftp->code == ctComplete) fprintf(stderr, _("%s: deleted\n"), sp); else fprintf(stderr, _("error deleting '%s': %s\n"), sp, ftp_getreply(false)); } free(sp); } } else { stats_file(STATS_FAIL, 0); ret = -1; } } free(dest); return ret; }
char *expand_prompt(const char *fmt) { unsigned maxlen; char *ins, *e; bool freeins; char *tmp; if(!fmt) return 0; char* prompt = (char *)xmalloc(strlen(fmt)+1); char* cp = prompt; while(fmt && *fmt) { if(*fmt == '%') { fmt++; ins = 0; freeins = false; maxlen = (unsigned)-1; if(isdigit((int)*fmt)) { maxlen = (unsigned)atoi(fmt); while(isdigit((int)*fmt)) fmt++; } switch(*fmt) { case 'c': if (asprintf(&ins, "%u", list_numitem(gvFtpList)) == -1) { fprintf(stderr, _("Failed to allocate memory.\n")); free(prompt); return NULL; } freeins = true; break; case 'C': if (asprintf(&ins, "%u", connection_number()) == -1) { fprintf(stderr, _("Failed to allocate memory.\n")); free(prompt); return NULL; } freeins = true; break; case 'u': /* username */ ins = ftp_loggedin() ? ftp->url->username : "******"; break; case 'h': /* remote hostname (as passed to cmd_open()) */ ins = ftp_connected() ? ftp->url->hostname : "?"; break; case 'H': /* %h up to first '.' */ if(!ftp_connected()) { ins = "?"; break; } e = strchr(ftp->url->hostname, '.'); if(e) { ins = xstrndup(ftp->url->hostname, e - ftp->url->hostname); freeins = true; } else ins = ftp->url->hostname; break; case 'm': /* remote machine name (as returned from gethostbynmame) */ ins = xstrdup(ftp_connected() ? host_getoname(ftp->host) : "?"); freeins = true; break; case 'M': /* %m up to first '.' */ if(!ftp_connected()) { ins = "?"; break; } e = strchr(host_getoname(ftp->host), '.'); if(e) { ins = xstrndup(host_getoname(ftp->host), e - host_getoname(ftp->host)); } else ins = xstrdup(host_getoname(ftp->host)); freeins = true; break; case 'n': /* remote ip number */ ins = xstrdup(ftp_connected() ? host_getoname(ftp->host) : "?"); freeins = true; break; case 'w': /* current remote directory */ if(!ftp_loggedin()) { ins = "?"; break; } ins = shortpath(ftp->curdir, maxlen, 0); freeins = true; break; case 'W': /* basename(%w) */ if(!ftp_loggedin()) { ins = "?"; break; } ins = (char *)base_name_ptr(ftp->curdir); break; case '~': /* %w but homedir replaced with '~' */ if(!ftp_loggedin()) { ins = "?"; break; } ins = shortpath(ftp->curdir, maxlen, ftp->homedir); freeins = true; break; case 'l': /* current local directory */ tmp = getcwd(NULL, 0); ins = shortpath(tmp, maxlen, 0); freeins = true; free(tmp); break; case 'L': /* basename(%l) */ tmp = getcwd(NULL, 0); ins = (char *)base_name_ptr(tmp); free(tmp); break; case '%': /* percent sign */ ins = "%"; break; case '#': /* local user == root ? '#' : '$' */ ins = getuid() == 0 ? "#" : "$"; break; case '{': /* begin non-printable character string */ #ifdef HAVE_LIBREADLINE ins = "\001\001"; /* \001 + RL_PROMPT_START_IGNORE */ #endif break; case '}': /* end non-printable character string */ #ifdef HAVE_LIBREADLINE ins = "\001\002"; /* \001 + RL_PROMPT_END_IGNORE */ #endif break; case 'e': /* escape (0x1B) */ ins = "\x1B"; break; default: /* illegal format specifier */ break; } if(ins) { const size_t len = strlen(prompt) + strlen(ins) + strlen(fmt+1) + 1; char* tmp = xmalloc(len); strlcpy(tmp, prompt, len); strlcat(tmp, ins, len); cp = tmp + strlen(prompt) + strlen(ins); free(prompt); prompt = tmp; if(freeins) free(ins); } } else *cp++ = *fmt; fmt++; } unquote_escapes(prompt); return prompt; }
static void putfiles(list *gl, unsigned opt, const char *output) { struct stat sb; char *path = 0; const char *file; listitem *li; list_sort(gl, put_sort_func, false); for(li=gl->first; li && !put_quit; li=li->next) { if(!ftp_connected()) return; if(gvSighupReceived) { if(!test(opt, PUT_RESUME)) opt |= PUT_UNIQUE; opt |= PUT_FORCE; } path = (char *)li->data; file = base_name_ptr(path); if(strcmp(file, ".") == 0 || strcmp(file, "..") == 0) continue; if(test(opt, PUT_INTERACTIVE) && !put_batch) { int a = ask(ASKYES|ASKNO|ASKCANCEL|ASKALL, ASKYES, _("Put '%s'?"), shortpath(path, 42, gvLocalHomeDir)); if(a == ASKNO) continue; if(a == ASKCANCEL) { put_quit = true; break; } if(a == ASKALL) put_batch = true; /* else a==ASKYES */ } if(stat(path, &sb) != 0) { perror(path); continue; } if(S_ISDIR(sb.st_mode)) { if(test(opt, PUT_RECURSIVE)) { char *recurs_output; char *recurs_mask; list *rgl; int r; if((put_dir_glob_mask && fnmatch(put_dir_glob_mask, base_name_ptr(path), FNM_EXTMATCH) == FNM_NOMATCH) #ifdef HAVE_REGEX || (put_dir_rx_mask_set && regexec(&put_dir_rx_mask, base_name_ptr(path), 0, 0, 0) == REG_NOMATCH) #endif ) { /*printf("skipping %s\n", path);*/ } else { if(!test(opt, PUT_PARENTS)) { asprintf(&recurs_output, "%s/%s", output ? output : ".", file); } else recurs_output = xstrdup(output ? output : "."); asprintf(&recurs_mask, "%s/*", path); rgl = lglob_create(); r = lglob_glob(rgl, recurs_mask, true, put_exclude_func); free(recurs_mask); if(list_numitem(rgl) > 0) putfiles(rgl, opt, recurs_output); free(recurs_output); } } else fprintf(stderr, _("%s: omitting directory\n"), shortpath(path, 42, gvLocalHomeDir)); continue; } if(!S_ISREG(sb.st_mode)) { fprintf(stderr, _("%s: not a regular file\n"), shortpath(path, 42, gvLocalHomeDir)); continue; } putfile(path, &sb, opt, output); if(gvInterrupted) { gvInterrupted = false; if(li->next && !put_quit && ftp_connected() && !gvSighupReceived) { int a = ask(ASKYES|ASKNO, ASKYES, _("Continue transfer?")); if(a == ASKNO) { put_quit = true; break; } /* else a == ASKYES */ fprintf(stderr, _("Excellent!!!\n")); } } } }
static void putfile(const char *path, struct stat *sb, unsigned opt, const char *output) { putmode_t how = putNormal; bool file_exists = false; char *dest, *dpath; int r; bool dir_created; char *dest_dir, *q_dest_dir; if((put_glob_mask && fnmatch(put_glob_mask, base_name_ptr(path), FNM_EXTMATCH) == FNM_NOMATCH) #ifdef HAVE_REGEX || (put_rx_mask_set && regexec(&put_rx_mask, base_name_ptr(path), 0, 0, 0) == REG_NOMATCH) #endif ) return; if(!output) output = "."; if(test(opt, PUT_PARENTS)) { char *p = base_dir_xptr(path); asprintf(&dest, "%s/%s/%s", output, p, base_name_ptr(path)); free(p); } else if(test(opt, PUT_OUTPUT_FILE)) dest = xstrdup(output); else asprintf(&dest, "%s/%s", output, base_name_ptr(path)); path_collapse(dest); /* make sure destination directory exists */ dpath = base_dir_xptr(dest); dest_dir = ftp_path_absolute(dpath); q_dest_dir = bash_backslash_quote(dest_dir); r = ftp_mkpath(q_dest_dir); free(q_dest_dir); free(dest_dir); if(r == -1) { transfer_mail_msg(_("failed to create directory %s\n"), dest_dir); free(dpath); free(dest); return; } dir_created = (r == 1); if(!dir_created && !test(opt, PUT_UNIQUE) && !test(opt, PUT_FORCE)) { rfile *f; f = ftp_get_file(dest); file_exists = (f != 0); if(f && risdir(f)) { /* can't overwrite a directory */ printf(_("%s: is a directory\n"), dest); free(dest); return; } } if(test(opt, PUT_APPEND)) { how = putAppend; } else if(file_exists) { if(test(opt, PUT_SKIP_EXISTING)) { printf(_("Remote file '%s' exists, skipping...\n"), shortpath(dest, 42, ftp->homedir)); free(dest); return; } else if(test(opt, PUT_NEWER)) { time_t ft = ftp_filetime(dest); if(ft != (time_t)-1 && ft >= sb->st_mtime) { printf(_("Remote file '%s' is newer than local, skipping...\n"), shortpath(dest, 42, ftp->homedir)); free(dest); return; } } else if(!test(opt, PUT_RESUME)) { if(!put_owbatch) { struct tm *fan = gmtime(&sb->st_mtime); time_t ft; int a; rfile *f; char *e; f = ftp_get_file(dest); ft = ftp_filetime(f->path); sb->st_mtime = gmt_mktime(fan); e = xstrdup(ctime(&sb->st_mtime)); a = ask(ASKYES|ASKNO|ASKUNIQUE|ASKCANCEL|ASKALL|ASKRESUME, ASKRESUME, _("Remote file '%s' exists\nLocal: %lld bytes, %sRemote: %lld bytes, %sOverwrite?"), shortpath(dest, 42, ftp->homedir), (unsigned long long) sb->st_size, e ? e : "unknown size", ftp_filesize(f->path), ctime(&ft)); free(e); if(a == ASKCANCEL) { put_quit = true; free(dest); return; } else if(a == ASKNO) { free(dest); return; } else if(a == ASKUNIQUE) opt |= PUT_UNIQUE; /* for this file only */ else if(a == ASKALL) put_owbatch = true; else if(a == ASKRESUME) opt |= PUT_RESUME; /* for this file only */ /* else a == ASKYES */ } } } if(test(opt, PUT_RESUME)) how = putResume; if(test(opt, PUT_UNIQUE)) how = putUnique; r = do_the_put(path, dest, how, opt); free(dest); if(r != 0) return; if(test(opt, PUT_PRESERVE)) { if(ftp->has_site_chmod_command) ftp_chmod(ftp->ti.local_name, get_mode_string(sb->st_mode)); } if(test(opt, PUT_DELETE_AFTER)) { bool dodel = false; if(!test(opt, PUT_FORCE) && !put_delbatch) { int a = ask(ASKYES|ASKNO|ASKCANCEL|ASKALL, ASKYES, _("Delete local file '%s'?"), shortpath(path, 42, gvLocalHomeDir)); if(a == ASKALL) { put_delbatch = true; dodel = true; } else if(a == ASKCANCEL) put_quit = true; else if(a != ASKNO) dodel = true; } else dodel = true; if(dodel) { if(unlink(path) == 0) printf(_("%s: deleted\n"), shortpath(path, 42, gvLocalHomeDir)); else printf(_("error deleting '%s': %s\n"), shortpath(path, 42, gvLocalHomeDir), strerror(errno)); } } }
void cmd_bookmark(int argc, char **argv) { struct option longopts[] = { {"save", optional_argument, 0, 's'}, {"edit", no_argument, 0, 'e'}, {"read", optional_argument, 0, 'r'}, {"delete", no_argument, 0, 'd'}, {"list", no_argument, 0, 'l'}, {"noupdate", no_argument, 0, 'u'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; int action = BM_BOOKMARK; int c; char *bmfile = 0; optind = 0; while((c=getopt_long(argc, argv, "s::er::dluh", longopts, 0)) != EOF) { switch(c) { case 's': action = BM_SAVE; free(bmfile); bmfile = xstrdup(optarg); break; case 'e': action = BM_EDIT; break; case 'r': action = BM_READ; free(bmfile); bmfile = xstrdup(optarg); break; case 'd': action = BM_DELETE; break; case 'l': action = BM_LIST; break; case 'u': action = BM_TOGGLE_NOUPDATE; break; case 'h': print_bookmark_syntax(); /* fall through */ default: return; } } if(action == BM_SAVE) { bookmark_save(bmfile); if(bmfile) printf(_("bookmarks saved in %s\n"), bmfile); else printf(_("bookmarks saved in %s/bookmarks\n"), gvWorkingDirectory); return; } if(action == BM_READ) { char *tmp = 0; int ret; list_clear(gvBookmarks); if(bmfile) ret = parse_rc(bmfile, true); else { if (asprintf(&tmp, "%s/bookmarks", gvWorkingDirectory) == -1) { fprintf(stderr, _("Failed to allocate memory.\n")); return; } ret = parse_rc(tmp, false); } if(ret != -1) printf(_("bookmarks read from %s\n"), bmfile ? bmfile : tmp); free(tmp); return; } if(action == BM_EDIT) { invoke_shell("%s %s/bookmarks", gvEditor, gvWorkingDirectory); return; } if(action == BM_LIST) { listitem *li; printf(_("%zu bookmarks present in memory\n"), list_numitem(gvBookmarks)); for(li = gvBookmarks->first; li; li=li->next) { url_t *u = (url_t *)li->data; /* note: all info not printed */ printf("%-20s", u->alias ? u->alias : u->hostname); printf("%s://%s@%s", u->protocol ? u->protocol : "ftp", u->username, u->hostname); if(u->directory) { char* sp = shortpath(u->directory, 30, 0); printf("/%s", sp); free(sp); } putchar('\n'); } return; } if(action == BM_DELETE) { int i; bool del_done = false; minargs(optind); for(i = optind; i < argc; i++) { listitem *li; while((li = list_search(gvBookmarks, (listsearchfunc)urlcmp_name, argv[i])) != 0) { url_t *u = (url_t *)li->data; printf(_("deleted bookmark %s\n"), u->alias ? u->alias : u->hostname); list_delitem(gvBookmarks, li); del_done = true; } } if(del_done) { bookmark_save(0); printf(_("bookmarks saved in %s/bookmarks\n"), gvWorkingDirectory); } return; } if(action == BM_TOGGLE_NOUPDATE) { int i; bool toggle_done = false; if(argc == optind) { listitem *li; need_connected(); need_loggedin(); li = list_search(gvBookmarks, (listsearchfunc)urlcmp_name, ftp->url->alias); if(li) { url_t *u = (url_t *)li->data; u->noupdate = !u->noupdate; printf(_("%s: noupdate: %s\n"), u->alias ? u->alias : u->hostname, u->noupdate ? _("yes") : _("no")); toggle_done = true; } ftp->url->noupdate = !ftp->url->noupdate; if(!toggle_done) printf(_("%s: noupdate: %s\n"), ftp->url->alias ? ftp->url->alias : ftp->url->hostname, ftp->url->noupdate ? _("yes") : _("no")); } for(i = optind; i < argc; i++) { listitem *li; li = list_search(gvBookmarks, (listsearchfunc)urlcmp_name, argv[i]); if(li) { url_t *u = (url_t *)li->data; u->noupdate = !u->noupdate; printf(_("%s: noupdate: %s\n"), u->alias ? u->alias : u->hostname, u->noupdate ? _("yes") : _("no")); toggle_done = true; } } if(toggle_done) { bookmark_save(0); printf(_("bookmarks saved in %s/bookmarks\n"), gvWorkingDirectory); } return; } maxargs(1); need_connected(); need_loggedin(); create_bookmark(argc > 1 ? argv[1] : 0); }
CString CPathUtils::GetLongPathname(const CString& path) { if (path.IsEmpty()) return path; TCHAR pathbufcanonicalized[MAX_PATH]; // MAX_PATH ok. DWORD ret = 0; CString sRet = path; if (!PathIsURL(path) && PathIsRelative(path)) { ret = GetFullPathName(path, 0, NULL, NULL); if (ret) { std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret+1]); if ((ret = GetFullPathName(path, ret, pathbuf.get(), NULL))!=0) { sRet = CString(pathbuf.get(), ret); } } } else if (PathCanonicalize(pathbufcanonicalized, path)) { ret = ::GetLongPathName(pathbufcanonicalized, NULL, 0); if (ret == 0) return path; std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret+2]); ret = ::GetLongPathName(pathbufcanonicalized, pathbuf.get(), ret+1); // GetFullPathName() sometimes returns the full path with the wrong // case. This is not a problem on Windows since its filesystem is // case-insensitive. But for SVN that's a problem if the wrong case // is inside a working copy: the svn wc database is case sensitive. // To fix the casing of the path, we use a trick: // convert the path to its short form, then back to its long form. // That will fix the wrong casing of the path. int shortret = ::GetShortPathName(pathbuf.get(), NULL, 0); if (shortret) { std::unique_ptr<TCHAR[]> shortpath(new TCHAR[shortret+2]); if (::GetShortPathName(pathbuf.get(), shortpath.get(), shortret+1)) { int ret2 = ::GetLongPathName(shortpath.get(), pathbuf.get(), ret+1); if (ret2) sRet = CString(pathbuf.get(), ret2); } } } else { ret = ::GetLongPathName(path, NULL, 0); if (ret == 0) return path; std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret+2]); ret = ::GetLongPathName(path, pathbuf.get(), ret+1); sRet = CString(pathbuf.get(), ret); // fix the wrong casing of the path. See above for details. int shortret = ::GetShortPathName(pathbuf.get(), NULL, 0); if (shortret) { std::unique_ptr<TCHAR[]> shortpath(new TCHAR[shortret+2]); if (::GetShortPathName(pathbuf.get(), shortpath.get(), shortret+1)) { int ret2 = ::GetLongPathName(shortpath.get(), pathbuf.get(), ret+1); if (ret2) sRet = CString(pathbuf.get(), ret2); } } } if (ret == 0) return path; return sRet; }
static int fxpfile(const rfile *fi, unsigned int opt, const char *output, const char *destname) { fxpmode_t how = fxpNormal; bool file_exists = false; char *dest, *dpath; bool dir_created; char *dest_dir, *q_dest_dir; Ftp *thisftp = ftp; if((fxp_glob_mask && fnmatch(fxp_glob_mask, base_name_ptr(fi->path), 0) == FNM_NOMATCH) #ifdef HAVE_REGEX || (fxp_rx_mask_set && regexec(&fxp_rx_mask, base_name_ptr(fi->path), 0, 0, 0) == REG_NOMATCH) #endif ) return 0; if(!output) output = "."; if(test(opt, FXP_PARENTS)) { char *p = base_dir_xptr(fi->path); if (asprintf(&dest, "%s/%s/%s", output, p, base_name_ptr(fi->path)) == -1) { fprintf(stderr, _("Failed to allocate memory.\n")); free(p); return -1; } free(p); } else if(test(opt, FXP_OUTPUT_FILE)) dest = xstrdup(output); else if (asprintf(&dest, "%s/%s", output, base_name_ptr(fi->path)) == -1) { fprintf(stderr, _("Failed to allocate memory.\n")); return -1; } path_collapse(dest); ftp_use(fxp_target); /* make sure destination directory exists */ dpath = base_dir_xptr(dest); dest_dir = ftp_path_absolute(dpath); q_dest_dir = backslash_quote(dest_dir); int r = ftp_mkpath(q_dest_dir); free(q_dest_dir); free(dest_dir); if(r == -1) { transfer_mail_msg(_("Couldn't create directory: %s\n"), dest_dir); free(dpath); free(dest); ftp_use(thisftp); return -1; } dir_created = (r == 1); if(!dir_created && !test(opt, FXP_UNIQUE) && !test(opt, FXP_FORCE)) { rfile *f; f = ftp_get_file(dest); file_exists = (f != 0); if(f && risdir(f)) { /* can't overwrite a directory */ printf(_("%s: is a directory\n"), dest); free(dest); return 0; } } if(test(opt, FXP_APPEND)) { how = fxpAppend; } else if(file_exists) { if(test(opt, FXP_SKIP_EXISTING)) { char* sp = shortpath(dest, 42, ftp->homedir); printf(_("Remote file '%s' exists, skipping...\n"), sp); free(sp); free(dest); ftp_use(thisftp); return 0; } else if(test(opt, FXP_NEWER)) { time_t src_ft; time_t dst_ft; ftp_use(thisftp); src_ft = ftp_filetime(fi->path, test(opt, FXP_FORCE_NEWER)); ftp_use(fxp_target); dst_ft = ftp_filetime(dest, test(opt, FXP_FORCE_NEWER)); if(src_ft != (time_t)-1 && dst_ft != (time_t)-1 && dst_ft >= src_ft) { char* sp = shortpath(dest, 42, ftp->homedir); printf(_("Remote file '%s' is newer than local, skipping...\n"), sp); free(sp); free(dest); ftp_use(thisftp); return 0; } } else if(!test(opt, FXP_RESUME)) { if(!fxp_owbatch) { char* sp = shortpath(dest, 42, ftp->homedir); int a = ask(ASKYES|ASKNO|ASKUNIQUE|ASKCANCEL|ASKALL|ASKRESUME, ASKRESUME, _("File '%s' exists, overwrite?"), sp); free(sp); if(a == ASKCANCEL) { fxp_quit = true; free(dest); ftp_use(thisftp); return 0; } else if(a == ASKNO) { free(dest); ftp_use(thisftp); return 0; } else if(a == ASKUNIQUE) opt |= FXP_UNIQUE; /* for this file only */ else if(a == ASKALL) fxp_owbatch = true; else if(a == ASKRESUME) opt |= FXP_RESUME; /* for this file only */ /* else a == ASKYES */ } } } if(test(opt, FXP_RESUME)) how = fxpResume; if(test(opt, FXP_UNIQUE)) how = fxpUnique; r = do_the_fxp(thisftp, fi->path, fxp_target, dest, how, opt); free(dest); if(r != 0) { ftp_use(thisftp); return -1; } if(test(opt, FXP_PRESERVE)) fxp_preserve_attribs(fi, dest); if(test(opt, FXP_DELETE_AFTER)) { bool dodel = false; ftp_use(thisftp); if(!test(opt, FXP_FORCE) && !fxp_delbatch && !gvSighupReceived) { char* sp = shortpath(fi->path, 42, ftp->homedir); int a = ask(ASKYES|ASKNO|ASKCANCEL|ASKALL, ASKYES, _("Delete remote file '%s'?"), sp); free(sp); if(a == ASKALL) { fxp_delbatch = true; dodel = true; } else if(a == ASKCANCEL) fxp_quit = true; else if(a != ASKNO) dodel = true; } else dodel = true; if(dodel) { ftp_unlink(fi->path); char* sp = shortpath(fi->path, 42, ftp->homedir); if(ftp->code == ctComplete) fprintf(stderr, _("%s: deleted\n"), sp); else fprintf(stderr, _("error deleting '%s': %s\n"), sp, ftp_getreply(false)); free(sp); } } ftp_use(thisftp); return 0; }