tramp-sh.el 195 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116
  1. ;;; tramp-sh.el --- Tramp access functions for (s)sh-like connections
  2. ;; Copyright (C) 1998-2012 Free Software Foundation, Inc.
  3. ;; (copyright statements below in code to be updated with the above notice)
  4. ;; Author: Kai Großjohann <kai.grossjohann@gmx.net>
  5. ;; Michael Albinus <michael.albinus@gmx.de>
  6. ;; Keywords: comm, processes
  7. ;; Package: tramp
  8. ;; This file is part of GNU Emacs.
  9. ;; GNU Emacs is free software: you can redistribute it and/or modify
  10. ;; it under the terms of the GNU General Public License as published by
  11. ;; the Free Software Foundation, either version 3 of the License, or
  12. ;; (at your option) any later version.
  13. ;; GNU Emacs is distributed in the hope that it will be useful,
  14. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. ;; GNU General Public License for more details.
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  19. ;;; Code:
  20. (eval-when-compile (require 'cl)) ; ignore-errors
  21. (require 'tramp)
  22. ;; Pacify byte-compiler. The function is needed on XEmacs only. I'm
  23. ;; not sure at all that this is the right way to do it, but let's hope
  24. ;; it works for now, and wait for a guru to point out the Right Way to
  25. ;; achieve this.
  26. ;;(eval-when-compile
  27. ;; (unless (fboundp 'dired-insert-set-properties)
  28. ;; (fset 'dired-insert-set-properties 'ignore)))
  29. ;; Gerd suggests this:
  30. (eval-when-compile (require 'dired))
  31. ;; Note that dired is required at run-time, too, when it is needed.
  32. ;; It is only needed on XEmacs for the function
  33. ;; `dired-insert-set-properties'.
  34. (defcustom tramp-inline-compress-start-size 4096
  35. "*The minimum size of compressing where inline transfer.
  36. When inline transfer, compress transferred data of file
  37. whose size is this value or above (up to `tramp-copy-size-limit').
  38. If it is nil, no compression at all will be applied."
  39. :group 'tramp
  40. :type '(choice (const nil) integer))
  41. (defcustom tramp-copy-size-limit 10240
  42. "*The maximum file size where inline copying is preferred over an out-of-the-band copy.
  43. If it is nil, inline out-of-the-band copy will be used without a check."
  44. :group 'tramp
  45. :type '(choice (const nil) integer))
  46. ;;;###tramp-autoload
  47. (defcustom tramp-terminal-type "dumb"
  48. "*Value of TERM environment variable for logging in to remote host.
  49. Because Tramp wants to parse the output of the remote shell, it is easily
  50. confused by ANSI color escape sequences and suchlike. Often, shell init
  51. files conditionalize this setup based on the TERM environment variable."
  52. :group 'tramp
  53. :type 'string)
  54. (defconst tramp-color-escape-sequence-regexp "\e[[;0-9]+m"
  55. "Escape sequences produced by the \"ls\" command.")
  56. ;; ksh on OpenBSD 4.5 requires that $PS1 contains a `#' character for
  57. ;; root users. It uses the `$' character for other users. In order
  58. ;; to guarantee a proper prompt, we use "#$ " for the prompt.
  59. (defvar tramp-end-of-output
  60. (format
  61. "///%s#$"
  62. (md5 (concat (prin1-to-string process-environment) (current-time-string))))
  63. "String used to recognize end of output.
  64. The '$' character at the end is quoted; the string cannot be
  65. detected as prompt when being sent on echoing hosts, therefore.")
  66. ;;;###tramp-autoload
  67. (defconst tramp-initial-end-of-output "#$ "
  68. "Prompt when establishing a connection.")
  69. ;; Initialize `tramp-methods' with the supported methods.
  70. ;;;###tramp-autoload
  71. (add-to-list 'tramp-methods
  72. '("rcp"
  73. (tramp-login-program "rsh")
  74. (tramp-login-args (("%h") ("-l" "%u")))
  75. (tramp-remote-shell "/bin/sh")
  76. (tramp-remote-shell-args ("-c"))
  77. (tramp-copy-program "rcp")
  78. (tramp-copy-args (("-p" "%k") ("-r")))
  79. (tramp-copy-keep-date t)
  80. (tramp-copy-recursive t)))
  81. ;;;###tramp-autoload
  82. (add-to-list 'tramp-methods
  83. '("remcp"
  84. (tramp-login-program "remsh")
  85. (tramp-login-args (("%h") ("-l" "%u")))
  86. (tramp-remote-shell "/bin/sh")
  87. (tramp-remote-shell-args ("-c"))
  88. (tramp-copy-program "rcp")
  89. (tramp-copy-args (("-p" "%k")))
  90. (tramp-copy-keep-date t)))
  91. ;;;###tramp-autoload
  92. (add-to-list 'tramp-methods
  93. '("scp"
  94. (tramp-login-program "ssh")
  95. (tramp-login-args (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h")))
  96. (tramp-async-args (("-q")))
  97. (tramp-remote-shell "/bin/sh")
  98. (tramp-remote-shell-args ("-c"))
  99. (tramp-copy-program "scp")
  100. (tramp-copy-args (("-P" "%p") ("-p" "%k") ("-q") ("-r")))
  101. (tramp-copy-keep-date t)
  102. (tramp-copy-recursive t)
  103. (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null")
  104. ("-o" "UserKnownHostsFile=/dev/null")
  105. ("-o" "StrictHostKeyChecking=no")))
  106. (tramp-default-port 22)))
  107. ;;;###tramp-autoload
  108. (add-to-list 'tramp-methods
  109. '("scp1"
  110. (tramp-login-program "ssh")
  111. (tramp-login-args (("-l" "%u") ("-p" "%p")
  112. ("-1") ("-e" "none") ("%h")))
  113. (tramp-async-args (("-q")))
  114. (tramp-remote-shell "/bin/sh")
  115. (tramp-remote-shell-args ("-c"))
  116. (tramp-copy-program "scp")
  117. (tramp-copy-args (("-1") ("-P" "%p") ("-p" "%k") ("-q") ("-r")))
  118. (tramp-copy-keep-date t)
  119. (tramp-copy-recursive t)
  120. (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null")
  121. ("-o" "UserKnownHostsFile=/dev/null")
  122. ("-o" "StrictHostKeyChecking=no")))
  123. (tramp-default-port 22)))
  124. ;;;###tramp-autoload
  125. (add-to-list 'tramp-methods
  126. '("scp2"
  127. (tramp-login-program "ssh")
  128. (tramp-login-args (("-l" "%u") ("-p" "%p")
  129. ("-2") ("-e" "none") ("%h")))
  130. (tramp-async-args (("-q")))
  131. (tramp-remote-shell "/bin/sh")
  132. (tramp-remote-shell-args ("-c"))
  133. (tramp-copy-program "scp")
  134. (tramp-copy-args (("-2") ("-P" "%p") ("-p" "%k") ("-q") ("-r")))
  135. (tramp-copy-keep-date t)
  136. (tramp-copy-recursive t)
  137. (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null")
  138. ("-o" "UserKnownHostsFile=/dev/null")
  139. ("-o" "StrictHostKeyChecking=no")))
  140. (tramp-default-port 22)))
  141. ;;;###tramp-autoload
  142. (add-to-list 'tramp-methods
  143. '("scpc"
  144. (tramp-login-program "ssh")
  145. (tramp-login-args (("-l" "%u") ("-p" "%p")
  146. ("-o" "ControlPath=%t.%%r@%%h:%%p")
  147. ("-o" "ControlMaster=yes")
  148. ("-e" "none") ("%h")))
  149. (tramp-async-args (("-q")))
  150. (tramp-remote-shell "/bin/sh")
  151. (tramp-remote-shell-args ("-c"))
  152. (tramp-copy-program "scp")
  153. (tramp-copy-args (("-P" "%p") ("-p" "%k") ("-q") ("-r")
  154. ("-o" "ControlPath=%t.%%r@%%h:%%p")
  155. ("-o" "ControlMaster=auto")))
  156. (tramp-copy-keep-date t)
  157. (tramp-copy-recursive t)
  158. (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null")
  159. ("-o" "UserKnownHostsFile=/dev/null")
  160. ("-o" "StrictHostKeyChecking=no")))
  161. (tramp-default-port 22)))
  162. ;;;###tramp-autoload
  163. (add-to-list 'tramp-methods
  164. '("scpx"
  165. (tramp-login-program "ssh")
  166. (tramp-login-args (("-l" "%u") ("-p" "%p")
  167. ("-e" "none") ("-t" "-t")
  168. ("%h") ("/bin/sh")))
  169. (tramp-async-args (("-q")))
  170. (tramp-remote-shell "/bin/sh")
  171. (tramp-remote-shell-args ("-c"))
  172. (tramp-copy-program "scp")
  173. (tramp-copy-args (("-P" "%p") ("-p" "%k") ("-q") ("-r")))
  174. (tramp-copy-keep-date t)
  175. (tramp-copy-recursive t)
  176. (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null")
  177. ("-o" "UserKnownHostsFile=/dev/null")
  178. ("-o" "StrictHostKeyChecking=no")))
  179. (tramp-default-port 22)))
  180. ;;;###tramp-autoload
  181. (add-to-list 'tramp-methods
  182. '("sftp"
  183. (tramp-login-program "ssh")
  184. (tramp-login-args (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h")))
  185. (tramp-async-args (("-q")))
  186. (tramp-remote-shell "/bin/sh")
  187. (tramp-remote-shell-args ("-c"))
  188. (tramp-copy-program "sftp")))
  189. ;;;###tramp-autoload
  190. (add-to-list 'tramp-methods
  191. '("rsync"
  192. (tramp-login-program "ssh")
  193. (tramp-login-args (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h")))
  194. (tramp-async-args (("-q")))
  195. (tramp-remote-shell "/bin/sh")
  196. (tramp-remote-shell-args ("-c"))
  197. (tramp-copy-program "rsync")
  198. (tramp-copy-args (("-e" "ssh") ("-t" "%k") ("-r")))
  199. (tramp-copy-keep-date t)
  200. (tramp-copy-keep-tmpfile t)
  201. (tramp-copy-recursive t)))
  202. ;;;###tramp-autoload
  203. (add-to-list 'tramp-methods
  204. `("rsyncc"
  205. (tramp-login-program "ssh")
  206. (tramp-login-args (("-l" "%u") ("-p" "%p")
  207. ("-o" "ControlPath=%t.%%r@%%h:%%p")
  208. ("-o" "ControlMaster=yes")
  209. ("-e" "none") ("%h")))
  210. (tramp-async-args (("-q")))
  211. (tramp-remote-shell "/bin/sh")
  212. (tramp-remote-shell-args ("-c"))
  213. (tramp-copy-program "rsync")
  214. (tramp-copy-args (("-t" "%k") ("-r")))
  215. (tramp-copy-env (("RSYNC_RSH")
  216. (,(concat
  217. "ssh"
  218. " -o ControlPath=%t.%%r@%%h:%%p"
  219. " -o ControlMaster=auto"))))
  220. (tramp-copy-keep-date t)
  221. (tramp-copy-keep-tmpfile t)
  222. (tramp-copy-recursive t)))
  223. ;;;###tramp-autoload
  224. (add-to-list 'tramp-methods
  225. '("rsh"
  226. (tramp-login-program "rsh")
  227. (tramp-login-args (("%h") ("-l" "%u")))
  228. (tramp-remote-shell "/bin/sh")
  229. (tramp-remote-shell-args ("-c"))))
  230. ;;;###tramp-autoload
  231. (add-to-list 'tramp-methods
  232. '("remsh"
  233. (tramp-login-program "remsh")
  234. (tramp-login-args (("%h") ("-l" "%u")))
  235. (tramp-remote-shell "/bin/sh")
  236. (tramp-remote-shell-args ("-c"))))
  237. ;;;###tramp-autoload
  238. (add-to-list 'tramp-methods
  239. '("ssh"
  240. (tramp-login-program "ssh")
  241. (tramp-login-args (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h")))
  242. (tramp-async-args (("-q")))
  243. (tramp-remote-shell "/bin/sh")
  244. (tramp-remote-shell-args ("-c"))
  245. (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null")
  246. ("-o" "UserKnownHostsFile=/dev/null")
  247. ("-o" "StrictHostKeyChecking=no")))
  248. (tramp-default-port 22)))
  249. ;;;###tramp-autoload
  250. (add-to-list 'tramp-methods
  251. '("ssh1"
  252. (tramp-login-program "ssh")
  253. (tramp-login-args (("-l" "%u") ("-p" "%p")
  254. ("-1") ("-e" "none") ("%h")))
  255. (tramp-async-args (("-q")))
  256. (tramp-remote-shell "/bin/sh")
  257. (tramp-remote-shell-args ("-c"))
  258. (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null")
  259. ("-o" "UserKnownHostsFile=/dev/null")
  260. ("-o" "StrictHostKeyChecking=no")))
  261. (tramp-default-port 22)))
  262. ;;;###tramp-autoload
  263. (add-to-list 'tramp-methods
  264. '("ssh2"
  265. (tramp-login-program "ssh")
  266. (tramp-login-args (("-l" "%u") ("-p" "%p")
  267. ("-2") ("-e" "none") ("%h")))
  268. (tramp-async-args (("-q")))
  269. (tramp-remote-shell "/bin/sh")
  270. (tramp-remote-shell-args ("-c"))
  271. (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null")
  272. ("-o" "UserKnownHostsFile=/dev/null")
  273. ("-o" "StrictHostKeyChecking=no")))
  274. (tramp-default-port 22)))
  275. ;;;###tramp-autoload
  276. (add-to-list 'tramp-methods
  277. '("sshx"
  278. (tramp-login-program "ssh")
  279. (tramp-login-args (("-l" "%u") ("-p" "%p")
  280. ("-e" "none") ("-t" "-t")
  281. ("%h") ("/bin/sh")))
  282. (tramp-async-args (("-q")))
  283. (tramp-remote-shell "/bin/sh")
  284. (tramp-remote-shell-args ("-c"))
  285. (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null")
  286. ("-o" "UserKnownHostsFile=/dev/null")
  287. ("-o" "StrictHostKeyChecking=no")))
  288. (tramp-default-port 22)))
  289. ;;;###tramp-autoload
  290. (add-to-list 'tramp-methods
  291. '("telnet"
  292. (tramp-login-program "telnet")
  293. (tramp-login-args (("%h") ("%p")))
  294. (tramp-remote-shell "/bin/sh")
  295. (tramp-remote-shell-args ("-c"))
  296. (tramp-default-port 23)))
  297. ;;;###tramp-autoload
  298. (add-to-list 'tramp-methods
  299. '("su"
  300. (tramp-login-program "su")
  301. (tramp-login-args (("-") ("%u")))
  302. (tramp-remote-shell "/bin/sh")
  303. (tramp-remote-shell-args ("-c"))))
  304. ;;;###tramp-autoload
  305. (add-to-list 'tramp-methods
  306. '("sudo"
  307. (tramp-login-program "sudo")
  308. (tramp-login-args (("-u" "%u") ("-s") ("-H") ("-p" "Password:")))
  309. (tramp-remote-shell "/bin/sh")
  310. (tramp-remote-shell-args ("-c"))))
  311. ;;;###tramp-autoload
  312. (add-to-list 'tramp-methods
  313. '("ksu"
  314. (tramp-login-program "ksu")
  315. (tramp-login-args (("%u") ("-q")))
  316. (tramp-remote-shell "/bin/sh")
  317. (tramp-remote-shell-args ("-c"))))
  318. ;;;###tramp-autoload
  319. (add-to-list 'tramp-methods
  320. '("krlogin"
  321. (tramp-login-program "krlogin")
  322. (tramp-login-args (("%h") ("-l" "%u") ("-x")))
  323. (tramp-remote-shell "/bin/sh")
  324. (tramp-remote-shell-args ("-c"))))
  325. ;;;###tramp-autoload
  326. (add-to-list 'tramp-methods
  327. '("plink"
  328. (tramp-login-program "plink")
  329. (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%h")))
  330. (tramp-remote-shell "/bin/sh")
  331. (tramp-remote-shell-args ("-c"))
  332. (tramp-password-end-of-line "xy") ;see docstring for "xy"
  333. (tramp-default-port 22)))
  334. ;;;###tramp-autoload
  335. (add-to-list 'tramp-methods
  336. '("plink1"
  337. (tramp-login-program "plink")
  338. (tramp-login-args (("-l" "%u") ("-P" "%p") ("-1" "-ssh") ("%h")))
  339. (tramp-remote-shell "/bin/sh")
  340. (tramp-remote-shell-args ("-c"))
  341. (tramp-password-end-of-line "xy") ;see docstring for "xy"
  342. (tramp-default-port 22)))
  343. ;;;###tramp-autoload
  344. (add-to-list 'tramp-methods
  345. `("plinkx"
  346. (tramp-login-program "plink")
  347. ;; ("%h") must be a single element, see
  348. ;; `tramp-compute-multi-hops'.
  349. (tramp-login-args (("-load") ("%h") ("-t")
  350. (,(format
  351. "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'"
  352. tramp-terminal-type
  353. tramp-initial-end-of-output))
  354. ("/bin/sh")))
  355. (tramp-remote-shell "/bin/sh")
  356. (tramp-remote-shell-args ("-c"))))
  357. ;;;###tramp-autoload
  358. (add-to-list 'tramp-methods
  359. '("pscp"
  360. (tramp-login-program "plink")
  361. (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%h")))
  362. (tramp-remote-shell "/bin/sh")
  363. (tramp-remote-shell-args ("-c"))
  364. (tramp-copy-program "pscp")
  365. (tramp-copy-args (("-l" "%u") ("-P" "%p") ("-scp") ("-p" "%k")
  366. ("-q") ("-r")))
  367. (tramp-copy-keep-date t)
  368. (tramp-copy-recursive t)
  369. (tramp-password-end-of-line "xy") ;see docstring for "xy"
  370. (tramp-default-port 22)))
  371. ;;;###tramp-autoload
  372. (add-to-list 'tramp-methods
  373. '("psftp"
  374. (tramp-login-program "plink")
  375. (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%h")))
  376. (tramp-remote-shell "/bin/sh")
  377. (tramp-remote-shell-args ("-c"))
  378. (tramp-copy-program "pscp")
  379. (tramp-copy-args (("-l" "%u") ("-P" "%p") ("-sftp") ("-p" "%k")
  380. ("-q") ("-r")))
  381. (tramp-copy-keep-date t)
  382. (tramp-copy-recursive t)
  383. (tramp-password-end-of-line "xy"))) ;see docstring for "xy"
  384. ;;;###tramp-autoload
  385. (add-to-list 'tramp-methods
  386. '("fcp"
  387. (tramp-login-program "fsh")
  388. (tramp-login-args (("%h") ("-l" "%u") ("sh" "-i")))
  389. (tramp-remote-shell "/bin/sh")
  390. (tramp-remote-shell-args ("-i") ("-c"))
  391. (tramp-copy-program "fcp")
  392. (tramp-copy-args (("-p" "%k")))
  393. (tramp-copy-keep-date t)))
  394. ;;;###tramp-autoload
  395. (add-to-list 'tramp-default-method-alist
  396. `(,tramp-local-host-regexp "\\`root\\'" "su"))
  397. ;;;###tramp-autoload
  398. (add-to-list 'tramp-default-user-alist
  399. `(,(concat "\\`" (regexp-opt '("su" "sudo" "ksu")) "\\'")
  400. nil "root"))
  401. ;; Do not add "ssh" based methods, otherwise ~/.ssh/config would be ignored.
  402. ;; Do not add "plink" based methods, they ask interactively for the user.
  403. ;;;###tramp-autoload
  404. (add-to-list 'tramp-default-user-alist
  405. `(,(concat
  406. "\\`"
  407. (regexp-opt '("rcp" "remcp" "rsh" "telnet" "krlogin" "fcp"))
  408. "\\'")
  409. nil ,(user-login-name)))
  410. ;;;###tramp-autoload
  411. (defconst tramp-completion-function-alist-rsh
  412. '((tramp-parse-rhosts "/etc/hosts.equiv")
  413. (tramp-parse-rhosts "~/.rhosts"))
  414. "Default list of (FUNCTION FILE) pairs to be examined for rsh methods.")
  415. ;;;###tramp-autoload
  416. (defconst tramp-completion-function-alist-ssh
  417. '((tramp-parse-rhosts "/etc/hosts.equiv")
  418. (tramp-parse-rhosts "/etc/shosts.equiv")
  419. (tramp-parse-shosts "/etc/ssh_known_hosts")
  420. (tramp-parse-sconfig "/etc/ssh_config")
  421. (tramp-parse-shostkeys "/etc/ssh2/hostkeys")
  422. (tramp-parse-sknownhosts "/etc/ssh2/knownhosts")
  423. (tramp-parse-rhosts "~/.rhosts")
  424. (tramp-parse-rhosts "~/.shosts")
  425. (tramp-parse-shosts "~/.ssh/known_hosts")
  426. (tramp-parse-sconfig "~/.ssh/config")
  427. (tramp-parse-shostkeys "~/.ssh2/hostkeys")
  428. (tramp-parse-sknownhosts "~/.ssh2/knownhosts"))
  429. "Default list of (FUNCTION FILE) pairs to be examined for ssh methods.")
  430. ;;;###tramp-autoload
  431. (defconst tramp-completion-function-alist-telnet
  432. '((tramp-parse-hosts "/etc/hosts"))
  433. "Default list of (FUNCTION FILE) pairs to be examined for telnet methods.")
  434. ;;;###tramp-autoload
  435. (defconst tramp-completion-function-alist-su
  436. '((tramp-parse-passwd "/etc/passwd"))
  437. "Default list of (FUNCTION FILE) pairs to be examined for su methods.")
  438. ;;;###tramp-autoload
  439. (defconst tramp-completion-function-alist-putty
  440. '((tramp-parse-putty
  441. "HKEY_CURRENT_USER\\Software\\SimonTatham\\PuTTY\\Sessions"))
  442. "Default list of (FUNCTION REGISTRY) pairs to be examined for putty methods.")
  443. ;;;###tramp-autoload
  444. (eval-after-load 'tramp
  445. '(progn
  446. (tramp-set-completion-function "rcp" tramp-completion-function-alist-rsh)
  447. (tramp-set-completion-function "remcp" tramp-completion-function-alist-rsh)
  448. (tramp-set-completion-function "scp" tramp-completion-function-alist-ssh)
  449. (tramp-set-completion-function "scp1" tramp-completion-function-alist-ssh)
  450. (tramp-set-completion-function "scp2" tramp-completion-function-alist-ssh)
  451. (tramp-set-completion-function "scpc" tramp-completion-function-alist-ssh)
  452. (tramp-set-completion-function "scpx" tramp-completion-function-alist-ssh)
  453. (tramp-set-completion-function "sftp" tramp-completion-function-alist-ssh)
  454. (tramp-set-completion-function "rsync" tramp-completion-function-alist-ssh)
  455. (tramp-set-completion-function
  456. "rsyncc" tramp-completion-function-alist-ssh)
  457. (tramp-set-completion-function "rsh" tramp-completion-function-alist-rsh)
  458. (tramp-set-completion-function "remsh" tramp-completion-function-alist-rsh)
  459. (tramp-set-completion-function "ssh" tramp-completion-function-alist-ssh)
  460. (tramp-set-completion-function "ssh1" tramp-completion-function-alist-ssh)
  461. (tramp-set-completion-function "ssh2" tramp-completion-function-alist-ssh)
  462. (tramp-set-completion-function
  463. "ssh1_old" tramp-completion-function-alist-ssh)
  464. (tramp-set-completion-function
  465. "ssh2_old" tramp-completion-function-alist-ssh)
  466. (tramp-set-completion-function "sshx" tramp-completion-function-alist-ssh)
  467. (tramp-set-completion-function
  468. "telnet" tramp-completion-function-alist-telnet)
  469. (tramp-set-completion-function "su" tramp-completion-function-alist-su)
  470. (tramp-set-completion-function "sudo" tramp-completion-function-alist-su)
  471. (tramp-set-completion-function "ksu" tramp-completion-function-alist-su)
  472. (tramp-set-completion-function
  473. "krlogin" tramp-completion-function-alist-rsh)
  474. (tramp-set-completion-function "plink" tramp-completion-function-alist-ssh)
  475. (tramp-set-completion-function
  476. "plink1" tramp-completion-function-alist-ssh)
  477. (tramp-set-completion-function
  478. "plinkx" tramp-completion-function-alist-putty)
  479. (tramp-set-completion-function "pscp" tramp-completion-function-alist-ssh)
  480. (tramp-set-completion-function "fcp" tramp-completion-function-alist-ssh)))
  481. ;; "getconf PATH" yields:
  482. ;; HP-UX: /usr/bin:/usr/ccs/bin:/opt/ansic/bin:/opt/langtools/bin:/opt/fortran/bin
  483. ;; Solaris: /usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin
  484. ;; GNU/Linux (Debian, Suse): /bin:/usr/bin
  485. ;; FreeBSD: /usr/bin:/bin:/usr/sbin:/sbin: - beware trailing ":"!
  486. ;; IRIX64: /usr/bin
  487. ;;;###tramp-autoload
  488. (defcustom tramp-remote-path
  489. '(tramp-default-remote-path "/bin" "/usr/bin" "/usr/sbin" "/usr/local/bin"
  490. "/local/bin" "/local/freeware/bin" "/local/gnu/bin"
  491. "/usr/freeware/bin" "/usr/pkg/bin" "/usr/contrib/bin")
  492. "*List of directories to search for executables on remote host.
  493. For every remote host, this variable will be set buffer local,
  494. keeping the list of existing directories on that host.
  495. You can use `~' in this list, but when searching for a shell which groks
  496. tilde expansion, all directory names starting with `~' will be ignored.
  497. `Default Directories' represent the list of directories given by
  498. the command \"getconf PATH\". It is recommended to use this
  499. entry on top of this list, because these are the default
  500. directories for POSIX compatible commands. On remote hosts which
  501. do not offer the getconf command (like cygwin), the value
  502. \"/bin:/usr/bin\" is used instead of.
  503. `Private Directories' are the settings of the $PATH environment,
  504. as given in your `~/.profile'."
  505. :group 'tramp
  506. :type '(repeat (choice
  507. (const :tag "Default Directories" tramp-default-remote-path)
  508. (const :tag "Private Directories" tramp-own-remote-path)
  509. (string :tag "Directory"))))
  510. (defcustom tramp-remote-process-environment
  511. `("HISTFILE=$HOME/.tramp_history" "HISTSIZE=1" "LC_ALL=C"
  512. ,(format "TERM=%s" tramp-terminal-type)
  513. "EMACS=t" ;; Deprecated.
  514. ,(format "INSIDE_EMACS='%s,tramp:%s'" emacs-version tramp-version)
  515. "CDPATH=" "HISTORY=" "MAIL=" "MAILCHECK=" "MAILPATH=" "PAGER=\"\""
  516. "autocorrect=" "correct=")
  517. "*List of environment variables to be set on the remote host.
  518. Each element should be a string of the form ENVVARNAME=VALUE. An
  519. entry ENVVARNAME= disables the corresponding environment variable,
  520. which might have been set in the init files like ~/.profile.
  521. Special handling is applied to the PATH environment, which should
  522. not be set here. Instead, it should be set via `tramp-remote-path'."
  523. :group 'tramp
  524. :type '(repeat string))
  525. (defcustom tramp-sh-extra-args '(("/bash\\'" . "-norc -noprofile"))
  526. "*Alist specifying extra arguments to pass to the remote shell.
  527. Entries are (REGEXP . ARGS) where REGEXP is a regular expression
  528. matching the shell file name and ARGS is a string specifying the
  529. arguments.
  530. This variable is only used when Tramp needs to start up another shell
  531. for tilde expansion. The extra arguments should typically prevent the
  532. shell from reading its init file."
  533. :group 'tramp
  534. ;; This might be the wrong way to test whether the widget type
  535. ;; `alist' is available. Who knows the right way to test it?
  536. :type (if (get 'alist 'widget-type)
  537. '(alist :key-type string :value-type string)
  538. '(repeat (cons string string))))
  539. (defconst tramp-actions-before-shell
  540. '((tramp-login-prompt-regexp tramp-action-login)
  541. (tramp-password-prompt-regexp tramp-action-password)
  542. (tramp-wrong-passwd-regexp tramp-action-permission-denied)
  543. (shell-prompt-pattern tramp-action-succeed)
  544. (tramp-shell-prompt-pattern tramp-action-succeed)
  545. (tramp-yesno-prompt-regexp tramp-action-yesno)
  546. (tramp-yn-prompt-regexp tramp-action-yn)
  547. (tramp-terminal-prompt-regexp tramp-action-terminal)
  548. (tramp-process-alive-regexp tramp-action-process-alive))
  549. "List of pattern/action pairs.
  550. Whenever a pattern matches, the corresponding action is performed.
  551. Each item looks like (PATTERN ACTION).
  552. The PATTERN should be a symbol, a variable. The value of this
  553. variable gives the regular expression to search for. Note that the
  554. regexp must match at the end of the buffer, \"\\'\" is implicitly
  555. appended to it.
  556. The ACTION should also be a symbol, but a function. When the
  557. corresponding PATTERN matches, the ACTION function is called.")
  558. (defconst tramp-actions-copy-out-of-band
  559. '((tramp-password-prompt-regexp tramp-action-password)
  560. (tramp-wrong-passwd-regexp tramp-action-permission-denied)
  561. (tramp-copy-failed-regexp tramp-action-permission-denied)
  562. (tramp-process-alive-regexp tramp-action-out-of-band))
  563. "List of pattern/action pairs.
  564. This list is used for copying/renaming with out-of-band methods.
  565. See `tramp-actions-before-shell' for more info.")
  566. (defconst tramp-uudecode
  567. "(echo begin 600 /tmp/tramp.$$; tail +2) | uudecode
  568. cat /tmp/tramp.$$
  569. rm -f /tmp/tramp.$$"
  570. "Shell function to implement `uudecode' to standard output.
  571. Many systems support `uudecode -o /dev/stdout' or `uudecode -o -'
  572. for this or `uudecode -p', but some systems don't, and for them
  573. we have this shell function.")
  574. (defconst tramp-perl-file-truename
  575. "%s -e '
  576. use File::Spec;
  577. use Cwd \"realpath\";
  578. sub recursive {
  579. my ($volume, @dirs) = @_;
  580. my $real = realpath(File::Spec->catpath(
  581. $volume, File::Spec->catdir(@dirs), \"\"));
  582. if ($real) {
  583. my ($vol, $dir) = File::Spec->splitpath($real, 1);
  584. return ($vol, File::Spec->splitdir($dir));
  585. }
  586. else {
  587. my $last = pop(@dirs);
  588. ($volume, @dirs) = recursive($volume, @dirs);
  589. push(@dirs, $last);
  590. return ($volume, @dirs);
  591. }
  592. }
  593. $result = realpath($ARGV[0]);
  594. if (!$result) {
  595. my ($vol, $dir) = File::Spec->splitpath($ARGV[0], 1);
  596. ($vol, @dirs) = recursive($vol, File::Spec->splitdir($dir));
  597. $result = File::Spec->catpath($vol, File::Spec->catdir(@dirs), \"\");
  598. }
  599. if ($ARGV[0] =~ /\\/$/) {
  600. $result = $result . \"/\";
  601. }
  602. print \"\\\"$result\\\"\\n\";
  603. ' \"$1\" 2>/dev/null"
  604. "Perl script to produce output suitable for use with `file-truename'
  605. on the remote file system.
  606. Escape sequence %s is replaced with name of Perl binary.
  607. This string is passed to `format', so percent characters need to be doubled.")
  608. (defconst tramp-perl-file-name-all-completions
  609. "%s -e 'sub case {
  610. my $str = shift;
  611. if ($ARGV[2]) {
  612. return lc($str);
  613. }
  614. else {
  615. return $str;
  616. }
  617. }
  618. opendir(d, $ARGV[0]) || die(\"$ARGV[0]: $!\\nfail\\n\");
  619. @files = readdir(d); closedir(d);
  620. foreach $f (@files) {
  621. if (case(substr($f, 0, length($ARGV[1]))) eq case($ARGV[1])) {
  622. if (-d \"$ARGV[0]/$f\") {
  623. print \"$f/\\n\";
  624. }
  625. else {
  626. print \"$f\\n\";
  627. }
  628. }
  629. }
  630. print \"ok\\n\"
  631. ' \"$1\" \"$2\" \"$3\" 2>/dev/null"
  632. "Perl script to produce output suitable for use with
  633. `file-name-all-completions' on the remote file system. Escape
  634. sequence %s is replaced with name of Perl binary. This string is
  635. passed to `format', so percent characters need to be doubled.")
  636. ;; Perl script to implement `file-attributes' in a Lisp `read'able
  637. ;; output. If you are hacking on this, note that you get *no* output
  638. ;; unless this spits out a complete line, including the '\n' at the
  639. ;; end.
  640. ;; The device number is returned as "-1", because there will be a virtual
  641. ;; device number set in `tramp-sh-handle-file-attributes'.
  642. (defconst tramp-perl-file-attributes
  643. "%s -e '
  644. @stat = lstat($ARGV[0]);
  645. if (!@stat) {
  646. print \"nil\\n\";
  647. exit 0;
  648. }
  649. if (($stat[2] & 0170000) == 0120000)
  650. {
  651. $type = readlink($ARGV[0]);
  652. $type = \"\\\"$type\\\"\";
  653. }
  654. elsif (($stat[2] & 0170000) == 040000)
  655. {
  656. $type = \"t\";
  657. }
  658. else
  659. {
  660. $type = \"nil\"
  661. };
  662. $uid = ($ARGV[1] eq \"integer\") ? $stat[4] : \"\\\"\" . getpwuid($stat[4]) . \"\\\"\";
  663. $gid = ($ARGV[1] eq \"integer\") ? $stat[5] : \"\\\"\" . getgrgid($stat[5]) . \"\\\"\";
  664. printf(
  665. \"(%%s %%u %%s %%s (%%u %%u) (%%u %%u) (%%u %%u) %%u.0 %%u t (%%u . %%u) -1)\\n\",
  666. $type,
  667. $stat[3],
  668. $uid,
  669. $gid,
  670. $stat[8] >> 16 & 0xffff,
  671. $stat[8] & 0xffff,
  672. $stat[9] >> 16 & 0xffff,
  673. $stat[9] & 0xffff,
  674. $stat[10] >> 16 & 0xffff,
  675. $stat[10] & 0xffff,
  676. $stat[7],
  677. $stat[2],
  678. $stat[1] >> 16 & 0xffff,
  679. $stat[1] & 0xffff
  680. );' \"$1\" \"$2\" 2>/dev/null"
  681. "Perl script to produce output suitable for use with `file-attributes'
  682. on the remote file system.
  683. Escape sequence %s is replaced with name of Perl binary.
  684. This string is passed to `format', so percent characters need to be doubled.")
  685. (defconst tramp-perl-directory-files-and-attributes
  686. "%s -e '
  687. chdir($ARGV[0]) or printf(\"\\\"Cannot change to $ARGV[0]: $''!''\\\"\\n\"), exit();
  688. opendir(DIR,\".\") or printf(\"\\\"Cannot open directory $ARGV[0]: $''!''\\\"\\n\"), exit();
  689. @list = readdir(DIR);
  690. closedir(DIR);
  691. $n = scalar(@list);
  692. printf(\"(\\n\");
  693. for($i = 0; $i < $n; $i++)
  694. {
  695. $filename = $list[$i];
  696. @stat = lstat($filename);
  697. if (($stat[2] & 0170000) == 0120000)
  698. {
  699. $type = readlink($filename);
  700. $type = \"\\\"$type\\\"\";
  701. }
  702. elsif (($stat[2] & 0170000) == 040000)
  703. {
  704. $type = \"t\";
  705. }
  706. else
  707. {
  708. $type = \"nil\"
  709. };
  710. $uid = ($ARGV[1] eq \"integer\") ? $stat[4] : \"\\\"\" . getpwuid($stat[4]) . \"\\\"\";
  711. $gid = ($ARGV[1] eq \"integer\") ? $stat[5] : \"\\\"\" . getgrgid($stat[5]) . \"\\\"\";
  712. printf(
  713. \"(\\\"%%s\\\" %%s %%u %%s %%s (%%u %%u) (%%u %%u) (%%u %%u) %%u.0 %%u t (%%u . %%u) (%%u . %%u))\\n\",
  714. $filename,
  715. $type,
  716. $stat[3],
  717. $uid,
  718. $gid,
  719. $stat[8] >> 16 & 0xffff,
  720. $stat[8] & 0xffff,
  721. $stat[9] >> 16 & 0xffff,
  722. $stat[9] & 0xffff,
  723. $stat[10] >> 16 & 0xffff,
  724. $stat[10] & 0xffff,
  725. $stat[7],
  726. $stat[2],
  727. $stat[1] >> 16 & 0xffff,
  728. $stat[1] & 0xffff,
  729. $stat[0] >> 16 & 0xffff,
  730. $stat[0] & 0xffff);
  731. }
  732. printf(\")\\n\");' \"$1\" \"$2\" 2>/dev/null"
  733. "Perl script implementing `directory-files-attributes' as Lisp `read'able
  734. output.
  735. Escape sequence %s is replaced with name of Perl binary.
  736. This string is passed to `format', so percent characters need to be doubled.")
  737. ;; These two use base64 encoding.
  738. (defconst tramp-perl-encode-with-module
  739. "%s -MMIME::Base64 -0777 -ne 'print encode_base64($_)' 2>/dev/null"
  740. "Perl program to use for encoding a file.
  741. Escape sequence %s is replaced with name of Perl binary.
  742. This string is passed to `format', so percent characters need to be doubled.
  743. This implementation requires the MIME::Base64 Perl module to be installed
  744. on the remote host.")
  745. (defconst tramp-perl-decode-with-module
  746. "%s -MMIME::Base64 -0777 -ne 'print decode_base64($_)' 2>/dev/null"
  747. "Perl program to use for decoding a file.
  748. Escape sequence %s is replaced with name of Perl binary.
  749. This string is passed to `format', so percent characters need to be doubled.
  750. This implementation requires the MIME::Base64 Perl module to be installed
  751. on the remote host.")
  752. (defconst tramp-perl-encode
  753. "%s -e '
  754. # This script contributed by Juanma Barranquero <lektu@terra.es>.
  755. # Copyright (C) 2002-2012 Free Software Foundation, Inc.
  756. use strict;
  757. my %%trans = do {
  758. my $i = 0;
  759. map {(substr(unpack(q(B8), chr $i++), 2, 6), $_)}
  760. split //, q(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/);
  761. };
  762. binmode(\\*STDIN);
  763. # We read in chunks of 54 bytes, to generate output lines
  764. # of 72 chars (plus end of line)
  765. $/ = \\54;
  766. while (my $data = <STDIN>) {
  767. my $pad = q();
  768. # Only for the last chunk, and only if did not fill the last three-byte packet
  769. if (eof) {
  770. my $mod = length($data) %% 3;
  771. $pad = q(=) x (3 - $mod) if $mod;
  772. }
  773. # Not the fastest method, but it is simple: unpack to binary string, split
  774. # by groups of 6 bits and convert back from binary to byte; then map into
  775. # the translation table
  776. print
  777. join q(),
  778. map($trans{$_},
  779. (substr(unpack(q(B*), $data) . q(00000), 0, 432) =~ /....../g)),
  780. $pad,
  781. qq(\\n);
  782. }' 2>/dev/null"
  783. "Perl program to use for encoding a file.
  784. Escape sequence %s is replaced with name of Perl binary.
  785. This string is passed to `format', so percent characters need to be doubled.")
  786. (defconst tramp-perl-decode
  787. "%s -e '
  788. # This script contributed by Juanma Barranquero <lektu@terra.es>.
  789. # Copyright (C) 2002-2012 Free Software Foundation, Inc.
  790. use strict;
  791. my %%trans = do {
  792. my $i = 0;
  793. map {($_, substr(unpack(q(B8), chr $i++), 2, 6))}
  794. split //, q(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/)
  795. };
  796. my %%bytes = map {(unpack(q(B8), chr $_), chr $_)} 0 .. 255;
  797. binmode(\\*STDOUT);
  798. # We are going to accumulate into $pending to accept any line length
  799. # (we do not check they are <= 76 chars as the RFC says)
  800. my $pending = q();
  801. while (my $data = <STDIN>) {
  802. chomp $data;
  803. # If we find one or two =, we have reached the end and
  804. # any following data is to be discarded
  805. my $finished = $data =~ s/(==?).*/$1/;
  806. $pending .= $data;
  807. my $len = length($pending);
  808. my $chunk = substr($pending, 0, $len & ~3);
  809. $pending = substr($pending, $len & ~3 + 1);
  810. # Easy method: translate from chars to (pregenerated) six-bit packets, join,
  811. # split in 8-bit chunks and convert back to char.
  812. print join q(),
  813. map $bytes{$_},
  814. ((join q(), map {$trans{$_} || q()} split //, $chunk) =~ /......../g);
  815. last if $finished;
  816. }' 2>/dev/null"
  817. "Perl program to use for decoding a file.
  818. Escape sequence %s is replaced with name of Perl binary.
  819. This string is passed to `format', so percent characters need to be doubled.")
  820. (defconst tramp-vc-registered-read-file-names
  821. "echo \"(\"
  822. while read file; do
  823. if %s \"$file\"; then
  824. echo \"(\\\"$file\\\" \\\"file-exists-p\\\" t)\"
  825. else
  826. echo \"(\\\"$file\\\" \\\"file-exists-p\\\" nil)\"
  827. fi
  828. if %s \"$file\"; then
  829. echo \"(\\\"$file\\\" \\\"file-readable-p\\\" t)\"
  830. else
  831. echo \"(\\\"$file\\\" \\\"file-readable-p\\\" nil)\"
  832. fi
  833. done
  834. echo \")\""
  835. "Script to check existence of VC related files.
  836. It must be send formatted with two strings; the tests for file
  837. existence, and file readability. Input shall be read via
  838. here-document, otherwise the command could exceed maximum length
  839. of command line.")
  840. (defconst tramp-file-mode-type-map
  841. '((0 . "-") ; Normal file (SVID-v2 and XPG2)
  842. (1 . "p") ; fifo
  843. (2 . "c") ; character device
  844. (3 . "m") ; multiplexed character device (v7)
  845. (4 . "d") ; directory
  846. (5 . "?") ; Named special file (XENIX)
  847. (6 . "b") ; block device
  848. (7 . "?") ; multiplexed block device (v7)
  849. (8 . "-") ; regular file
  850. (9 . "n") ; network special file (HP-UX)
  851. (10 . "l") ; symlink
  852. (11 . "?") ; ACL shadow inode (Solaris, not userspace)
  853. (12 . "s") ; socket
  854. (13 . "D") ; door special (Solaris)
  855. (14 . "w")) ; whiteout (BSD)
  856. "A list of file types returned from the `stat' system call.
  857. This is used to map a mode number to a permission string.")
  858. ;; New handlers should be added here. The following operations can be
  859. ;; handled using the normal primitives: file-name-sans-versions,
  860. ;; get-file-buffer.
  861. (defconst tramp-sh-file-name-handler-alist
  862. '((load . tramp-handle-load)
  863. (make-symbolic-link . tramp-sh-handle-make-symbolic-link)
  864. (file-name-as-directory . tramp-handle-file-name-as-directory)
  865. (file-name-directory . tramp-handle-file-name-directory)
  866. (file-name-nondirectory . tramp-handle-file-name-nondirectory)
  867. (file-truename . tramp-sh-handle-file-truename)
  868. (file-exists-p . tramp-sh-handle-file-exists-p)
  869. (file-directory-p . tramp-sh-handle-file-directory-p)
  870. (file-executable-p . tramp-sh-handle-file-executable-p)
  871. (file-readable-p . tramp-sh-handle-file-readable-p)
  872. (file-regular-p . tramp-handle-file-regular-p)
  873. (file-symlink-p . tramp-handle-file-symlink-p)
  874. (file-writable-p . tramp-sh-handle-file-writable-p)
  875. (file-ownership-preserved-p . tramp-sh-handle-file-ownership-preserved-p)
  876. (file-newer-than-file-p . tramp-sh-handle-file-newer-than-file-p)
  877. (file-attributes . tramp-sh-handle-file-attributes)
  878. (file-modes . tramp-handle-file-modes)
  879. (directory-files . tramp-handle-directory-files)
  880. (directory-files-and-attributes
  881. . tramp-sh-handle-directory-files-and-attributes)
  882. (file-name-all-completions . tramp-sh-handle-file-name-all-completions)
  883. (file-name-completion . tramp-handle-file-name-completion)
  884. (add-name-to-file . tramp-sh-handle-add-name-to-file)
  885. (copy-file . tramp-sh-handle-copy-file)
  886. (copy-directory . tramp-sh-handle-copy-directory)
  887. (rename-file . tramp-sh-handle-rename-file)
  888. (set-file-modes . tramp-sh-handle-set-file-modes)
  889. (set-file-times . tramp-sh-handle-set-file-times)
  890. (make-directory . tramp-sh-handle-make-directory)
  891. (delete-directory . tramp-sh-handle-delete-directory)
  892. (delete-file . tramp-sh-handle-delete-file)
  893. (directory-file-name . tramp-handle-directory-file-name)
  894. ;; `executable-find' is not official yet.
  895. (executable-find . tramp-sh-handle-executable-find)
  896. (start-file-process . tramp-sh-handle-start-file-process)
  897. (process-file . tramp-sh-handle-process-file)
  898. (shell-command . tramp-handle-shell-command)
  899. (insert-directory . tramp-sh-handle-insert-directory)
  900. (expand-file-name . tramp-sh-handle-expand-file-name)
  901. (substitute-in-file-name . tramp-handle-substitute-in-file-name)
  902. (file-local-copy . tramp-sh-handle-file-local-copy)
  903. (file-remote-p . tramp-handle-file-remote-p)
  904. (insert-file-contents . tramp-handle-insert-file-contents)
  905. (insert-file-contents-literally
  906. . tramp-sh-handle-insert-file-contents-literally)
  907. (write-region . tramp-sh-handle-write-region)
  908. (find-backup-file-name . tramp-handle-find-backup-file-name)
  909. (make-auto-save-file-name . tramp-sh-handle-make-auto-save-file-name)
  910. (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
  911. (dired-compress-file . tramp-sh-handle-dired-compress-file)
  912. (dired-recursive-delete-directory
  913. . tramp-sh-handle-dired-recursive-delete-directory)
  914. (dired-uncache . tramp-handle-dired-uncache)
  915. (set-visited-file-modtime . tramp-sh-handle-set-visited-file-modtime)
  916. (verify-visited-file-modtime . tramp-sh-handle-verify-visited-file-modtime)
  917. (file-selinux-context . tramp-sh-handle-file-selinux-context)
  918. (set-file-selinux-context . tramp-sh-handle-set-file-selinux-context)
  919. (vc-registered . tramp-sh-handle-vc-registered))
  920. "Alist of handler functions.
  921. Operations not mentioned here will be handled by the normal Emacs functions.")
  922. ;; This must be the last entry, because `identity' always matches.
  923. ;;;###tramp-autoload
  924. (add-to-list 'tramp-foreign-file-name-handler-alist
  925. '(identity . tramp-sh-file-name-handler) 'append)
  926. ;;; File Name Handler Functions:
  927. (defun tramp-sh-handle-make-symbolic-link
  928. (filename linkname &optional ok-if-already-exists)
  929. "Like `make-symbolic-link' for Tramp files.
  930. If LINKNAME is a non-Tramp file, it is used verbatim as the target of
  931. the symlink. If LINKNAME is a Tramp file, only the localname component is
  932. used as the target of the symlink.
  933. If LINKNAME is a Tramp file and the localname component is relative, then
  934. it is expanded first, before the localname component is taken. Note that
  935. this can give surprising results if the user/host for the source and
  936. target of the symlink differ."
  937. (with-parsed-tramp-file-name linkname l
  938. (let ((ln (tramp-get-remote-ln l))
  939. (cwd (tramp-run-real-handler
  940. 'file-name-directory (list l-localname))))
  941. (unless ln
  942. (tramp-error
  943. l 'file-error
  944. "Making a symbolic link. ln(1) does not exist on the remote host."))
  945. ;; Do the 'confirm if exists' thing.
  946. (when (file-exists-p linkname)
  947. ;; What to do?
  948. (if (or (null ok-if-already-exists) ; not allowed to exist
  949. (and (numberp ok-if-already-exists)
  950. (not (yes-or-no-p
  951. (format
  952. "File %s already exists; make it a link anyway? "
  953. l-localname)))))
  954. (tramp-error
  955. l 'file-already-exists "File %s already exists" l-localname)
  956. (delete-file linkname)))
  957. ;; If FILENAME is a Tramp name, use just the localname component.
  958. (when (tramp-tramp-file-p filename)
  959. (setq filename
  960. (tramp-file-name-localname
  961. (tramp-dissect-file-name (expand-file-name filename)))))
  962. (tramp-flush-file-property l (file-name-directory l-localname))
  963. (tramp-flush-file-property l l-localname)
  964. ;; Right, they are on the same host, regardless of user, method,
  965. ;; etc. We now make the link on the remote machine. This will
  966. ;; occur as the user that FILENAME belongs to.
  967. (tramp-send-command-and-check
  968. l
  969. (format
  970. "cd %s && %s -sf %s %s"
  971. (tramp-shell-quote-argument cwd)
  972. ln
  973. (tramp-shell-quote-argument filename)
  974. (tramp-shell-quote-argument l-localname))
  975. t))))
  976. (defun tramp-sh-handle-file-truename (filename &optional counter prev-dirs)
  977. "Like `file-truename' for Tramp files."
  978. (with-parsed-tramp-file-name (expand-file-name filename) nil
  979. (tramp-make-tramp-file-name method user host
  980. (with-file-property v localname "file-truename"
  981. (let ((result nil)) ; result steps in reverse order
  982. (tramp-message v 4 "Finding true name for `%s'" filename)
  983. (cond
  984. ;; Use GNU readlink --canonicalize-missing where available.
  985. ((tramp-get-remote-readlink v)
  986. (setq result
  987. (tramp-send-command-and-read
  988. v
  989. (format "echo \"\\\"`%s --canonicalize-missing %s`\\\"\""
  990. (tramp-get-remote-readlink v)
  991. (tramp-shell-quote-argument localname)))))
  992. ;; Use Perl implementation.
  993. ((and (tramp-get-remote-perl v)
  994. (tramp-get-connection-property v "perl-file-spec" nil)
  995. (tramp-get-connection-property v "perl-cwd-realpath" nil))
  996. (tramp-maybe-send-script
  997. v tramp-perl-file-truename "tramp_perl_file_truename")
  998. (setq result
  999. (tramp-send-command-and-read
  1000. v
  1001. (format "tramp_perl_file_truename %s"
  1002. (tramp-shell-quote-argument localname)))))
  1003. ;; Do it yourself. We bind `directory-sep-char' here for
  1004. ;; XEmacs on Windows, which would otherwise use backslash.
  1005. (t (let* ((directory-sep-char ?/)
  1006. (steps (tramp-compat-split-string localname "/"))
  1007. (localnamedir (tramp-run-real-handler
  1008. 'file-name-as-directory (list localname)))
  1009. (is-dir (string= localname localnamedir))
  1010. (thisstep nil)
  1011. (numchase 0)
  1012. ;; Don't make the following value larger than
  1013. ;; necessary. People expect an error message in
  1014. ;; a timely fashion when something is wrong;
  1015. ;; otherwise they might think that Emacs is hung.
  1016. ;; Of course, correctness has to come first.
  1017. (numchase-limit 20)
  1018. symlink-target)
  1019. (while (and steps (< numchase numchase-limit))
  1020. (setq thisstep (pop steps))
  1021. (tramp-message
  1022. v 5 "Check %s"
  1023. (mapconcat 'identity
  1024. (append '("") (reverse result) (list thisstep))
  1025. "/"))
  1026. (setq symlink-target
  1027. (nth 0 (file-attributes
  1028. (tramp-make-tramp-file-name
  1029. method user host
  1030. (mapconcat 'identity
  1031. (append '("")
  1032. (reverse result)
  1033. (list thisstep))
  1034. "/")))))
  1035. (cond ((string= "." thisstep)
  1036. (tramp-message v 5 "Ignoring step `.'"))
  1037. ((string= ".." thisstep)
  1038. (tramp-message v 5 "Processing step `..'")
  1039. (pop result))
  1040. ((stringp symlink-target)
  1041. ;; It's a symlink, follow it.
  1042. (tramp-message
  1043. v 5 "Follow symlink to %s" symlink-target)
  1044. (setq numchase (1+ numchase))
  1045. (when (file-name-absolute-p symlink-target)
  1046. (setq result nil))
  1047. ;; If the symlink was absolute, we'll get a
  1048. ;; string like "/user@host:/some/target";
  1049. ;; extract the "/some/target" part from it.
  1050. (when (tramp-tramp-file-p symlink-target)
  1051. (unless (tramp-equal-remote filename symlink-target)
  1052. (tramp-error
  1053. v 'file-error
  1054. "Symlink target `%s' on wrong host"
  1055. symlink-target))
  1056. (setq symlink-target localname))
  1057. (setq steps
  1058. (append (tramp-compat-split-string
  1059. symlink-target "/")
  1060. steps)))
  1061. (t
  1062. ;; It's a file.
  1063. (setq result (cons thisstep result)))))
  1064. (when (>= numchase numchase-limit)
  1065. (tramp-error
  1066. v 'file-error
  1067. "Maximum number (%d) of symlinks exceeded" numchase-limit))
  1068. (setq result (reverse result))
  1069. ;; Combine list to form string.
  1070. (setq result
  1071. (if result
  1072. (mapconcat 'identity (cons "" result) "/")
  1073. "/"))
  1074. (when (and is-dir
  1075. (or (string= "" result)
  1076. (not (string= (substring result -1) "/"))))
  1077. (setq result (concat result "/"))))))
  1078. (tramp-message v 4 "True name of `%s' is `%s'" localname result)
  1079. result)))))
  1080. ;; Basic functions.
  1081. (defun tramp-sh-handle-file-exists-p (filename)
  1082. "Like `file-exists-p' for Tramp files."
  1083. (with-parsed-tramp-file-name filename nil
  1084. (with-file-property v localname "file-exists-p"
  1085. (or (not (null (tramp-get-file-property
  1086. v localname "file-attributes-integer" nil)))
  1087. (not (null (tramp-get-file-property
  1088. v localname "file-attributes-string" nil)))
  1089. (tramp-send-command-and-check
  1090. v
  1091. (format
  1092. "%s %s"
  1093. (tramp-get-file-exists-command v)
  1094. (tramp-shell-quote-argument localname)))))))
  1095. ;; CCC: This should check for an error condition and signal failure
  1096. ;; when something goes wrong.
  1097. ;; Daniel Pittman <daniel@danann.net>
  1098. (defun tramp-sh-handle-file-attributes (filename &optional id-format)
  1099. "Like `file-attributes' for Tramp files."
  1100. (unless id-format (setq id-format 'integer))
  1101. ;; Don't modify `last-coding-system-used' by accident.
  1102. (let ((last-coding-system-used last-coding-system-used))
  1103. (with-parsed-tramp-file-name (expand-file-name filename) nil
  1104. (with-file-property v localname (format "file-attributes-%s" id-format)
  1105. (save-excursion
  1106. (tramp-convert-file-attributes
  1107. v
  1108. (or
  1109. (cond
  1110. ((tramp-get-remote-stat v)
  1111. (tramp-do-file-attributes-with-stat v localname id-format))
  1112. ((tramp-get-remote-perl v)
  1113. (tramp-do-file-attributes-with-perl v localname id-format))
  1114. (t nil))
  1115. ;; The scripts could fail, for example with huge file size.
  1116. (tramp-do-file-attributes-with-ls v localname id-format))))))))
  1117. (defun tramp-do-file-attributes-with-ls (vec localname &optional id-format)
  1118. "Implement `file-attributes' for Tramp files using the ls(1) command."
  1119. (let (symlinkp dirp
  1120. res-inode res-filemodes res-numlinks
  1121. res-uid res-gid res-size res-symlink-target)
  1122. (tramp-message vec 5 "file attributes with ls: %s" localname)
  1123. (tramp-send-command
  1124. vec
  1125. (format "(%s %s || %s -h %s) && %s %s %s"
  1126. (tramp-get-file-exists-command vec)
  1127. (tramp-shell-quote-argument localname)
  1128. (tramp-get-test-command vec)
  1129. (tramp-shell-quote-argument localname)
  1130. (tramp-get-ls-command vec)
  1131. (if (eq id-format 'integer) "-ildn" "-ild")
  1132. (tramp-shell-quote-argument localname)))
  1133. ;; parse `ls -l' output ...
  1134. (with-current-buffer (tramp-get-buffer vec)
  1135. (when (> (buffer-size) 0)
  1136. (goto-char (point-min))
  1137. ;; ... inode
  1138. (setq res-inode
  1139. (condition-case err
  1140. (read (current-buffer))
  1141. (invalid-read-syntax
  1142. (when (and (equal (cadr err)
  1143. "Integer constant overflow in reader")
  1144. (string-match
  1145. "^[0-9]+\\([0-9][0-9][0-9][0-9][0-9]\\)\\'"
  1146. (car (cddr err))))
  1147. (let* ((big (read (substring (car (cddr err)) 0
  1148. (match-beginning 1))))
  1149. (small (read (match-string 1 (car (cddr err)))))
  1150. (twiddle (/ small 65536)))
  1151. (cons (+ big twiddle)
  1152. (- small (* twiddle 65536))))))))
  1153. ;; ... file mode flags
  1154. (setq res-filemodes (symbol-name (read (current-buffer))))
  1155. ;; ... number links
  1156. (setq res-numlinks (read (current-buffer)))
  1157. ;; ... uid and gid
  1158. (setq res-uid (read (current-buffer)))
  1159. (setq res-gid (read (current-buffer)))
  1160. (if (eq id-format 'integer)
  1161. (progn
  1162. (unless (numberp res-uid) (setq res-uid -1))
  1163. (unless (numberp res-gid) (setq res-gid -1)))
  1164. (progn
  1165. (unless (stringp res-uid) (setq res-uid (symbol-name res-uid)))
  1166. (unless (stringp res-gid) (setq res-gid (symbol-name res-gid)))))
  1167. ;; ... size
  1168. (setq res-size (read (current-buffer)))
  1169. ;; From the file modes, figure out other stuff.
  1170. (setq symlinkp (eq ?l (aref res-filemodes 0)))
  1171. (setq dirp (eq ?d (aref res-filemodes 0)))
  1172. ;; if symlink, find out file name pointed to
  1173. (when symlinkp
  1174. (search-forward "-> ")
  1175. (setq res-symlink-target (buffer-substring (point) (point-at-eol))))
  1176. ;; return data gathered
  1177. (list
  1178. ;; 0. t for directory, string (name linked to) for symbolic
  1179. ;; link, or nil.
  1180. (or dirp res-symlink-target)
  1181. ;; 1. Number of links to file.
  1182. res-numlinks
  1183. ;; 2. File uid.
  1184. res-uid
  1185. ;; 3. File gid.
  1186. res-gid
  1187. ;; 4. Last access time, as a list of two integers. First
  1188. ;; integer has high-order 16 bits of time, second has low 16
  1189. ;; bits.
  1190. ;; 5. Last modification time, likewise.
  1191. ;; 6. Last status change time, likewise.
  1192. '(0 0) '(0 0) '(0 0) ;CCC how to find out?
  1193. ;; 7. Size in bytes (-1, if number is out of range).
  1194. res-size
  1195. ;; 8. File modes, as a string of ten letters or dashes as in ls -l.
  1196. res-filemodes
  1197. ;; 9. t if file's gid would change if file were deleted and
  1198. ;; recreated. Will be set in `tramp-convert-file-attributes'
  1199. t
  1200. ;; 10. inode number.
  1201. res-inode
  1202. ;; 11. Device number. Will be replaced by a virtual device number.
  1203. -1
  1204. )))))
  1205. (defun tramp-do-file-attributes-with-perl
  1206. (vec localname &optional id-format)
  1207. "Implement `file-attributes' for Tramp files using a Perl script."
  1208. (tramp-message vec 5 "file attributes with perl: %s" localname)
  1209. (tramp-maybe-send-script
  1210. vec tramp-perl-file-attributes "tramp_perl_file_attributes")
  1211. (tramp-send-command-and-read
  1212. vec
  1213. (format "tramp_perl_file_attributes %s %s"
  1214. (tramp-shell-quote-argument localname) id-format)))
  1215. (defun tramp-do-file-attributes-with-stat
  1216. (vec localname &optional id-format)
  1217. "Implement `file-attributes' for Tramp files using stat(1) command."
  1218. (tramp-message vec 5 "file attributes with stat: %s" localname)
  1219. (tramp-send-command-and-read
  1220. vec
  1221. (format
  1222. ;; On Opsware, pdksh (which is the true name of ksh there) doesn't
  1223. ;; parse correctly the sequence "((". Therefore, we add a space.
  1224. "( (%s %s || %s -h %s) && %s -c '((\"%%N\") %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \"%%A\" t %%ie0 -1)' %s || echo nil)"
  1225. (tramp-get-file-exists-command vec)
  1226. (tramp-shell-quote-argument localname)
  1227. (tramp-get-test-command vec)
  1228. (tramp-shell-quote-argument localname)
  1229. (tramp-get-remote-stat vec)
  1230. (if (eq id-format 'integer) "%u" "\"%U\"")
  1231. (if (eq id-format 'integer) "%g" "\"%G\"")
  1232. (tramp-shell-quote-argument localname))))
  1233. (defun tramp-sh-handle-set-visited-file-modtime (&optional time-list)
  1234. "Like `set-visited-file-modtime' for Tramp files."
  1235. (unless (buffer-file-name)
  1236. (error "Can't set-visited-file-modtime: buffer `%s' not visiting a file"
  1237. (buffer-name)))
  1238. (if time-list
  1239. (tramp-run-real-handler 'set-visited-file-modtime (list time-list))
  1240. (let ((f (buffer-file-name))
  1241. coding-system-used)
  1242. (with-parsed-tramp-file-name f nil
  1243. (let* ((attr (file-attributes f))
  1244. ;; '(-1 65535) means file doesn't exists yet.
  1245. (modtime (or (nth 5 attr) '(-1 65535))))
  1246. (when (boundp 'last-coding-system-used)
  1247. (setq coding-system-used (symbol-value 'last-coding-system-used)))
  1248. ;; We use '(0 0) as a don't-know value. See also
  1249. ;; `tramp-do-file-attributes-with-ls'.
  1250. (if (not (equal modtime '(0 0)))
  1251. (tramp-run-real-handler 'set-visited-file-modtime (list modtime))
  1252. (progn
  1253. (tramp-send-command
  1254. v
  1255. (format "%s -ild %s"
  1256. (tramp-get-ls-command v)
  1257. (tramp-shell-quote-argument localname)))
  1258. (setq attr (buffer-substring (point)
  1259. (progn (end-of-line) (point)))))
  1260. (tramp-set-file-property
  1261. v localname "visited-file-modtime-ild" attr))
  1262. (when (boundp 'last-coding-system-used)
  1263. (set 'last-coding-system-used coding-system-used))
  1264. nil)))))
  1265. ;; This function makes the same assumption as
  1266. ;; `tramp-sh-handle-set-visited-file-modtime'.
  1267. (defun tramp-sh-handle-verify-visited-file-modtime (buf)
  1268. "Like `verify-visited-file-modtime' for Tramp files.
  1269. At the time `verify-visited-file-modtime' calls this function, we
  1270. already know that the buffer is visiting a file and that
  1271. `visited-file-modtime' does not return 0. Do not call this
  1272. function directly, unless those two cases are already taken care
  1273. of."
  1274. (with-current-buffer buf
  1275. (let ((f (buffer-file-name)))
  1276. ;; There is no file visiting the buffer, or the buffer has no
  1277. ;; recorded last modification time, or there is no established
  1278. ;; connection.
  1279. (if (or (not f)
  1280. (eq (visited-file-modtime) 0)
  1281. (not (tramp-file-name-handler 'file-remote-p f nil 'connected)))
  1282. t
  1283. (with-parsed-tramp-file-name f nil
  1284. (let* ((remote-file-name-inhibit-cache t)
  1285. (attr (file-attributes f))
  1286. (modtime (nth 5 attr))
  1287. (mt (visited-file-modtime)))
  1288. (cond
  1289. ;; File exists, and has a known modtime.
  1290. ((and attr (not (equal modtime '(0 0))))
  1291. (< (abs (tramp-time-diff
  1292. modtime
  1293. ;; For compatibility, deal with both the old
  1294. ;; (HIGH . LOW) and the new (HIGH LOW) return
  1295. ;; values of `visited-file-modtime'.
  1296. (if (atom (cdr mt))
  1297. (list (car mt) (cdr mt))
  1298. mt)))
  1299. 2))
  1300. ;; Modtime has the don't know value.
  1301. (attr
  1302. (tramp-send-command
  1303. v
  1304. (format "%s -ild %s"
  1305. (tramp-get-ls-command v)
  1306. (tramp-shell-quote-argument localname)))
  1307. (with-current-buffer (tramp-get-buffer v)
  1308. (setq attr (buffer-substring
  1309. (point) (progn (end-of-line) (point)))))
  1310. (equal
  1311. attr
  1312. (tramp-get-file-property
  1313. v localname "visited-file-modtime-ild" "")))
  1314. ;; If file does not exist, say it is not modified if and
  1315. ;; only if that agrees with the buffer's record.
  1316. (t (equal mt '(-1 65535))))))))))
  1317. (defun tramp-sh-handle-set-file-modes (filename mode)
  1318. "Like `set-file-modes' for Tramp files."
  1319. (with-parsed-tramp-file-name filename nil
  1320. (tramp-flush-file-property v localname)
  1321. ;; FIXME: extract the proper text from chmod's stderr.
  1322. (tramp-barf-unless-okay
  1323. v
  1324. (format "chmod %s %s"
  1325. (tramp-compat-decimal-to-octal mode)
  1326. (tramp-shell-quote-argument localname))
  1327. "Error while changing file's mode %s" filename)))
  1328. (defun tramp-sh-handle-set-file-times (filename &optional time)
  1329. "Like `set-file-times' for Tramp files."
  1330. (if (file-remote-p filename)
  1331. (with-parsed-tramp-file-name filename nil
  1332. (tramp-flush-file-property v localname)
  1333. (let ((time (if (or (null time) (equal time '(0 0)))
  1334. (current-time)
  1335. time))
  1336. ;; With GNU Emacs, `format-time-string' has an optional
  1337. ;; parameter UNIVERSAL. This is preferred, because we
  1338. ;; could handle the case when the remote host is located
  1339. ;; in a different time zone as the local host.
  1340. (utc (not (featurep 'xemacs))))
  1341. (tramp-send-command-and-check
  1342. v (format "%s touch -t %s %s"
  1343. (if utc "TZ=UTC; export TZ;" "")
  1344. (if utc
  1345. (format-time-string "%Y%m%d%H%M.%S" time t)
  1346. (format-time-string "%Y%m%d%H%M.%S" time))
  1347. (tramp-shell-quote-argument localname)))))
  1348. ;; We handle also the local part, because in older Emacsen,
  1349. ;; without `set-file-times', this function is an alias for this.
  1350. ;; We are local, so we don't need the UTC settings.
  1351. (zerop
  1352. (tramp-compat-call-process
  1353. "touch" nil nil nil "-t"
  1354. (format-time-string "%Y%m%d%H%M.%S" time)
  1355. (tramp-shell-quote-argument filename)))))
  1356. (defun tramp-set-file-uid-gid (filename &optional uid gid)
  1357. "Set the ownership for FILENAME.
  1358. If UID and GID are provided, these values are used; otherwise uid
  1359. and gid of the corresponding user is taken. Both parameters must be integers."
  1360. ;; Modern Unices allow chown only for root. So we might need
  1361. ;; another implementation, see `dired-do-chown'. OTOH, it is mostly
  1362. ;; working with su(do)? when it is needed, so it shall succeed in
  1363. ;; the majority of cases.
  1364. ;; Don't modify `last-coding-system-used' by accident.
  1365. (let ((last-coding-system-used last-coding-system-used))
  1366. (if (file-remote-p filename)
  1367. (with-parsed-tramp-file-name filename nil
  1368. (if (and (zerop (user-uid)) (tramp-local-host-p v))
  1369. ;; If we are root on the local host, we can do it directly.
  1370. (tramp-set-file-uid-gid localname uid gid)
  1371. (let ((uid (or (and (integerp uid) uid)
  1372. (tramp-get-remote-uid v 'integer)))
  1373. (gid (or (and (integerp gid) gid)
  1374. (tramp-get-remote-gid v 'integer))))
  1375. (tramp-send-command
  1376. v (format
  1377. "chown %d:%d %s" uid gid
  1378. (tramp-shell-quote-argument localname))))))
  1379. ;; We handle also the local part, because there doesn't exist
  1380. ;; `set-file-uid-gid'. On W32 "chown" might not work.
  1381. (let ((uid (or (and (integerp uid) uid) (tramp-get-local-uid 'integer)))
  1382. (gid (or (and (integerp gid) gid) (tramp-get-local-gid 'integer))))
  1383. (tramp-compat-call-process
  1384. "chown" nil nil nil
  1385. (format "%d:%d" uid gid) (tramp-shell-quote-argument filename))))))
  1386. (defun tramp-remote-selinux-p (vec)
  1387. "Check, whether SELINUX is enabled on the remote host."
  1388. (with-connection-property (tramp-get-connection-process vec) "selinux-p"
  1389. (let ((result (tramp-find-executable
  1390. vec "getenforce" (tramp-get-remote-path vec) t t)))
  1391. (and result
  1392. (string-equal
  1393. (tramp-send-command-and-read
  1394. vec (format "echo \\\"`%S`\\\"" result))
  1395. "Enforcing")))))
  1396. (defun tramp-sh-handle-file-selinux-context (filename)
  1397. "Like `file-selinux-context' for Tramp files."
  1398. (with-parsed-tramp-file-name filename nil
  1399. (with-file-property v localname "file-selinux-context"
  1400. (let ((context '(nil nil nil nil))
  1401. (regexp (concat "\\([a-z0-9_]+\\):" "\\([a-z0-9_]+\\):"
  1402. "\\([a-z0-9_]+\\):" "\\([a-z0-9_]+\\)")))
  1403. (when (and (tramp-remote-selinux-p v)
  1404. (tramp-send-command-and-check
  1405. v (format
  1406. "%s -d -Z %s"
  1407. (tramp-get-ls-command v)
  1408. (tramp-shell-quote-argument localname))))
  1409. (with-current-buffer (tramp-get-connection-buffer v)
  1410. (goto-char (point-min))
  1411. (when (re-search-forward regexp (point-at-eol) t)
  1412. (setq context (list (match-string 1) (match-string 2)
  1413. (match-string 3) (match-string 4))))))
  1414. ;; Return the context.
  1415. context))))
  1416. (defun tramp-sh-handle-set-file-selinux-context (filename context)
  1417. "Like `set-file-selinux-context' for Tramp files."
  1418. (with-parsed-tramp-file-name filename nil
  1419. (if (and (consp context)
  1420. (tramp-remote-selinux-p v)
  1421. (tramp-send-command-and-check
  1422. v (format "chcon %s %s %s %s %s"
  1423. (if (stringp (nth 0 context))
  1424. (format "--user=%s" (nth 0 context)) "")
  1425. (if (stringp (nth 1 context))
  1426. (format "--role=%s" (nth 1 context)) "")
  1427. (if (stringp (nth 2 context))
  1428. (format "--type=%s" (nth 2 context)) "")
  1429. (if (stringp (nth 3 context))
  1430. (format "--range=%s" (nth 3 context)) "")
  1431. (tramp-shell-quote-argument localname))))
  1432. (tramp-set-file-property v localname "file-selinux-context" context)
  1433. (tramp-set-file-property v localname "file-selinux-context" 'undef)))
  1434. ;; We always return nil.
  1435. nil)
  1436. ;; Simple functions using the `test' command.
  1437. (defun tramp-sh-handle-file-executable-p (filename)
  1438. "Like `file-executable-p' for Tramp files."
  1439. (with-parsed-tramp-file-name filename nil
  1440. (with-file-property v localname "file-executable-p"
  1441. ;; Examine `file-attributes' cache to see if request can be
  1442. ;; satisfied without remote operation.
  1443. (or (tramp-check-cached-permissions v ?x)
  1444. (tramp-run-test "-x" filename)))))
  1445. (defun tramp-sh-handle-file-readable-p (filename)
  1446. "Like `file-readable-p' for Tramp files."
  1447. (with-parsed-tramp-file-name filename nil
  1448. (with-file-property v localname "file-readable-p"
  1449. ;; Examine `file-attributes' cache to see if request can be
  1450. ;; satisfied without remote operation.
  1451. (or (tramp-check-cached-permissions v ?r)
  1452. (tramp-run-test "-r" filename)))))
  1453. ;; When the remote shell is started, it looks for a shell which groks
  1454. ;; tilde expansion. Here, we assume that all shells which grok tilde
  1455. ;; expansion will also provide a `test' command which groks `-nt' (for
  1456. ;; newer than). If this breaks, tell me about it and I'll try to do
  1457. ;; something smarter about it.
  1458. (defun tramp-sh-handle-file-newer-than-file-p (file1 file2)
  1459. "Like `file-newer-than-file-p' for Tramp files."
  1460. (cond ((not (file-exists-p file1))
  1461. nil)
  1462. ((not (file-exists-p file2))
  1463. t)
  1464. ;; We are sure both files exist at this point.
  1465. (t
  1466. (save-excursion
  1467. ;; We try to get the mtime of both files. If they are not
  1468. ;; equal to the "dont-know" value, then we subtract the times
  1469. ;; and obtain the result.
  1470. (let ((fa1 (file-attributes file1))
  1471. (fa2 (file-attributes file2)))
  1472. (if (and (not (equal (nth 5 fa1) '(0 0)))
  1473. (not (equal (nth 5 fa2) '(0 0))))
  1474. (> 0 (tramp-time-diff (nth 5 fa2) (nth 5 fa1)))
  1475. ;; If one of them is the dont-know value, then we can
  1476. ;; still try to run a shell command on the remote host.
  1477. ;; However, this only works if both files are Tramp
  1478. ;; files and both have the same method, same user, same
  1479. ;; host.
  1480. (unless (tramp-equal-remote file1 file2)
  1481. (with-parsed-tramp-file-name
  1482. (if (tramp-tramp-file-p file1) file1 file2) nil
  1483. (tramp-error
  1484. v 'file-error
  1485. "Files %s and %s must have same method, user, host"
  1486. file1 file2)))
  1487. (with-parsed-tramp-file-name file1 nil
  1488. (tramp-run-test2
  1489. (tramp-get-test-nt-command v) file1 file2))))))))
  1490. ;; Functions implemented using the basic functions above.
  1491. (defun tramp-sh-handle-file-directory-p (filename)
  1492. "Like `file-directory-p' for Tramp files."
  1493. (with-parsed-tramp-file-name filename nil
  1494. ;; `file-directory-p' is used as predicate for filename completion.
  1495. ;; Sometimes, when a connection is not established yet, it is
  1496. ;; desirable to return t immediately for "/method:foo:". It can
  1497. ;; be expected that this is always a directory.
  1498. (or (zerop (length localname))
  1499. (with-file-property v localname "file-directory-p"
  1500. (tramp-run-test "-d" filename)))))
  1501. (defun tramp-sh-handle-file-writable-p (filename)
  1502. "Like `file-writable-p' for Tramp files."
  1503. (with-parsed-tramp-file-name filename nil
  1504. (with-file-property v localname "file-writable-p"
  1505. (if (file-exists-p filename)
  1506. ;; Examine `file-attributes' cache to see if request can be
  1507. ;; satisfied without remote operation.
  1508. (or (tramp-check-cached-permissions v ?w)
  1509. (tramp-run-test "-w" filename))
  1510. ;; If file doesn't exist, check if directory is writable.
  1511. (and (tramp-run-test "-d" (file-name-directory filename))
  1512. (tramp-run-test "-w" (file-name-directory filename)))))))
  1513. (defun tramp-sh-handle-file-ownership-preserved-p (filename)
  1514. "Like `file-ownership-preserved-p' for Tramp files."
  1515. (with-parsed-tramp-file-name filename nil
  1516. (with-file-property v localname "file-ownership-preserved-p"
  1517. (let ((attributes (file-attributes filename)))
  1518. ;; Return t if the file doesn't exist, since it's true that no
  1519. ;; information would be lost by an (attempted) delete and create.
  1520. (or (null attributes)
  1521. (= (nth 2 attributes) (tramp-get-remote-uid v 'integer)))))))
  1522. ;; Directory listings.
  1523. (defun tramp-sh-handle-directory-files-and-attributes
  1524. (directory &optional full match nosort id-format)
  1525. "Like `directory-files-and-attributes' for Tramp files."
  1526. (unless id-format (setq id-format 'integer))
  1527. (when (file-directory-p directory)
  1528. (setq directory (expand-file-name directory))
  1529. (let* ((temp
  1530. (copy-tree
  1531. (with-parsed-tramp-file-name directory nil
  1532. (with-file-property
  1533. v localname
  1534. (format "directory-files-and-attributes-%s" id-format)
  1535. (save-excursion
  1536. (mapcar
  1537. (lambda (x)
  1538. (cons (car x)
  1539. (tramp-convert-file-attributes v (cdr x))))
  1540. (cond
  1541. ((tramp-get-remote-stat v)
  1542. (tramp-do-directory-files-and-attributes-with-stat
  1543. v localname id-format))
  1544. ((tramp-get-remote-perl v)
  1545. (tramp-do-directory-files-and-attributes-with-perl
  1546. v localname id-format)))))))))
  1547. result item)
  1548. (while temp
  1549. (setq item (pop temp))
  1550. (when (or (null match) (string-match match (car item)))
  1551. (when full
  1552. (setcar item (expand-file-name (car item) directory)))
  1553. (push item result)))
  1554. (if nosort
  1555. result
  1556. (sort result (lambda (x y) (string< (car x) (car y))))))))
  1557. (defun tramp-do-directory-files-and-attributes-with-perl
  1558. (vec localname &optional id-format)
  1559. "Implement `directory-files-and-attributes' for Tramp files using a Perl script."
  1560. (tramp-message vec 5 "directory-files-and-attributes with perl: %s" localname)
  1561. (tramp-maybe-send-script
  1562. vec tramp-perl-directory-files-and-attributes
  1563. "tramp_perl_directory_files_and_attributes")
  1564. (let ((object
  1565. (tramp-send-command-and-read
  1566. vec
  1567. (format "tramp_perl_directory_files_and_attributes %s %s"
  1568. (tramp-shell-quote-argument localname) id-format))))
  1569. (when (stringp object) (tramp-error vec 'file-error object))
  1570. object))
  1571. (defun tramp-do-directory-files-and-attributes-with-stat
  1572. (vec localname &optional id-format)
  1573. "Implement `directory-files-and-attributes' for Tramp files using stat(1) command."
  1574. (tramp-message vec 5 "directory-files-and-attributes with stat: %s" localname)
  1575. (tramp-send-command-and-read
  1576. vec
  1577. (format
  1578. (concat
  1579. ;; We must care about filenames with spaces, or starting with
  1580. ;; "-"; this would confuse xargs. "ls -aQ" might be a solution,
  1581. ;; but it does not work on all remote systems. Therefore, we
  1582. ;; quote the filenames via sed.
  1583. "cd %s; echo \"(\"; (%s -a | sed -e s/\\$/\\\"/g -e s/^/\\\"/g | xargs "
  1584. "%s -c '(\"%%n\" (\"%%N\") %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \"%%A\" t %%ie0 -1)'); "
  1585. "echo \")\"")
  1586. (tramp-shell-quote-argument localname)
  1587. (tramp-get-ls-command vec)
  1588. (tramp-get-remote-stat vec)
  1589. (if (eq id-format 'integer) "%u" "\"%U\"")
  1590. (if (eq id-format 'integer) "%g" "\"%G\""))))
  1591. ;; This function should return "foo/" for directories and "bar" for
  1592. ;; files.
  1593. (defun tramp-sh-handle-file-name-all-completions (filename directory)
  1594. "Like `file-name-all-completions' for Tramp files."
  1595. (unless (save-match-data (string-match "/" filename))
  1596. (with-parsed-tramp-file-name (expand-file-name directory) nil
  1597. (all-completions
  1598. filename
  1599. (mapcar
  1600. 'list
  1601. (or
  1602. ;; Try cache entries for filename, filename with last
  1603. ;; character removed, filename with last two characters
  1604. ;; removed, ..., and finally the empty string - all
  1605. ;; concatenated to the local directory name.
  1606. (let ((remote-file-name-inhibit-cache
  1607. (or remote-file-name-inhibit-cache
  1608. tramp-completion-reread-directory-timeout)))
  1609. ;; This is inefficient for very long filenames, pity
  1610. ;; `reduce' is not available...
  1611. (car
  1612. (apply
  1613. 'append
  1614. (mapcar
  1615. (lambda (x)
  1616. (let ((cache-hit
  1617. (tramp-get-file-property
  1618. v
  1619. (concat localname (substring filename 0 x))
  1620. "file-name-all-completions"
  1621. nil)))
  1622. (when cache-hit (list cache-hit))))
  1623. ;; We cannot use a length of 0, because file properties
  1624. ;; for "foo" and "foo/" are identical.
  1625. (tramp-compat-number-sequence (length filename) 1 -1)))))
  1626. ;; Cache expired or no matching cache entry found so we need
  1627. ;; to perform a remote operation.
  1628. (let (result)
  1629. ;; Get a list of directories and files, including reliably
  1630. ;; tagging the directories with a trailing '/'. Because I
  1631. ;; rock. --daniel@danann.net
  1632. ;; Changed to perform `cd' in the same remote op and only
  1633. ;; get entries starting with `filename'. Capture any `cd'
  1634. ;; error messages. Ensure any `cd' and `echo' aliases are
  1635. ;; ignored.
  1636. (tramp-send-command
  1637. v
  1638. (if (tramp-get-remote-perl v)
  1639. (progn
  1640. (tramp-maybe-send-script
  1641. v tramp-perl-file-name-all-completions
  1642. "tramp_perl_file_name_all_completions")
  1643. (format "tramp_perl_file_name_all_completions %s %s %d"
  1644. (tramp-shell-quote-argument localname)
  1645. (tramp-shell-quote-argument filename)
  1646. (if (symbol-value
  1647. ;; `read-file-name-completion-ignore-case'
  1648. ;; is introduced with Emacs 22.1.
  1649. (if (boundp
  1650. 'read-file-name-completion-ignore-case)
  1651. 'read-file-name-completion-ignore-case
  1652. 'completion-ignore-case))
  1653. 1 0)))
  1654. (format (concat
  1655. "(\\cd %s 2>&1 && (%s %s -a 2>/dev/null"
  1656. ;; `ls' with wildcard might fail with `Argument
  1657. ;; list too long' error in some corner cases; if
  1658. ;; `ls' fails after `cd' succeeded, chances are
  1659. ;; that's the case, so let's retry without
  1660. ;; wildcard. This will return "too many" entries
  1661. ;; but that isn't harmful.
  1662. " || %s -a 2>/dev/null)"
  1663. " | while read f; do"
  1664. " if %s -d \"$f\" 2>/dev/null;"
  1665. " then \\echo \"$f/\"; else \\echo \"$f\"; fi; done"
  1666. " && \\echo ok) || \\echo fail")
  1667. (tramp-shell-quote-argument localname)
  1668. (tramp-get-ls-command v)
  1669. ;; When `filename' is empty, just `ls' without
  1670. ;; filename argument is more efficient than `ls *'
  1671. ;; for very large directories and might avoid the
  1672. ;; `Argument list too long' error.
  1673. ;;
  1674. ;; With and only with wildcard, we need to add
  1675. ;; `-d' to prevent `ls' from descending into
  1676. ;; sub-directories.
  1677. (if (zerop (length filename))
  1678. "."
  1679. (concat (tramp-shell-quote-argument filename) "* -d"))
  1680. (tramp-get-ls-command v)
  1681. (tramp-get-test-command v))))
  1682. ;; Now grab the output.
  1683. (with-current-buffer (tramp-get-buffer v)
  1684. (goto-char (point-max))
  1685. ;; Check result code, found in last line of output.
  1686. (forward-line -1)
  1687. (if (looking-at "^fail$")
  1688. (progn
  1689. ;; Grab error message from line before last line
  1690. ;; (it was put there by `cd 2>&1').
  1691. (forward-line -1)
  1692. (tramp-error
  1693. v 'file-error
  1694. "tramp-sh-handle-file-name-all-completions: %s"
  1695. (buffer-substring (point) (point-at-eol))))
  1696. ;; For peace of mind, if buffer doesn't end in `fail'
  1697. ;; then it should end in `ok'. If neither are in the
  1698. ;; buffer something went seriously wrong on the remote
  1699. ;; side.
  1700. (unless (looking-at "^ok$")
  1701. (tramp-error
  1702. v 'file-error
  1703. "\
  1704. tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'"
  1705. (tramp-shell-quote-argument localname) (buffer-string))))
  1706. (while (zerop (forward-line -1))
  1707. (push (buffer-substring (point) (point-at-eol)) result)))
  1708. ;; Because the remote op went through OK we know the
  1709. ;; directory we `cd'-ed to exists.
  1710. (tramp-set-file-property v localname "file-exists-p" t)
  1711. ;; Because the remote op went through OK we know every
  1712. ;; file listed by `ls' exists.
  1713. (mapc (lambda (entry)
  1714. (tramp-set-file-property
  1715. v (concat localname entry) "file-exists-p" t))
  1716. result)
  1717. ;; Store result in the cache.
  1718. (tramp-set-file-property
  1719. v (concat localname filename)
  1720. "file-name-all-completions" result))))))))
  1721. ;; cp, mv and ln
  1722. (defun tramp-sh-handle-add-name-to-file
  1723. (filename newname &optional ok-if-already-exists)
  1724. "Like `add-name-to-file' for Tramp files."
  1725. (unless (tramp-equal-remote filename newname)
  1726. (with-parsed-tramp-file-name
  1727. (if (tramp-tramp-file-p filename) filename newname) nil
  1728. (tramp-error
  1729. v 'file-error
  1730. "add-name-to-file: %s"
  1731. "only implemented for same method, same user, same host")))
  1732. (with-parsed-tramp-file-name filename v1
  1733. (with-parsed-tramp-file-name newname v2
  1734. (let ((ln (when v1 (tramp-get-remote-ln v1))))
  1735. (when (and (not ok-if-already-exists)
  1736. (file-exists-p newname)
  1737. (not (numberp ok-if-already-exists))
  1738. (y-or-n-p
  1739. (format
  1740. "File %s already exists; make it a new name anyway? "
  1741. newname)))
  1742. (tramp-error
  1743. v2 'file-error
  1744. "add-name-to-file: file %s already exists" newname))
  1745. (tramp-flush-file-property v2 (file-name-directory v2-localname))
  1746. (tramp-flush-file-property v2 v2-localname)
  1747. (tramp-barf-unless-okay
  1748. v1
  1749. (format "%s %s %s" ln (tramp-shell-quote-argument v1-localname)
  1750. (tramp-shell-quote-argument v2-localname))
  1751. "error with add-name-to-file, see buffer `%s' for details"
  1752. (buffer-name))))))
  1753. (defun tramp-sh-handle-copy-file
  1754. (filename newname &optional ok-if-already-exists keep-date
  1755. preserve-uid-gid preserve-selinux-context)
  1756. "Like `copy-file' for Tramp files."
  1757. (setq filename (expand-file-name filename))
  1758. (setq newname (expand-file-name newname))
  1759. (cond
  1760. ;; At least one file a Tramp file?
  1761. ((or (tramp-tramp-file-p filename)
  1762. (tramp-tramp-file-p newname))
  1763. (tramp-do-copy-or-rename-file
  1764. 'copy filename newname ok-if-already-exists keep-date
  1765. preserve-uid-gid preserve-selinux-context))
  1766. ;; Compat section.
  1767. (preserve-selinux-context
  1768. (tramp-run-real-handler
  1769. 'copy-file
  1770. (list filename newname ok-if-already-exists keep-date
  1771. preserve-uid-gid preserve-selinux-context)))
  1772. (preserve-uid-gid
  1773. (tramp-run-real-handler
  1774. 'copy-file
  1775. (list filename newname ok-if-already-exists keep-date preserve-uid-gid)))
  1776. (t
  1777. (tramp-run-real-handler
  1778. 'copy-file (list filename newname ok-if-already-exists keep-date)))))
  1779. (defun tramp-sh-handle-copy-directory
  1780. (dirname newname &optional keep-date parents copy-contents)
  1781. "Like `copy-directory' for Tramp files."
  1782. (let ((t1 (tramp-tramp-file-p dirname))
  1783. (t2 (tramp-tramp-file-p newname)))
  1784. (with-parsed-tramp-file-name (if t1 dirname newname) nil
  1785. (if (and (tramp-get-method-parameter method 'tramp-copy-recursive)
  1786. ;; When DIRNAME and NEWNAME are remote, they must have
  1787. ;; the same method.
  1788. (or (null t1) (null t2)
  1789. (string-equal
  1790. (tramp-file-name-method (tramp-dissect-file-name dirname))
  1791. (tramp-file-name-method (tramp-dissect-file-name newname)))))
  1792. ;; scp or rsync DTRT.
  1793. (progn
  1794. (setq dirname (directory-file-name (expand-file-name dirname))
  1795. newname (directory-file-name (expand-file-name newname)))
  1796. (if (and (file-directory-p newname)
  1797. (not (string-equal (file-name-nondirectory dirname)
  1798. (file-name-nondirectory newname))))
  1799. (setq newname
  1800. (expand-file-name
  1801. (file-name-nondirectory dirname) newname)))
  1802. (if (not (file-directory-p (file-name-directory newname)))
  1803. (make-directory (file-name-directory newname) parents))
  1804. (tramp-do-copy-or-rename-file-out-of-band
  1805. 'copy dirname newname keep-date))
  1806. ;; We must do it file-wise.
  1807. (tramp-run-real-handler
  1808. 'copy-directory (list dirname newname keep-date parents)))
  1809. ;; When newname did exist, we have wrong cached values.
  1810. (when t2
  1811. (with-parsed-tramp-file-name newname nil
  1812. (tramp-flush-file-property v (file-name-directory localname))
  1813. (tramp-flush-file-property v localname))))))
  1814. (defun tramp-sh-handle-rename-file
  1815. (filename newname &optional ok-if-already-exists)
  1816. "Like `rename-file' for Tramp files."
  1817. ;; Check if both files are local -- invoke normal rename-file.
  1818. ;; Otherwise, use Tramp from local system.
  1819. (setq filename (expand-file-name filename))
  1820. (setq newname (expand-file-name newname))
  1821. ;; At least one file a Tramp file?
  1822. (if (or (tramp-tramp-file-p filename)
  1823. (tramp-tramp-file-p newname))
  1824. (tramp-do-copy-or-rename-file
  1825. 'rename filename newname ok-if-already-exists t t)
  1826. (tramp-run-real-handler
  1827. 'rename-file (list filename newname ok-if-already-exists))))
  1828. (defun tramp-do-copy-or-rename-file
  1829. (op filename newname &optional ok-if-already-exists keep-date
  1830. preserve-uid-gid preserve-selinux-context)
  1831. "Copy or rename a remote file.
  1832. OP must be `copy' or `rename' and indicates the operation to perform.
  1833. FILENAME specifies the file to copy or rename, NEWNAME is the name of
  1834. the new file (for copy) or the new name of the file (for rename).
  1835. OK-IF-ALREADY-EXISTS means don't barf if NEWNAME exists already.
  1836. KEEP-DATE means to make sure that NEWNAME has the same timestamp
  1837. as FILENAME. PRESERVE-UID-GID, when non-nil, instructs to keep
  1838. the uid and gid if both files are on the same host.
  1839. PRESERVE-SELINUX-CONTEXT activates selinux commands.
  1840. This function is invoked by `tramp-sh-handle-copy-file' and
  1841. `tramp-sh-handle-rename-file'. It is an error if OP is neither
  1842. of `copy' and `rename'. FILENAME and NEWNAME must be absolute
  1843. file names."
  1844. (unless (memq op '(copy rename))
  1845. (error "Unknown operation `%s', must be `copy' or `rename'" op))
  1846. (let ((t1 (tramp-tramp-file-p filename))
  1847. (t2 (tramp-tramp-file-p newname))
  1848. (context (and preserve-selinux-context
  1849. (apply 'file-selinux-context (list filename))))
  1850. pr tm)
  1851. (with-parsed-tramp-file-name (if t1 filename newname) nil
  1852. (when (and (not ok-if-already-exists) (file-exists-p newname))
  1853. (tramp-error
  1854. v 'file-already-exists "File %s already exists" newname))
  1855. (tramp-with-progress-reporter
  1856. v 0 (format "%s %s to %s"
  1857. (if (eq op 'copy) "Copying" "Renaming")
  1858. filename newname)
  1859. (cond
  1860. ;; Both are Tramp files.
  1861. ((and t1 t2)
  1862. (with-parsed-tramp-file-name filename v1
  1863. (with-parsed-tramp-file-name newname v2
  1864. (cond
  1865. ;; Shortcut: if method, host, user are the same for
  1866. ;; both files, we invoke `cp' or `mv' on the remote
  1867. ;; host directly.
  1868. ((tramp-equal-remote filename newname)
  1869. (tramp-do-copy-or-rename-file-directly
  1870. op filename newname
  1871. ok-if-already-exists keep-date preserve-uid-gid))
  1872. ;; Try out-of-band operation.
  1873. ((tramp-method-out-of-band-p
  1874. v1 (nth 7 (file-attributes (file-truename filename))))
  1875. (tramp-do-copy-or-rename-file-out-of-band
  1876. op filename newname keep-date))
  1877. ;; No shortcut was possible. So we copy the file
  1878. ;; first. If the operation was `rename', we go back
  1879. ;; and delete the original file (if the copy was
  1880. ;; successful). The approach is simple-minded: we
  1881. ;; create a new buffer, insert the contents of the
  1882. ;; source file into it, then write out the buffer to
  1883. ;; the target file. The advantage is that it doesn't
  1884. ;; matter which filename handlers are used for the
  1885. ;; source and target file.
  1886. (t
  1887. (tramp-do-copy-or-rename-file-via-buffer
  1888. op filename newname keep-date))))))
  1889. ;; One file is a Tramp file, the other one is local.
  1890. ((or t1 t2)
  1891. (cond
  1892. ;; Fast track on local machine.
  1893. ((tramp-local-host-p v)
  1894. (tramp-do-copy-or-rename-file-directly
  1895. op filename newname
  1896. ok-if-already-exists keep-date preserve-uid-gid))
  1897. ;; If the Tramp file has an out-of-band method, the
  1898. ;; corresponding copy-program can be invoked.
  1899. ((tramp-method-out-of-band-p
  1900. v (nth 7 (file-attributes (file-truename filename))))
  1901. (tramp-do-copy-or-rename-file-out-of-band
  1902. op filename newname keep-date))
  1903. ;; Use the inline method via a Tramp buffer.
  1904. (t (tramp-do-copy-or-rename-file-via-buffer
  1905. op filename newname keep-date))))
  1906. (t
  1907. ;; One of them must be a Tramp file.
  1908. (error "Tramp implementation says this cannot happen")))
  1909. ;; Handle `preserve-selinux-context'.
  1910. (when context (apply 'set-file-selinux-context (list newname context)))
  1911. ;; In case of `rename', we must flush the cache of the source file.
  1912. (when (and t1 (eq op 'rename))
  1913. (with-parsed-tramp-file-name filename v1
  1914. (tramp-flush-file-property v1 (file-name-directory localname))
  1915. (tramp-flush-file-property v1 localname)))
  1916. ;; When newname did exist, we have wrong cached values.
  1917. (when t2
  1918. (with-parsed-tramp-file-name newname v2
  1919. (tramp-flush-file-property v2 (file-name-directory localname))
  1920. (tramp-flush-file-property v2 localname)))))))
  1921. (defun tramp-do-copy-or-rename-file-via-buffer (op filename newname keep-date)
  1922. "Use an Emacs buffer to copy or rename a file.
  1923. First arg OP is either `copy' or `rename' and indicates the operation.
  1924. FILENAME is the source file, NEWNAME the target file.
  1925. KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME."
  1926. (with-temp-buffer
  1927. ;; We must disable multibyte, because binary data shall not be
  1928. ;; converted.
  1929. (set-buffer-multibyte nil)
  1930. (let ((coding-system-for-read 'binary)
  1931. (jka-compr-inhibit t))
  1932. (insert-file-contents-literally filename))
  1933. ;; We don't want the target file to be compressed, so we let-bind
  1934. ;; `jka-compr-inhibit' to t.
  1935. (let ((coding-system-for-write 'binary)
  1936. (jka-compr-inhibit t))
  1937. (write-region (point-min) (point-max) newname)))
  1938. ;; KEEP-DATE handling.
  1939. (when keep-date (set-file-times newname (nth 5 (file-attributes filename))))
  1940. ;; Set the mode.
  1941. (set-file-modes newname (tramp-default-file-modes filename))
  1942. ;; If the operation was `rename', delete the original file.
  1943. (unless (eq op 'copy) (delete-file filename)))
  1944. (defun tramp-do-copy-or-rename-file-directly
  1945. (op filename newname ok-if-already-exists keep-date preserve-uid-gid)
  1946. "Invokes `cp' or `mv' on the remote system.
  1947. OP must be one of `copy' or `rename', indicating `cp' or `mv',
  1948. respectively. FILENAME specifies the file to copy or rename,
  1949. NEWNAME is the name of the new file (for copy) or the new name of
  1950. the file (for rename). Both files must reside on the same host.
  1951. KEEP-DATE means to make sure that NEWNAME has the same timestamp
  1952. as FILENAME. PRESERVE-UID-GID, when non-nil, instructs to keep
  1953. the uid and gid from FILENAME."
  1954. (let ((t1 (tramp-tramp-file-p filename))
  1955. (t2 (tramp-tramp-file-p newname))
  1956. (file-times (nth 5 (file-attributes filename)))
  1957. (file-modes (tramp-default-file-modes filename)))
  1958. (with-parsed-tramp-file-name (if t1 filename newname) nil
  1959. (let* ((cmd (cond ((and (eq op 'copy) preserve-uid-gid) "cp -f -p")
  1960. ((eq op 'copy) "cp -f")
  1961. ((eq op 'rename) "mv -f")
  1962. (t (tramp-error
  1963. v 'file-error
  1964. "Unknown operation `%s', must be `copy' or `rename'"
  1965. op))))
  1966. (localname1
  1967. (if t1
  1968. (tramp-file-name-handler 'file-remote-p filename 'localname)
  1969. filename))
  1970. (localname2
  1971. (if t2
  1972. (tramp-file-name-handler 'file-remote-p newname 'localname)
  1973. newname))
  1974. (prefix (file-remote-p (if t1 filename newname)))
  1975. cmd-result)
  1976. (cond
  1977. ;; Both files are on a remote host, with same user.
  1978. ((and t1 t2)
  1979. (setq cmd-result
  1980. (tramp-send-command-and-check
  1981. v (format "%s %s %s" cmd
  1982. (tramp-shell-quote-argument localname1)
  1983. (tramp-shell-quote-argument localname2))))
  1984. (with-current-buffer (tramp-get-buffer v)
  1985. (goto-char (point-min))
  1986. (unless
  1987. (or
  1988. (and keep-date
  1989. ;; Mask cp -f error.
  1990. (re-search-forward
  1991. tramp-operation-not-permitted-regexp nil t))
  1992. cmd-result)
  1993. (tramp-error-with-buffer
  1994. nil v 'file-error
  1995. "Copying directly failed, see buffer `%s' for details."
  1996. (buffer-name)))))
  1997. ;; We are on the local host.
  1998. ((or t1 t2)
  1999. (cond
  2000. ;; We can do it directly.
  2001. ((let (file-name-handler-alist)
  2002. (and (file-readable-p localname1)
  2003. (file-writable-p (file-name-directory localname2))
  2004. (or (file-directory-p localname2)
  2005. (file-writable-p localname2))))
  2006. (if (eq op 'copy)
  2007. (tramp-compat-copy-file
  2008. localname1 localname2 ok-if-already-exists
  2009. keep-date preserve-uid-gid)
  2010. (tramp-run-real-handler
  2011. 'rename-file (list localname1 localname2 ok-if-already-exists))))
  2012. ;; We can do it directly with `tramp-send-command'
  2013. ((and (file-readable-p (concat prefix localname1))
  2014. (file-writable-p
  2015. (file-name-directory (concat prefix localname2)))
  2016. (or (file-directory-p (concat prefix localname2))
  2017. (file-writable-p (concat prefix localname2))))
  2018. (tramp-do-copy-or-rename-file-directly
  2019. op (concat prefix localname1) (concat prefix localname2)
  2020. ok-if-already-exists keep-date t)
  2021. ;; We must change the ownership to the local user.
  2022. (tramp-set-file-uid-gid
  2023. (concat prefix localname2)
  2024. (tramp-get-local-uid 'integer)
  2025. (tramp-get-local-gid 'integer)))
  2026. ;; We need a temporary file in between.
  2027. (t
  2028. ;; Create the temporary file.
  2029. (let ((tmpfile (tramp-compat-make-temp-file localname1)))
  2030. (unwind-protect
  2031. (progn
  2032. (cond
  2033. (t1
  2034. (tramp-barf-unless-okay
  2035. v (format
  2036. "%s %s %s" cmd
  2037. (tramp-shell-quote-argument localname1)
  2038. (tramp-shell-quote-argument tmpfile))
  2039. "Copying directly failed, see buffer `%s' for details."
  2040. (tramp-get-buffer v))
  2041. ;; We must change the ownership as remote user.
  2042. ;; Since this does not work reliable, we also
  2043. ;; give read permissions.
  2044. (set-file-modes
  2045. (concat prefix tmpfile)
  2046. (tramp-compat-octal-to-decimal "0777"))
  2047. (tramp-set-file-uid-gid
  2048. (concat prefix tmpfile)
  2049. (tramp-get-local-uid 'integer)
  2050. (tramp-get-local-gid 'integer)))
  2051. (t2
  2052. (if (eq op 'copy)
  2053. (tramp-compat-copy-file
  2054. localname1 tmpfile t
  2055. keep-date preserve-uid-gid)
  2056. (tramp-run-real-handler
  2057. 'rename-file
  2058. (list localname1 tmpfile t)))
  2059. ;; We must change the ownership as local user.
  2060. ;; Since this does not work reliable, we also
  2061. ;; give read permissions.
  2062. (set-file-modes
  2063. tmpfile (tramp-compat-octal-to-decimal "0777"))
  2064. (tramp-set-file-uid-gid
  2065. tmpfile
  2066. (tramp-get-remote-uid v 'integer)
  2067. (tramp-get-remote-gid v 'integer))))
  2068. ;; Move the temporary file to its destination.
  2069. (cond
  2070. (t2
  2071. (tramp-barf-unless-okay
  2072. v (format
  2073. "cp -f -p %s %s"
  2074. (tramp-shell-quote-argument tmpfile)
  2075. (tramp-shell-quote-argument localname2))
  2076. "Copying directly failed, see buffer `%s' for details."
  2077. (tramp-get-buffer v)))
  2078. (t1
  2079. (tramp-run-real-handler
  2080. 'rename-file
  2081. (list tmpfile localname2 ok-if-already-exists)))))
  2082. ;; Save exit.
  2083. (ignore-errors (delete-file tmpfile)))))))))
  2084. ;; Set the time and mode. Mask possible errors.
  2085. (ignore-errors
  2086. (when keep-date
  2087. (set-file-times newname file-times)
  2088. (set-file-modes newname file-modes))))))
  2089. (defun tramp-do-copy-or-rename-file-out-of-band (op filename newname keep-date)
  2090. "Invoke rcp program to copy.
  2091. The method used must be an out-of-band method."
  2092. (let* ((t1 (tramp-tramp-file-p filename))
  2093. (t2 (tramp-tramp-file-p newname))
  2094. (orig-vec (tramp-dissect-file-name (if t1 filename newname)))
  2095. copy-program copy-args copy-env copy-keep-date port spec
  2096. source target)
  2097. (with-parsed-tramp-file-name (if t1 filename newname) nil
  2098. (if (and t1 t2)
  2099. ;; Both are Tramp files. We shall optimize it when the
  2100. ;; methods for filename and newname are the same.
  2101. (let* ((dir-flag (file-directory-p filename))
  2102. (tmpfile (tramp-compat-make-temp-file localname dir-flag)))
  2103. (if dir-flag
  2104. (setq tmpfile
  2105. (expand-file-name
  2106. (file-name-nondirectory newname) tmpfile)))
  2107. (unwind-protect
  2108. (progn
  2109. (tramp-do-copy-or-rename-file-out-of-band
  2110. op filename tmpfile keep-date)
  2111. (tramp-do-copy-or-rename-file-out-of-band
  2112. 'rename tmpfile newname keep-date))
  2113. ;; Save exit.
  2114. (ignore-errors
  2115. (if dir-flag
  2116. (tramp-compat-delete-directory
  2117. (expand-file-name ".." tmpfile) 'recursive)
  2118. (delete-file tmpfile)))))
  2119. ;; Set variables for computing the prompt for reading
  2120. ;; password.
  2121. (setq tramp-current-method (tramp-file-name-method v)
  2122. tramp-current-user (or (tramp-file-name-user v)
  2123. (tramp-get-connection-property
  2124. v "login-as" nil))
  2125. tramp-current-host (tramp-file-name-real-host v))
  2126. ;; Expand hops. Might be necessary for gateway methods.
  2127. (setq v (car (tramp-compute-multi-hops v)))
  2128. (aset v 3 localname)
  2129. ;; Check which ones of source and target are Tramp files.
  2130. (setq source (if t1 (tramp-make-copy-program-file-name v) filename)
  2131. target (funcall
  2132. (if (and (file-directory-p filename)
  2133. (string-equal
  2134. (file-name-nondirectory filename)
  2135. (file-name-nondirectory newname)))
  2136. 'file-name-directory
  2137. 'identity)
  2138. (if t2 (tramp-make-copy-program-file-name v) newname)))
  2139. ;; Check for host and port number. We cannot use
  2140. ;; `tramp-file-name-port', because this returns also
  2141. ;; `tramp-default-port', which might clash with settings in
  2142. ;; "~/.ssh/config".
  2143. (setq host (tramp-file-name-host v)
  2144. port "")
  2145. (when (string-match tramp-host-with-port-regexp host)
  2146. (setq port (string-to-number (match-string 2 host))
  2147. host (string-to-number (match-string 1 host))))
  2148. ;; Check for user. There might be an interactive setting.
  2149. (setq user (or (tramp-file-name-user v)
  2150. (tramp-get-connection-property v "login-as" nil)))
  2151. ;; Compose copy command.
  2152. (setq host (or host "")
  2153. user (or user "")
  2154. port (or port "")
  2155. spec (format-spec-make
  2156. ?h host ?u user ?p port
  2157. ?t (tramp-get-connection-property
  2158. (tramp-get-connection-process v) "temp-file" "")
  2159. ?k (if keep-date " " ""))
  2160. copy-program (tramp-get-method-parameter
  2161. method 'tramp-copy-program)
  2162. copy-keep-date (tramp-get-method-parameter
  2163. method 'tramp-copy-keep-date)
  2164. copy-args
  2165. (delete
  2166. ;; " " has either been a replacement of "%k" (when
  2167. ;; keep-date argument is non-nil), or a replacement
  2168. ;; for the whole keep-date sublist.
  2169. " "
  2170. (dolist
  2171. (x
  2172. (tramp-get-method-parameter method 'tramp-copy-args)
  2173. copy-args)
  2174. (setq copy-args
  2175. (append
  2176. copy-args
  2177. (let ((y (mapcar (lambda (z) (format-spec z spec)) x)))
  2178. (if (member "" y) '(" ") y))))))
  2179. copy-env
  2180. (delq
  2181. nil
  2182. (mapcar
  2183. (lambda (x)
  2184. (setq x (mapcar (lambda (y) (format-spec y spec)) x))
  2185. (unless (member "" x) (mapconcat 'identity x " ")))
  2186. (tramp-get-method-parameter method 'tramp-copy-env))))
  2187. ;; Check for program.
  2188. (unless (let ((default-directory
  2189. (tramp-compat-temporary-file-directory)))
  2190. (executable-find copy-program))
  2191. (tramp-error
  2192. v 'file-error "Cannot find copy program: %s" copy-program))
  2193. (with-temp-buffer
  2194. (unwind-protect
  2195. ;; The default directory must be remote.
  2196. (let ((default-directory
  2197. (file-name-directory (if t1 filename newname)))
  2198. (process-environment (copy-sequence process-environment)))
  2199. ;; Set the transfer process properties.
  2200. (tramp-set-connection-property
  2201. v "process-name" (buffer-name (current-buffer)))
  2202. (tramp-set-connection-property
  2203. v "process-buffer" (current-buffer))
  2204. (while copy-env
  2205. (tramp-message
  2206. orig-vec 5 "%s=\"%s\"" (car copy-env) (cadr copy-env))
  2207. (setenv (pop copy-env) (pop copy-env)))
  2208. ;; Use an asynchronous process. By this, password can
  2209. ;; be handled. The default directory must be local, in
  2210. ;; order to apply the correct `copy-program'. We don't
  2211. ;; set a timeout, because the copying of large files can
  2212. ;; last longer than 60 secs.
  2213. (let ((p (let ((default-directory
  2214. (tramp-compat-temporary-file-directory)))
  2215. (apply 'start-process
  2216. (tramp-get-connection-name v)
  2217. (tramp-get-connection-buffer v)
  2218. copy-program
  2219. (append copy-args (list source target))))))
  2220. (tramp-message
  2221. orig-vec 6 "%s"
  2222. (mapconcat 'identity (process-command p) " "))
  2223. (tramp-compat-set-process-query-on-exit-flag p nil)
  2224. (tramp-process-actions
  2225. p v nil tramp-actions-copy-out-of-band)))
  2226. ;; Reset the transfer process properties.
  2227. (tramp-message orig-vec 6 "%s" (buffer-string))
  2228. (tramp-set-connection-property v "process-name" nil)
  2229. (tramp-set-connection-property v "process-buffer" nil)))
  2230. ;; Handle KEEP-DATE argument.
  2231. (when (and keep-date (not copy-keep-date))
  2232. (set-file-times newname (nth 5 (file-attributes filename))))
  2233. ;; Set the mode.
  2234. (unless (and keep-date copy-keep-date)
  2235. (ignore-errors
  2236. (set-file-modes newname (tramp-default-file-modes filename)))))
  2237. ;; If the operation was `rename', delete the original file.
  2238. (unless (eq op 'copy)
  2239. (if (file-regular-p filename)
  2240. (delete-file filename)
  2241. (tramp-compat-delete-directory filename 'recursive))))))
  2242. (defun tramp-sh-handle-make-directory (dir &optional parents)
  2243. "Like `make-directory' for Tramp files."
  2244. (setq dir (expand-file-name dir))
  2245. (with-parsed-tramp-file-name dir nil
  2246. (tramp-flush-directory-property v (file-name-directory localname))
  2247. (save-excursion
  2248. (tramp-barf-unless-okay
  2249. v (format "%s %s"
  2250. (if parents "mkdir -p" "mkdir")
  2251. (tramp-shell-quote-argument localname))
  2252. "Couldn't make directory %s" dir))))
  2253. (defun tramp-sh-handle-delete-directory (directory &optional recursive)
  2254. "Like `delete-directory' for Tramp files."
  2255. (setq directory (expand-file-name directory))
  2256. (with-parsed-tramp-file-name directory nil
  2257. (tramp-flush-file-property v (file-name-directory localname))
  2258. (tramp-flush-directory-property v localname)
  2259. (tramp-barf-unless-okay
  2260. v (format "%s %s"
  2261. (if recursive "rm -rf" "rmdir")
  2262. (tramp-shell-quote-argument localname))
  2263. "Couldn't delete %s" directory)))
  2264. (defun tramp-sh-handle-delete-file (filename &optional trash)
  2265. "Like `delete-file' for Tramp files."
  2266. (setq filename (expand-file-name filename))
  2267. (with-parsed-tramp-file-name filename nil
  2268. (tramp-flush-file-property v (file-name-directory localname))
  2269. (tramp-flush-file-property v localname)
  2270. (tramp-barf-unless-okay
  2271. v (format "%s %s"
  2272. (or (and trash (tramp-get-remote-trash v)) "rm -f")
  2273. (tramp-shell-quote-argument localname))
  2274. "Couldn't delete %s" filename)))
  2275. ;; Dired.
  2276. ;; CCC: This does not seem to be enough. Something dies when
  2277. ;; we try and delete two directories under Tramp :/
  2278. (defun tramp-sh-handle-dired-recursive-delete-directory (filename)
  2279. "Recursively delete the directory given.
  2280. This is like `dired-recursive-delete-directory' for Tramp files."
  2281. (with-parsed-tramp-file-name filename nil
  2282. ;; Run a shell command 'rm -r <localname>'
  2283. ;; Code shamelessly stolen from the dired implementation and, um, hacked :)
  2284. (unless (file-exists-p filename)
  2285. (tramp-error v 'file-error "No such directory: %s" filename))
  2286. ;; Which is better, -r or -R? (-r works for me <daniel@danann.net>)
  2287. (tramp-send-command
  2288. v
  2289. (format "rm -rf %s" (tramp-shell-quote-argument localname))
  2290. ;; Don't read the output, do it explicitly.
  2291. nil t)
  2292. ;; Wait for the remote system to return to us...
  2293. ;; This might take a while, allow it plenty of time.
  2294. (tramp-wait-for-output (tramp-get-connection-process v) 120)
  2295. ;; Make sure that it worked...
  2296. (tramp-flush-file-property v (file-name-directory localname))
  2297. (tramp-flush-directory-property v localname)
  2298. (and (file-exists-p filename)
  2299. (tramp-error
  2300. v 'file-error "Failed to recursively delete %s" filename))))
  2301. (defun tramp-sh-handle-dired-compress-file (file &rest ok-flag)
  2302. "Like `dired-compress-file' for Tramp files."
  2303. ;; OK-FLAG is valid for XEmacs only, but not implemented.
  2304. ;; Code stolen mainly from dired-aux.el.
  2305. (with-parsed-tramp-file-name file nil
  2306. (tramp-flush-file-property v localname)
  2307. (save-excursion
  2308. (let ((suffixes
  2309. (if (not (featurep 'xemacs))
  2310. ;; Emacs case
  2311. (symbol-value 'dired-compress-file-suffixes)
  2312. ;; XEmacs has `dired-compression-method-alist', which is
  2313. ;; transformed into `dired-compress-file-suffixes' structure.
  2314. (mapcar
  2315. (lambda (x)
  2316. (list (concat (regexp-quote (nth 1 x)) "\\'")
  2317. nil
  2318. (mapconcat 'identity (nth 3 x) " ")))
  2319. (symbol-value 'dired-compression-method-alist))))
  2320. suffix)
  2321. ;; See if any suffix rule matches this file name.
  2322. (while suffixes
  2323. (let (case-fold-search)
  2324. (if (string-match (car (car suffixes)) localname)
  2325. (setq suffix (car suffixes) suffixes nil))
  2326. (setq suffixes (cdr suffixes))))
  2327. (cond ((file-symlink-p file)
  2328. nil)
  2329. ((and suffix (nth 2 suffix))
  2330. ;; We found an uncompression rule.
  2331. (tramp-with-progress-reporter
  2332. v 0 (format "Uncompressing %s" file)
  2333. (when (tramp-send-command-and-check
  2334. v (concat (nth 2 suffix) " "
  2335. (tramp-shell-quote-argument localname)))
  2336. ;; `dired-remove-file' is not defined in XEmacs.
  2337. (tramp-compat-funcall 'dired-remove-file file)
  2338. (string-match (car suffix) file)
  2339. (concat (substring file 0 (match-beginning 0))))))
  2340. (t
  2341. ;; We don't recognize the file as compressed, so compress it.
  2342. ;; Try gzip.
  2343. (tramp-with-progress-reporter v 0 (format "Compressing %s" file)
  2344. (when (tramp-send-command-and-check
  2345. v (concat "gzip -f "
  2346. (tramp-shell-quote-argument localname)))
  2347. ;; `dired-remove-file' is not defined in XEmacs.
  2348. (tramp-compat-funcall 'dired-remove-file file)
  2349. (cond ((file-exists-p (concat file ".gz"))
  2350. (concat file ".gz"))
  2351. ((file-exists-p (concat file ".z"))
  2352. (concat file ".z"))
  2353. (t nil))))))))))
  2354. (defun tramp-sh-handle-insert-directory
  2355. (filename switches &optional wildcard full-directory-p)
  2356. "Like `insert-directory' for Tramp files."
  2357. (setq filename (expand-file-name filename))
  2358. (with-parsed-tramp-file-name filename nil
  2359. (if (and (featurep 'ls-lisp)
  2360. (not (symbol-value 'ls-lisp-use-insert-directory-program)))
  2361. (tramp-run-real-handler
  2362. 'insert-directory (list filename switches wildcard full-directory-p))
  2363. (when (stringp switches)
  2364. (setq switches (split-string switches)))
  2365. (when (and (member "--dired" switches)
  2366. (not (tramp-get-ls-command-with-dired v)))
  2367. (setq switches (delete "--dired" switches)))
  2368. (when wildcard
  2369. (setq wildcard (tramp-run-real-handler
  2370. 'file-name-nondirectory (list localname)))
  2371. (setq localname (tramp-run-real-handler
  2372. 'file-name-directory (list localname))))
  2373. (unless full-directory-p
  2374. (setq switches (add-to-list 'switches "-d" 'append)))
  2375. (setq switches (mapconcat 'tramp-shell-quote-argument switches " "))
  2376. (when wildcard
  2377. (setq switches (concat switches " " wildcard)))
  2378. (tramp-message
  2379. v 4 "Inserting directory `ls %s %s', wildcard %s, fulldir %s"
  2380. switches filename (if wildcard "yes" "no")
  2381. (if full-directory-p "yes" "no"))
  2382. ;; If `full-directory-p', we just say `ls -l FILENAME'.
  2383. ;; Else we chdir to the parent directory, then say `ls -ld BASENAME'.
  2384. (if full-directory-p
  2385. (tramp-send-command
  2386. v
  2387. (format "%s %s %s 2>/dev/null"
  2388. (tramp-get-ls-command v)
  2389. switches
  2390. (if wildcard
  2391. localname
  2392. (tramp-shell-quote-argument (concat localname ".")))))
  2393. (tramp-barf-unless-okay
  2394. v
  2395. (format "cd %s" (tramp-shell-quote-argument
  2396. (tramp-run-real-handler
  2397. 'file-name-directory (list localname))))
  2398. "Couldn't `cd %s'"
  2399. (tramp-shell-quote-argument
  2400. (tramp-run-real-handler 'file-name-directory (list localname))))
  2401. (tramp-send-command
  2402. v
  2403. (format "%s %s %s"
  2404. (tramp-get-ls-command v)
  2405. switches
  2406. (if (or wildcard
  2407. (zerop (length
  2408. (tramp-run-real-handler
  2409. 'file-name-nondirectory (list localname)))))
  2410. ""
  2411. (tramp-shell-quote-argument
  2412. (tramp-run-real-handler
  2413. 'file-name-nondirectory (list localname)))))))
  2414. (let ((beg (point)))
  2415. ;; We cannot use `insert-buffer-substring' because the Tramp
  2416. ;; buffer changes its contents before insertion due to calling
  2417. ;; `expand-file' and alike.
  2418. (insert
  2419. (with-current-buffer (tramp-get-buffer v)
  2420. (buffer-string)))
  2421. ;; Check for "--dired" output.
  2422. (forward-line -2)
  2423. (when (looking-at "//SUBDIRED//")
  2424. (forward-line -1))
  2425. (when (looking-at "//DIRED//\\s-+")
  2426. (let ((databeg (match-end 0))
  2427. (end (point-at-eol)))
  2428. ;; Now read the numeric positions of file names.
  2429. (goto-char databeg)
  2430. (while (< (point) end)
  2431. (let ((start (+ beg (read (current-buffer))))
  2432. (end (+ beg (read (current-buffer)))))
  2433. (if (memq (char-after end) '(?\n ?\ ))
  2434. ;; End is followed by \n or by " -> ".
  2435. (put-text-property start end 'dired-filename t))))))
  2436. ;; Remove trailing lines.
  2437. (goto-char (point-at-bol))
  2438. (while (looking-at "//")
  2439. (forward-line 1)
  2440. (delete-region (match-beginning 0) (point)))
  2441. ;; Some busyboxes are reluctant to discard colors.
  2442. (unless (string-match "color" (tramp-get-connection-property v "ls" ""))
  2443. (goto-char beg)
  2444. (while (re-search-forward tramp-color-escape-sequence-regexp nil t)
  2445. (replace-match "")))
  2446. ;; The inserted file could be from somewhere else.
  2447. (when (and (not wildcard) (not full-directory-p))
  2448. (goto-char (point-max))
  2449. (when (file-symlink-p filename)
  2450. (goto-char (search-backward "->" beg 'noerror)))
  2451. (search-backward
  2452. (if (zerop (length (file-name-nondirectory filename)))
  2453. "."
  2454. (file-name-nondirectory filename))
  2455. beg 'noerror)
  2456. (replace-match (file-relative-name filename) t))
  2457. (goto-char (point-max))))))
  2458. ;; Canonicalization of file names.
  2459. (defun tramp-sh-handle-expand-file-name (name &optional dir)
  2460. "Like `expand-file-name' for Tramp files.
  2461. If the localname part of the given filename starts with \"/../\" then
  2462. the result will be a local, non-Tramp, filename."
  2463. ;; If DIR is not given, use DEFAULT-DIRECTORY or "/".
  2464. (setq dir (or dir default-directory "/"))
  2465. ;; Unless NAME is absolute, concat DIR and NAME.
  2466. (unless (file-name-absolute-p name)
  2467. (setq name (concat (file-name-as-directory dir) name)))
  2468. ;; If NAME is not a Tramp file, run the real handler.
  2469. (if (not (tramp-connectable-p name))
  2470. (tramp-run-real-handler 'expand-file-name (list name nil))
  2471. ;; Dissect NAME.
  2472. (with-parsed-tramp-file-name name nil
  2473. (unless (tramp-run-real-handler 'file-name-absolute-p (list localname))
  2474. (setq localname (concat "~/" localname)))
  2475. ;; Tilde expansion if necessary. This needs a shell which
  2476. ;; groks tilde expansion! The function `tramp-find-shell' is
  2477. ;; supposed to find such a shell on the remote host. Please
  2478. ;; tell me about it when this doesn't work on your system.
  2479. (when (string-match "\\`\\(~[^/]*\\)\\(.*\\)\\'" localname)
  2480. (let ((uname (match-string 1 localname))
  2481. (fname (match-string 2 localname)))
  2482. ;; We cannot simply apply "~/", because under sudo "~/" is
  2483. ;; expanded to the local user home directory but to the
  2484. ;; root home directory. On the other hand, using always
  2485. ;; the default user name for tilde expansion is not
  2486. ;; appropriate either, because ssh and companions might
  2487. ;; use a user name from the config file.
  2488. (when (and (string-equal uname "~")
  2489. (string-match "\\`su\\(do\\)?\\'" method))
  2490. (setq uname (concat uname user)))
  2491. (setq uname
  2492. (with-connection-property v uname
  2493. (tramp-send-command
  2494. v (format "cd %s; pwd" (tramp-shell-quote-argument uname)))
  2495. (with-current-buffer (tramp-get-buffer v)
  2496. (goto-char (point-min))
  2497. (buffer-substring (point) (point-at-eol)))))
  2498. (setq localname (concat uname fname))))
  2499. ;; There might be a double slash, for example when "~/"
  2500. ;; expands to "/". Remove this.
  2501. (while (string-match "//" localname)
  2502. (setq localname (replace-match "/" t t localname)))
  2503. ;; No tilde characters in file name, do normal
  2504. ;; `expand-file-name' (this does "/./" and "/../"). We bind
  2505. ;; `directory-sep-char' here for XEmacs on Windows, which would
  2506. ;; otherwise use backslash. `default-directory' is bound,
  2507. ;; because on Windows there would be problems with UNC shares or
  2508. ;; Cygwin mounts.
  2509. (let ((directory-sep-char ?/)
  2510. (default-directory (tramp-compat-temporary-file-directory)))
  2511. (tramp-make-tramp-file-name
  2512. method user host
  2513. (tramp-drop-volume-letter
  2514. (tramp-run-real-handler
  2515. 'expand-file-name (list localname))))))))
  2516. ;;; Remote commands:
  2517. (defun tramp-sh-handle-executable-find (command)
  2518. "Like `executable-find' for Tramp files."
  2519. (with-parsed-tramp-file-name default-directory nil
  2520. (tramp-find-executable v command (tramp-get-remote-path v) t)))
  2521. (defun tramp-process-sentinel (proc event)
  2522. "Flush file caches."
  2523. (unless (memq (process-status proc) '(run open))
  2524. (let ((vec (tramp-get-connection-property proc "vector" nil)))
  2525. (when vec
  2526. (tramp-message vec 5 "Sentinel called: `%s' `%s'" proc event)
  2527. (tramp-flush-connection-property proc)
  2528. (tramp-flush-directory-property vec "")))))
  2529. ;; We use BUFFER also as connection buffer during setup. Because of
  2530. ;; this, its original contents must be saved, and restored once
  2531. ;; connection has been setup.
  2532. (defun tramp-sh-handle-start-file-process (name buffer program &rest args)
  2533. "Like `start-file-process' for Tramp files."
  2534. (with-parsed-tramp-file-name default-directory nil
  2535. ;; When PROGRAM is nil, we just provide a tty.
  2536. (let ((command
  2537. (when (stringp program)
  2538. (format "cd %s; exec env PS1=%s %s"
  2539. (tramp-shell-quote-argument localname)
  2540. ;; Use a human-friendly prompt, for example for `shell'.
  2541. (tramp-shell-quote-argument
  2542. (format "%s %s"
  2543. (file-remote-p default-directory)
  2544. tramp-initial-end-of-output))
  2545. (mapconcat 'tramp-shell-quote-argument
  2546. (cons program args) " "))))
  2547. (tramp-process-connection-type
  2548. (or (null program) tramp-process-connection-type))
  2549. (bmp (and (buffer-live-p buffer) (buffer-modified-p buffer)))
  2550. (name1 name)
  2551. (i 0))
  2552. (unwind-protect
  2553. (save-excursion
  2554. (save-restriction
  2555. (unless buffer
  2556. ;; BUFFER can be nil. We use a temporary buffer.
  2557. (setq buffer (generate-new-buffer tramp-temp-buffer-name)))
  2558. (while (get-process name1)
  2559. ;; NAME must be unique as process name.
  2560. (setq i (1+ i)
  2561. name1 (format "%s<%d>" name i)))
  2562. (setq name name1)
  2563. ;; Set the new process properties.
  2564. (tramp-set-connection-property v "process-name" name)
  2565. (tramp-set-connection-property v "process-buffer" buffer)
  2566. ;; Activate narrowing in order to save BUFFER contents.
  2567. ;; Clear also the modification time; otherwise we might
  2568. ;; be interrupted by `verify-visited-file-modtime'.
  2569. (with-current-buffer (tramp-get-connection-buffer v)
  2570. (let ((buffer-undo-list t))
  2571. (clear-visited-file-modtime)
  2572. (narrow-to-region (point-max) (point-max))
  2573. (if command
  2574. ;; Send the command.
  2575. (tramp-send-command v command nil t) ; nooutput
  2576. ;; Check, whether a pty is associated.
  2577. (tramp-maybe-open-connection v)
  2578. (unless (tramp-compat-process-get
  2579. (tramp-get-connection-process v) 'remote-tty)
  2580. (tramp-error
  2581. v 'file-error
  2582. "pty association is not supported for `%s'" name)))))
  2583. (let ((p (tramp-get-connection-process v)))
  2584. ;; Set query flag for this process.
  2585. (tramp-compat-set-process-query-on-exit-flag p t)
  2586. ;; Return process.
  2587. p)))
  2588. ;; Save exit.
  2589. (with-current-buffer (tramp-get-connection-buffer v)
  2590. (if (string-match tramp-temp-buffer-name (buffer-name))
  2591. (progn
  2592. (set-process-buffer (tramp-get-connection-process v) nil)
  2593. (kill-buffer (current-buffer)))
  2594. (set-buffer-modified-p bmp)))
  2595. (tramp-set-connection-property v "process-name" nil)
  2596. (tramp-set-connection-property v "process-buffer" nil)))))
  2597. (defun tramp-sh-handle-process-file
  2598. (program &optional infile destination display &rest args)
  2599. "Like `process-file' for Tramp files."
  2600. ;; The implementation is not complete yet.
  2601. (when (and (numberp destination) (zerop destination))
  2602. (error "Implementation does not handle immediate return"))
  2603. (with-parsed-tramp-file-name default-directory nil
  2604. (let (command input tmpinput stderr tmpstderr outbuf ret)
  2605. ;; Compute command.
  2606. (setq command (mapconcat 'tramp-shell-quote-argument
  2607. (cons program args) " "))
  2608. ;; Determine input.
  2609. (if (null infile)
  2610. (setq input "/dev/null")
  2611. (setq infile (expand-file-name infile))
  2612. (if (tramp-equal-remote default-directory infile)
  2613. ;; INFILE is on the same remote host.
  2614. (setq input (with-parsed-tramp-file-name infile nil localname))
  2615. ;; INFILE must be copied to remote host.
  2616. (setq input (tramp-make-tramp-temp-file v)
  2617. tmpinput (tramp-make-tramp-file-name method user host input))
  2618. (copy-file infile tmpinput t)))
  2619. (when input (setq command (format "%s <%s" command input)))
  2620. ;; Determine output.
  2621. (cond
  2622. ;; Just a buffer.
  2623. ((bufferp destination)
  2624. (setq outbuf destination))
  2625. ;; A buffer name.
  2626. ((stringp destination)
  2627. (setq outbuf (get-buffer-create destination)))
  2628. ;; (REAL-DESTINATION ERROR-DESTINATION)
  2629. ((consp destination)
  2630. ;; output.
  2631. (cond
  2632. ((bufferp (car destination))
  2633. (setq outbuf (car destination)))
  2634. ((stringp (car destination))
  2635. (setq outbuf (get-buffer-create (car destination))))
  2636. ((car destination)
  2637. (setq outbuf (current-buffer))))
  2638. ;; stderr.
  2639. (cond
  2640. ((stringp (cadr destination))
  2641. (setcar (cdr destination) (expand-file-name (cadr destination)))
  2642. (if (tramp-equal-remote default-directory (cadr destination))
  2643. ;; stderr is on the same remote host.
  2644. (setq stderr (with-parsed-tramp-file-name
  2645. (cadr destination) nil localname))
  2646. ;; stderr must be copied to remote host. The temporary
  2647. ;; file must be deleted after execution.
  2648. (setq stderr (tramp-make-tramp-temp-file v)
  2649. tmpstderr (tramp-make-tramp-file-name
  2650. method user host stderr))))
  2651. ;; stderr to be discarded.
  2652. ((null (cadr destination))
  2653. (setq stderr "/dev/null"))))
  2654. ;; 't
  2655. (destination
  2656. (setq outbuf (current-buffer))))
  2657. (when stderr (setq command (format "%s 2>%s" command stderr)))
  2658. ;; Send the command. It might not return in time, so we protect
  2659. ;; it. Call it in a subshell, in order to preserve working
  2660. ;; directory.
  2661. (condition-case nil
  2662. (unwind-protect
  2663. (setq ret
  2664. (if (tramp-send-command-and-check
  2665. v (format "\\cd %s; %s"
  2666. (tramp-shell-quote-argument localname)
  2667. command)
  2668. t t)
  2669. 0 1))
  2670. ;; We should show the output anyway.
  2671. (when outbuf
  2672. (with-current-buffer outbuf
  2673. (insert
  2674. (with-current-buffer (tramp-get-connection-buffer v)
  2675. (buffer-string))))
  2676. (when display (display-buffer outbuf))))
  2677. ;; When the user did interrupt, we should do it also. We use
  2678. ;; return code -1 as marker.
  2679. (quit
  2680. (kill-buffer (tramp-get-connection-buffer v))
  2681. (setq ret -1))
  2682. ;; Handle errors.
  2683. (error
  2684. (kill-buffer (tramp-get-connection-buffer v))
  2685. (setq ret 1)))
  2686. ;; Provide error file.
  2687. (when tmpstderr (rename-file tmpstderr (cadr destination) t))
  2688. ;; Cleanup. We remove all file cache values for the connection,
  2689. ;; because the remote process could have changed them.
  2690. (when tmpinput (delete-file tmpinput))
  2691. ;; `process-file-side-effects' has been introduced with GNU
  2692. ;; Emacs 23.2. If set to `nil', no remote file will be changed
  2693. ;; by `program'. If it doesn't exist, we assume its default
  2694. ;; value `t'.
  2695. (unless (and (boundp 'process-file-side-effects)
  2696. (not (symbol-value 'process-file-side-effects)))
  2697. (tramp-flush-directory-property v ""))
  2698. ;; Return exit status.
  2699. (if (equal ret -1)
  2700. (keyboard-quit)
  2701. ret))))
  2702. (defun tramp-sh-handle-call-process-region
  2703. (start end program &optional delete buffer display &rest args)
  2704. "Like `call-process-region' for Tramp files."
  2705. (let ((tmpfile (tramp-compat-make-temp-file "")))
  2706. (write-region start end tmpfile)
  2707. (when delete (delete-region start end))
  2708. (unwind-protect
  2709. (apply 'call-process program tmpfile buffer display args)
  2710. (delete-file tmpfile))))
  2711. (defun tramp-sh-handle-file-local-copy (filename)
  2712. "Like `file-local-copy' for Tramp files."
  2713. (with-parsed-tramp-file-name filename nil
  2714. (unless (file-exists-p filename)
  2715. (tramp-error
  2716. v 'file-error
  2717. "Cannot make local copy of non-existing file `%s'" filename))
  2718. (let* ((size (nth 7 (file-attributes (file-truename filename))))
  2719. (rem-enc (tramp-get-inline-coding v "remote-encoding" size))
  2720. (loc-dec (tramp-get-inline-coding v "local-decoding" size))
  2721. (tmpfile (tramp-compat-make-temp-file filename)))
  2722. (condition-case err
  2723. (cond
  2724. ;; `copy-file' handles direct copy and out-of-band methods.
  2725. ((or (tramp-local-host-p v)
  2726. (tramp-method-out-of-band-p v size))
  2727. (copy-file filename tmpfile t t))
  2728. ;; Use inline encoding for file transfer.
  2729. (rem-enc
  2730. (save-excursion
  2731. (tramp-with-progress-reporter
  2732. v 3 (format "Encoding remote file %s" filename)
  2733. (tramp-barf-unless-okay
  2734. v (format rem-enc (tramp-shell-quote-argument localname))
  2735. "Encoding remote file failed"))
  2736. (if (functionp loc-dec)
  2737. ;; If local decoding is a function, we call it. We
  2738. ;; must disable multibyte, because
  2739. ;; `uudecode-decode-region' doesn't handle it
  2740. ;; correctly.
  2741. (with-temp-buffer
  2742. (set-buffer-multibyte nil)
  2743. (insert-buffer-substring (tramp-get-buffer v))
  2744. (tramp-with-progress-reporter
  2745. v 3 (format "Decoding remote file %s with function %s"
  2746. filename loc-dec)
  2747. (funcall loc-dec (point-min) (point-max))
  2748. ;; Unset `file-name-handler-alist'. Otherwise,
  2749. ;; epa-file gets confused.
  2750. (let (file-name-handler-alist
  2751. (coding-system-for-write 'binary))
  2752. (write-region (point-min) (point-max) tmpfile))))
  2753. ;; If tramp-decoding-function is not defined for this
  2754. ;; method, we invoke tramp-decoding-command instead.
  2755. (let ((tmpfile2 (tramp-compat-make-temp-file filename)))
  2756. ;; Unset `file-name-handler-alist'. Otherwise,
  2757. ;; epa-file gets confused.
  2758. (let (file-name-handler-alist
  2759. (coding-system-for-write 'binary))
  2760. (write-region (point-min) (point-max) tmpfile2))
  2761. (tramp-with-progress-reporter
  2762. v 3 (format "Decoding remote file %s with command %s"
  2763. filename loc-dec)
  2764. (unwind-protect
  2765. (tramp-call-local-coding-command
  2766. loc-dec tmpfile2 tmpfile)
  2767. (delete-file tmpfile2)))))
  2768. ;; Set proper permissions.
  2769. (set-file-modes tmpfile (tramp-default-file-modes filename))
  2770. ;; Set local user ownership.
  2771. (tramp-set-file-uid-gid tmpfile)))
  2772. ;; Oops, I don't know what to do.
  2773. (t (tramp-error
  2774. v 'file-error "Wrong method specification for `%s'" method)))
  2775. ;; Error handling.
  2776. ((error quit)
  2777. (delete-file tmpfile)
  2778. (signal (car err) (cdr err))))
  2779. (run-hooks 'tramp-handle-file-local-copy-hook)
  2780. tmpfile)))
  2781. ;; This is needed for XEmacs only. Code stolen from files.el.
  2782. (defun tramp-sh-handle-insert-file-contents-literally
  2783. (filename &optional visit beg end replace)
  2784. "Like `insert-file-contents-literally' for Tramp files."
  2785. (let ((format-alist nil)
  2786. (after-insert-file-functions nil)
  2787. (coding-system-for-read 'no-conversion)
  2788. (coding-system-for-write 'no-conversion)
  2789. (find-buffer-file-type-function
  2790. (if (fboundp 'find-buffer-file-type)
  2791. (symbol-function 'find-buffer-file-type)
  2792. nil))
  2793. (inhibit-file-name-handlers '(jka-compr-handler image-file-handler))
  2794. (inhibit-file-name-operation 'insert-file-contents))
  2795. (unwind-protect
  2796. (progn
  2797. (fset 'find-buffer-file-type (lambda (filename) t))
  2798. (insert-file-contents filename visit beg end replace))
  2799. ;; Save exit.
  2800. (if find-buffer-file-type-function
  2801. (fset 'find-buffer-file-type find-buffer-file-type-function)
  2802. (fmakunbound 'find-buffer-file-type)))))
  2803. (defun tramp-sh-handle-make-auto-save-file-name ()
  2804. "Like `make-auto-save-file-name' for Tramp files.
  2805. Returns a file name in `tramp-auto-save-directory' for autosaving this file."
  2806. (let ((tramp-auto-save-directory tramp-auto-save-directory)
  2807. (buffer-file-name
  2808. (tramp-subst-strs-in-string
  2809. '(("_" . "|")
  2810. ("/" . "_a")
  2811. (":" . "_b")
  2812. ("|" . "__")
  2813. ("[" . "_l")
  2814. ("]" . "_r"))
  2815. (buffer-file-name))))
  2816. ;; File name must be unique. This is ensured with Emacs 22 (see
  2817. ;; UNIQUIFY element of `auto-save-file-name-transforms'); but for
  2818. ;; all other cases we must do it ourselves.
  2819. (when (boundp 'auto-save-file-name-transforms)
  2820. (mapc
  2821. (lambda (x)
  2822. (when (and (string-match (car x) buffer-file-name)
  2823. (not (car (cddr x))))
  2824. (setq tramp-auto-save-directory
  2825. (or tramp-auto-save-directory
  2826. (tramp-compat-temporary-file-directory)))))
  2827. (symbol-value 'auto-save-file-name-transforms)))
  2828. ;; Create directory.
  2829. (when tramp-auto-save-directory
  2830. (setq buffer-file-name
  2831. (expand-file-name buffer-file-name tramp-auto-save-directory))
  2832. (unless (file-exists-p tramp-auto-save-directory)
  2833. (make-directory tramp-auto-save-directory t)))
  2834. ;; Run plain `make-auto-save-file-name'. There might be an advice when
  2835. ;; it is not a magic file name operation (since Emacs 22).
  2836. ;; We must deactivate it temporarily.
  2837. (if (not (ad-is-active 'make-auto-save-file-name))
  2838. (tramp-run-real-handler 'make-auto-save-file-name nil)
  2839. ;; else
  2840. (ad-deactivate 'make-auto-save-file-name)
  2841. (prog1
  2842. (tramp-run-real-handler 'make-auto-save-file-name nil)
  2843. (ad-activate 'make-auto-save-file-name)))))
  2844. ;; CCC grok LOCKNAME
  2845. (defun tramp-sh-handle-write-region
  2846. (start end filename &optional append visit lockname confirm)
  2847. "Like `write-region' for Tramp files."
  2848. (setq filename (expand-file-name filename))
  2849. (with-parsed-tramp-file-name filename nil
  2850. ;; Following part commented out because we don't know what to do about
  2851. ;; file locking, and it does not appear to be a problem to ignore it.
  2852. ;; Ange-ftp ignores it, too.
  2853. ;; (when (and lockname (stringp lockname))
  2854. ;; (setq lockname (expand-file-name lockname)))
  2855. ;; (unless (or (eq lockname nil)
  2856. ;; (string= lockname filename))
  2857. ;; (error
  2858. ;; "tramp-sh-handle-write-region: LOCKNAME must be nil or equal FILENAME"))
  2859. ;; XEmacs takes a coding system as the seventh argument, not `confirm'.
  2860. (when (and (not (featurep 'xemacs)) confirm (file-exists-p filename))
  2861. (unless (y-or-n-p (format "File %s exists; overwrite anyway? " filename))
  2862. (tramp-error v 'file-error "File not overwritten")))
  2863. (let ((uid (or (nth 2 (tramp-compat-file-attributes filename 'integer))
  2864. (tramp-get-remote-uid v 'integer)))
  2865. (gid (or (nth 3 (tramp-compat-file-attributes filename 'integer))
  2866. (tramp-get-remote-gid v 'integer))))
  2867. (if (and (tramp-local-host-p v)
  2868. ;; `file-writable-p' calls `file-expand-file-name'. We
  2869. ;; cannot use `tramp-run-real-handler' therefore.
  2870. (let (file-name-handler-alist)
  2871. (and
  2872. (file-writable-p (file-name-directory localname))
  2873. (or (file-directory-p localname)
  2874. (file-writable-p localname)))))
  2875. ;; Short track: if we are on the local host, we can run directly.
  2876. (tramp-run-real-handler
  2877. 'write-region
  2878. (list start end localname append 'no-message lockname confirm))
  2879. (let ((modes (save-excursion (tramp-default-file-modes filename)))
  2880. ;; We use this to save the value of
  2881. ;; `last-coding-system-used' after writing the tmp
  2882. ;; file. At the end of the function, we set
  2883. ;; `last-coding-system-used' to this saved value. This
  2884. ;; way, any intermediary coding systems used while
  2885. ;; talking to the remote shell or suchlike won't hose
  2886. ;; this variable. This approach was snarfed from
  2887. ;; ange-ftp.el.
  2888. coding-system-used
  2889. ;; Write region into a tmp file. This isn't really
  2890. ;; needed if we use an encoding function, but currently
  2891. ;; we use it always because this makes the logic
  2892. ;; simpler.
  2893. (tmpfile (or tramp-temp-buffer-file-name
  2894. (tramp-compat-make-temp-file filename))))
  2895. ;; If `append' is non-nil, we copy the file locally, and let
  2896. ;; the native `write-region' implementation do the job.
  2897. (when append (copy-file filename tmpfile 'ok))
  2898. ;; We say `no-message' here because we don't want the
  2899. ;; visited file modtime data to be clobbered from the temp
  2900. ;; file. We call `set-visited-file-modtime' ourselves later
  2901. ;; on. We must ensure that `file-coding-system-alist'
  2902. ;; matches `tmpfile'.
  2903. (let (file-name-handler-alist
  2904. (file-coding-system-alist
  2905. (tramp-find-file-name-coding-system-alist filename tmpfile)))
  2906. (condition-case err
  2907. (tramp-run-real-handler
  2908. 'write-region
  2909. (list start end tmpfile append 'no-message lockname confirm))
  2910. ((error quit)
  2911. (setq tramp-temp-buffer-file-name nil)
  2912. (delete-file tmpfile)
  2913. (signal (car err) (cdr err))))
  2914. ;; Now, `last-coding-system-used' has the right value. Remember it.
  2915. (when (boundp 'last-coding-system-used)
  2916. (setq coding-system-used
  2917. (symbol-value 'last-coding-system-used))))
  2918. ;; The permissions of the temporary file should be set. If
  2919. ;; filename does not exist (eq modes nil) it has been
  2920. ;; renamed to the backup file. This case `save-buffer'
  2921. ;; handles permissions.
  2922. ;; Ensure that it is still readable.
  2923. (when modes
  2924. (set-file-modes
  2925. tmpfile
  2926. (logior (or modes 0) (tramp-compat-octal-to-decimal "0400"))))
  2927. ;; This is a bit lengthy due to the different methods
  2928. ;; possible for file transfer. First, we check whether the
  2929. ;; method uses an rcp program. If so, we call it.
  2930. ;; Otherwise, both encoding and decoding command must be
  2931. ;; specified. However, if the method _also_ specifies an
  2932. ;; encoding function, then that is used for encoding the
  2933. ;; contents of the tmp file.
  2934. (let* ((size (nth 7 (file-attributes tmpfile)))
  2935. (rem-dec (tramp-get-inline-coding v "remote-decoding" size))
  2936. (loc-enc (tramp-get-inline-coding v "local-encoding" size)))
  2937. (cond
  2938. ;; `copy-file' handles direct copy and out-of-band methods.
  2939. ((or (tramp-local-host-p v)
  2940. (tramp-method-out-of-band-p v size))
  2941. (if (and (not (stringp start))
  2942. (= (or end (point-max)) (point-max))
  2943. (= (or start (point-min)) (point-min))
  2944. (tramp-get-method-parameter
  2945. method 'tramp-copy-keep-tmpfile))
  2946. (progn
  2947. (setq tramp-temp-buffer-file-name tmpfile)
  2948. (condition-case err
  2949. ;; We keep the local file for performance
  2950. ;; reasons, useful for "rsync".
  2951. (copy-file tmpfile filename t)
  2952. ((error quit)
  2953. (setq tramp-temp-buffer-file-name nil)
  2954. (delete-file tmpfile)
  2955. (signal (car err) (cdr err)))))
  2956. (setq tramp-temp-buffer-file-name nil)
  2957. ;; Don't rename, in order to keep context in SELinux.
  2958. (unwind-protect
  2959. (copy-file tmpfile filename t)
  2960. (delete-file tmpfile))))
  2961. ;; Use inline file transfer.
  2962. (rem-dec
  2963. ;; Encode tmpfile.
  2964. (unwind-protect
  2965. (with-temp-buffer
  2966. (set-buffer-multibyte nil)
  2967. ;; Use encoding function or command.
  2968. (if (functionp loc-enc)
  2969. (tramp-with-progress-reporter
  2970. v 3 (format "Encoding region using function `%s'"
  2971. loc-enc)
  2972. (let ((coding-system-for-read 'binary))
  2973. (insert-file-contents-literally tmpfile))
  2974. ;; The following `let' is a workaround for the
  2975. ;; base64.el that comes with pgnus-0.84. If
  2976. ;; both of the following conditions are
  2977. ;; satisfied, it tries to write to a local
  2978. ;; file in default-directory, but at this
  2979. ;; point, default-directory is remote.
  2980. ;; (`call-process-region' can't write to
  2981. ;; remote files, it seems.) The file in
  2982. ;; question is a tmp file anyway.
  2983. (let ((default-directory
  2984. (tramp-compat-temporary-file-directory)))
  2985. (funcall loc-enc (point-min) (point-max))))
  2986. (tramp-with-progress-reporter
  2987. v 3 (format "Encoding region using command `%s'"
  2988. loc-enc)
  2989. (unless (zerop (tramp-call-local-coding-command
  2990. loc-enc tmpfile t))
  2991. (tramp-error
  2992. v 'file-error
  2993. (concat "Cannot write to `%s', "
  2994. "local encoding command `%s' failed")
  2995. filename loc-enc))))
  2996. ;; Send buffer into remote decoding command which
  2997. ;; writes to remote file. Because this happens on
  2998. ;; the remote host, we cannot use the function.
  2999. (tramp-with-progress-reporter
  3000. v 3
  3001. (format "Decoding region into remote file %s" filename)
  3002. (goto-char (point-max))
  3003. (unless (bolp) (newline))
  3004. (tramp-send-command
  3005. v
  3006. (format
  3007. (concat rem-dec " <<'EOF'\n%sEOF")
  3008. (tramp-shell-quote-argument localname)
  3009. (buffer-string)))
  3010. (tramp-barf-unless-okay
  3011. v nil
  3012. "Couldn't write region to `%s', decode using `%s' failed"
  3013. filename rem-dec)
  3014. ;; When `file-precious-flag' is set, the region is
  3015. ;; written to a temporary file. Check that the
  3016. ;; checksum is equal to that from the local tmpfile.
  3017. (when file-precious-flag
  3018. (erase-buffer)
  3019. (and
  3020. ;; cksum runs locally, if possible.
  3021. (zerop (tramp-compat-call-process "cksum" tmpfile t))
  3022. ;; cksum runs remotely.
  3023. (tramp-send-command-and-check
  3024. v
  3025. (format
  3026. "cksum <%s" (tramp-shell-quote-argument localname)))
  3027. ;; ... they are different.
  3028. (not
  3029. (string-equal
  3030. (buffer-string)
  3031. (with-current-buffer (tramp-get-buffer v)
  3032. (buffer-string))))
  3033. (tramp-error
  3034. v 'file-error
  3035. (concat "Couldn't write region to `%s',"
  3036. " decode using `%s' failed")
  3037. filename rem-dec)))))
  3038. ;; Save exit.
  3039. (delete-file tmpfile)))
  3040. ;; That's not expected.
  3041. (t
  3042. (tramp-error
  3043. v 'file-error
  3044. (concat "Method `%s' should specify both encoding and "
  3045. "decoding command or an rcp program")
  3046. method))))
  3047. ;; Make `last-coding-system-used' have the right value.
  3048. (when coding-system-used
  3049. (set 'last-coding-system-used coding-system-used))))
  3050. (tramp-flush-file-property v (file-name-directory localname))
  3051. (tramp-flush-file-property v localname)
  3052. ;; We must protect `last-coding-system-used', now we have set it
  3053. ;; to its correct value.
  3054. (let (last-coding-system-used (need-chown t))
  3055. ;; Set file modification time.
  3056. (when (or (eq visit t) (stringp visit))
  3057. (let ((file-attr (file-attributes filename)))
  3058. (set-visited-file-modtime
  3059. ;; We must pass modtime explicitly, because filename can
  3060. ;; be different from (buffer-file-name), f.e. if
  3061. ;; `file-precious-flag' is set.
  3062. (nth 5 file-attr))
  3063. (when (and (eq (nth 2 file-attr) uid)
  3064. (eq (nth 3 file-attr) gid))
  3065. (setq need-chown nil))))
  3066. ;; Set the ownership.
  3067. (when need-chown
  3068. (tramp-set-file-uid-gid filename uid gid))
  3069. (when (or (eq visit t) (null visit) (stringp visit))
  3070. (tramp-message v 0 "Wrote %s" filename))
  3071. (run-hooks 'tramp-handle-write-region-hook)))))
  3072. (defvar tramp-vc-registered-file-names nil
  3073. "List used to collect file names, which are checked during `vc-registered'.")
  3074. ;; VC backends check for the existence of various different special
  3075. ;; files. This is very time consuming, because every single check
  3076. ;; requires a remote command (the file cache must be invalidated).
  3077. ;; Therefore, we apply a kind of optimization. We install the file
  3078. ;; name handler `tramp-vc-file-name-handler', which does nothing but
  3079. ;; remembers all file names for which `file-exists-p' or
  3080. ;; `file-readable-p' has been applied. A first run of `vc-registered'
  3081. ;; is performed. Afterwards, a script is applied for all collected
  3082. ;; file names, using just one remote command. The result of this
  3083. ;; script is used to fill the file cache with actual values. Now we
  3084. ;; can reset the file name handlers, and we make a second run of
  3085. ;; `vc-registered', which returns the expected result without sending
  3086. ;; any other remote command.
  3087. (defun tramp-sh-handle-vc-registered (file)
  3088. "Like `vc-registered' for Tramp files."
  3089. (tramp-compat-with-temp-message ""
  3090. (with-parsed-tramp-file-name file nil
  3091. (tramp-with-progress-reporter
  3092. v 3 (format "Checking `vc-registered' for %s" file)
  3093. ;; There could be new files, created by the vc backend. We
  3094. ;; cannot reuse the old cache entries, therefore.
  3095. (let (tramp-vc-registered-file-names
  3096. (remote-file-name-inhibit-cache (current-time))
  3097. (file-name-handler-alist
  3098. `((,tramp-file-name-regexp . tramp-vc-file-name-handler))))
  3099. ;; Here we collect only file names, which need an operation.
  3100. (tramp-run-real-handler 'vc-registered (list file))
  3101. (tramp-message v 10 "\n%s" tramp-vc-registered-file-names)
  3102. ;; Send just one command, in order to fill the cache.
  3103. (when tramp-vc-registered-file-names
  3104. (tramp-maybe-send-script
  3105. v
  3106. (format tramp-vc-registered-read-file-names
  3107. (tramp-get-file-exists-command v)
  3108. (format "%s -r" (tramp-get-test-command v)))
  3109. "tramp_vc_registered_read_file_names")
  3110. (dolist
  3111. (elt
  3112. (tramp-send-command-and-read
  3113. v
  3114. (format
  3115. "tramp_vc_registered_read_file_names <<'EOF'\n%s\nEOF\n"
  3116. (mapconcat 'tramp-shell-quote-argument
  3117. tramp-vc-registered-file-names
  3118. "\n"))))
  3119. (tramp-set-file-property
  3120. v (car elt) (cadr elt) (cadr (cdr elt))))))
  3121. ;; Second run. Now all `file-exists-p' or `file-readable-p'
  3122. ;; calls shall be answered from the file cache. We unset
  3123. ;; `process-file-side-effects' in order to keep the cache when
  3124. ;; `process-file' calls appear.
  3125. (let (process-file-side-effects)
  3126. (tramp-run-real-handler 'vc-registered (list file)))))))
  3127. ;;;###tramp-autoload
  3128. (defun tramp-sh-file-name-handler (operation &rest args)
  3129. "Invoke remote-shell Tramp file name handler.
  3130. Fall back to normal file name handler if no Tramp handler exists."
  3131. (when (and tramp-locked (not tramp-locker))
  3132. (setq tramp-locked nil)
  3133. (signal 'file-error (list "Forbidden reentrant call of Tramp")))
  3134. (let ((tl tramp-locked))
  3135. (unwind-protect
  3136. (progn
  3137. (setq tramp-locked t)
  3138. (let ((tramp-locker t))
  3139. (save-match-data
  3140. (let ((fn (assoc operation tramp-sh-file-name-handler-alist)))
  3141. (if fn
  3142. (apply (cdr fn) args)
  3143. (tramp-run-real-handler operation args))))))
  3144. (setq tramp-locked tl))))
  3145. (defun tramp-vc-file-name-handler (operation &rest args)
  3146. "Invoke special file name handler, which collects files to be handled."
  3147. (save-match-data
  3148. (let ((filename
  3149. (tramp-replace-environment-variables
  3150. (apply 'tramp-file-name-for-operation operation args)))
  3151. (fn (assoc operation tramp-sh-file-name-handler-alist)))
  3152. (with-parsed-tramp-file-name filename nil
  3153. (cond
  3154. ;; That's what we want: file names, for which checks are
  3155. ;; applied. We assume that VC uses only `file-exists-p' and
  3156. ;; `file-readable-p' checks; otherwise we must extend the
  3157. ;; list. We do not perform any action, but return nil, in
  3158. ;; order to keep `vc-registered' running.
  3159. ((and fn (memq operation '(file-exists-p file-readable-p)))
  3160. (add-to-list 'tramp-vc-registered-file-names localname 'append)
  3161. nil)
  3162. ;; Tramp file name handlers like `expand-file-name'. They
  3163. ;; must still work.
  3164. (fn
  3165. (save-match-data (apply (cdr fn) args)))
  3166. ;; Default file name handlers, we don't care.
  3167. (t (tramp-run-real-handler operation args)))))))
  3168. ;;; Internal Functions:
  3169. (defun tramp-maybe-send-script (vec script name)
  3170. "Define in remote shell function NAME implemented as SCRIPT.
  3171. Only send the definition if it has not already been done."
  3172. ;; We cannot let-bind (tramp-get-connection-process vec) because it
  3173. ;; might be nil.
  3174. (let ((scripts (tramp-get-connection-property
  3175. (tramp-get-connection-process vec) "scripts" nil)))
  3176. (unless (member name scripts)
  3177. (tramp-with-progress-reporter vec 5 (format "Sending script `%s'" name)
  3178. ;; The script could contain a call of Perl. This is masked with `%s'.
  3179. (tramp-barf-unless-okay
  3180. vec
  3181. (format "%s () {\n%s\n}" name
  3182. (format script (tramp-get-remote-perl vec)))
  3183. "Script %s sending failed" name)
  3184. (tramp-set-connection-property
  3185. (tramp-get-connection-process vec) "scripts" (cons name scripts))))))
  3186. (defun tramp-set-auto-save ()
  3187. (when (and ;; ange-ftp has its own auto-save mechanism
  3188. (eq (tramp-find-foreign-file-name-handler (buffer-file-name))
  3189. 'tramp-sh-file-name-handler)
  3190. auto-save-default)
  3191. (auto-save-mode 1)))
  3192. (add-hook 'find-file-hooks 'tramp-set-auto-save t)
  3193. (add-hook 'tramp-unload-hook
  3194. (lambda ()
  3195. (remove-hook 'find-file-hooks 'tramp-set-auto-save)))
  3196. (defun tramp-run-test (switch filename)
  3197. "Run `test' on the remote system, given a SWITCH and a FILENAME.
  3198. Returns the exit code of the `test' program."
  3199. (with-parsed-tramp-file-name filename nil
  3200. (tramp-send-command-and-check
  3201. v
  3202. (format
  3203. "%s %s %s"
  3204. (tramp-get-test-command v)
  3205. switch
  3206. (tramp-shell-quote-argument localname)))))
  3207. (defun tramp-run-test2 (format-string file1 file2)
  3208. "Run `test'-like program on the remote system, given FILE1, FILE2.
  3209. FORMAT-STRING contains the program name, switches, and place holders.
  3210. Returns the exit code of the `test' program. Barfs if the methods,
  3211. hosts, or files, disagree."
  3212. (unless (tramp-equal-remote file1 file2)
  3213. (with-parsed-tramp-file-name (if (tramp-tramp-file-p file1) file1 file2) nil
  3214. (tramp-error
  3215. v 'file-error
  3216. "tramp-run-test2 only implemented for same method, user, host")))
  3217. (with-parsed-tramp-file-name file1 v1
  3218. (with-parsed-tramp-file-name file1 v2
  3219. (tramp-send-command-and-check
  3220. v1
  3221. (format format-string
  3222. (tramp-shell-quote-argument v1-localname)
  3223. (tramp-shell-quote-argument v2-localname))))))
  3224. (defun tramp-find-executable
  3225. (vec progname dirlist &optional ignore-tilde ignore-path)
  3226. "Searches for PROGNAME in $PATH and all directories mentioned in DIRLIST.
  3227. First arg VEC specifies the connection, PROGNAME is the program
  3228. to search for, and DIRLIST gives the list of directories to
  3229. search. If IGNORE-TILDE is non-nil, directory names starting
  3230. with `~' will be ignored. If IGNORE-PATH is non-nil, searches
  3231. only in DIRLIST.
  3232. Returns the absolute file name of PROGNAME, if found, and nil otherwise.
  3233. This function expects to be in the right *tramp* buffer."
  3234. (with-current-buffer (tramp-get-connection-buffer vec)
  3235. (let (result)
  3236. ;; Check whether the executable is in $PATH. "which(1)" does not
  3237. ;; report always a correct error code; therefore we check the
  3238. ;; number of words it returns.
  3239. (unless ignore-path
  3240. (tramp-send-command vec (format "which \\%s | wc -w" progname))
  3241. (goto-char (point-min))
  3242. (if (looking-at "^\\s-*1$")
  3243. (setq result (concat "\\" progname))))
  3244. (unless result
  3245. (when ignore-tilde
  3246. ;; Remove all ~/foo directories from dirlist. In XEmacs,
  3247. ;; `remove' is in CL, and we want to avoid CL dependencies.
  3248. (let (newdl d)
  3249. (while dirlist
  3250. (setq d (car dirlist))
  3251. (setq dirlist (cdr dirlist))
  3252. (unless (char-equal ?~ (aref d 0))
  3253. (setq newdl (cons d newdl))))
  3254. (setq dirlist (nreverse newdl))))
  3255. (tramp-send-command
  3256. vec
  3257. (format (concat "while read d; "
  3258. "do if test -x $d/%s -a -f $d/%s; "
  3259. "then echo tramp_executable $d/%s; "
  3260. "break; fi; done <<'EOF'\n"
  3261. "%s\nEOF")
  3262. progname progname progname (mapconcat 'identity dirlist "\n")))
  3263. (goto-char (point-max))
  3264. (when (search-backward "tramp_executable " nil t)
  3265. (skip-chars-forward "^ ")
  3266. (skip-chars-forward " ")
  3267. (setq result (buffer-substring (point) (point-at-eol)))))
  3268. result)))
  3269. (defun tramp-set-remote-path (vec)
  3270. "Sets the remote environment PATH to existing directories.
  3271. I.e., for each directory in `tramp-remote-path', it is tested
  3272. whether it exists and if so, it is added to the environment
  3273. variable PATH."
  3274. (tramp-message vec 5 (format "Setting $PATH environment variable"))
  3275. (tramp-send-command
  3276. vec (format "PATH=%s; export PATH"
  3277. (mapconcat 'identity (tramp-get-remote-path vec) ":"))))
  3278. ;; ------------------------------------------------------------
  3279. ;; -- Communication with external shell --
  3280. ;; ------------------------------------------------------------
  3281. (defun tramp-find-file-exists-command (vec)
  3282. "Find a command on the remote host for checking if a file exists.
  3283. Here, we are looking for a command which has zero exit status if the
  3284. file exists and nonzero exit status otherwise."
  3285. (let ((existing "/")
  3286. (nonexistent
  3287. (tramp-shell-quote-argument "/ this file does not exist "))
  3288. result)
  3289. ;; The algorithm is as follows: we try a list of several commands.
  3290. ;; For each command, we first run `$cmd /' -- this should return
  3291. ;; true, as the root directory always exists. And then we run
  3292. ;; `$cmd /this\ file\ does\ not\ exist ', hoping that the file indeed
  3293. ;; does not exist. This should return false. We use the first
  3294. ;; command we find that seems to work.
  3295. ;; The list of commands to try is as follows:
  3296. ;; `ls -d' This works on most systems, but NetBSD 1.4
  3297. ;; has a bug: `ls' always returns zero exit
  3298. ;; status, even for files which don't exist.
  3299. ;; `test -e' Some Bourne shells have a `test' builtin
  3300. ;; which does not know the `-e' option.
  3301. ;; `/bin/test -e' For those, the `test' binary on disk normally
  3302. ;; provides the option. Alas, the binary
  3303. ;; is sometimes `/bin/test' and sometimes it's
  3304. ;; `/usr/bin/test'.
  3305. ;; `/usr/bin/test -e' In case `/bin/test' does not exist.
  3306. (unless (or
  3307. (and (setq result (format "%s -e" (tramp-get-test-command vec)))
  3308. (tramp-send-command-and-check
  3309. vec (format "%s %s" result existing))
  3310. (not (tramp-send-command-and-check
  3311. vec (format "%s %s" result nonexistent))))
  3312. (and (setq result "/bin/test -e")
  3313. (tramp-send-command-and-check
  3314. vec (format "%s %s" result existing))
  3315. (not (tramp-send-command-and-check
  3316. vec (format "%s %s" result nonexistent))))
  3317. (and (setq result "/usr/bin/test -e")
  3318. (tramp-send-command-and-check
  3319. vec (format "%s %s" result existing))
  3320. (not (tramp-send-command-and-check
  3321. vec (format "%s %s" result nonexistent))))
  3322. (and (setq result (format "%s -d" (tramp-get-ls-command vec)))
  3323. (tramp-send-command-and-check
  3324. vec (format "%s %s" result existing))
  3325. (not (tramp-send-command-and-check
  3326. vec (format "%s %s" result nonexistent)))))
  3327. (tramp-error
  3328. vec 'file-error "Couldn't find command to check if file exists"))
  3329. result))
  3330. (defun tramp-open-shell (vec shell)
  3331. "Opens shell SHELL."
  3332. (tramp-with-progress-reporter
  3333. vec 5 (format "Opening remote shell `%s'" shell)
  3334. ;; Find arguments for this shell.
  3335. (let ((tramp-end-of-output tramp-initial-end-of-output)
  3336. (alist tramp-sh-extra-args)
  3337. item extra-args)
  3338. (while (and alist (null extra-args))
  3339. (setq item (pop alist))
  3340. (when (string-match (car item) shell)
  3341. (setq extra-args (cdr item))))
  3342. (when extra-args (setq shell (concat shell " " extra-args)))
  3343. (tramp-send-command
  3344. vec (format "exec env ENV='' PROMPT_COMMAND='' PS1=%s PS2='' PS3='' %s"
  3345. (tramp-shell-quote-argument tramp-end-of-output) shell)
  3346. t))
  3347. ;; Setting prompts.
  3348. (tramp-send-command
  3349. vec (format "PS1=%s" (tramp-shell-quote-argument tramp-end-of-output)) t)
  3350. (tramp-send-command vec "PS2=''" t)
  3351. (tramp-send-command vec "PS3=''" t)
  3352. (tramp-send-command vec "PROMPT_COMMAND=''" t)))
  3353. (defun tramp-find-shell (vec)
  3354. "Opens a shell on the remote host which groks tilde expansion."
  3355. (unless (tramp-get-connection-property vec "remote-shell" nil)
  3356. (let (shell)
  3357. (with-current-buffer (tramp-get-buffer vec)
  3358. (tramp-send-command vec "echo ~root" t)
  3359. (cond
  3360. ((or (string-match "^~root$" (buffer-string))
  3361. ;; The default shell (ksh93) of OpenSolaris and Solaris
  3362. ;; is buggy. We've got reports for "SunOS 5.10" and
  3363. ;; "SunOS 5.11" so far.
  3364. (string-match (regexp-opt '("SunOS 5.10" "SunOS 5.11"))
  3365. (tramp-get-connection-property vec "uname" "")))
  3366. (setq shell
  3367. (or (tramp-find-executable
  3368. vec "bash" (tramp-get-remote-path vec) t t)
  3369. (tramp-find-executable
  3370. vec "ksh" (tramp-get-remote-path vec) t t)))
  3371. (unless shell
  3372. (tramp-error
  3373. vec 'file-error
  3374. "Couldn't find a shell which groks tilde expansion"))
  3375. (tramp-message
  3376. vec 5 "Starting remote shell `%s' for tilde expansion"
  3377. (tramp-set-connection-property vec "remote-shell" shell))
  3378. (tramp-open-shell vec shell))
  3379. (t (tramp-message
  3380. vec 5 "Remote `%s' groks tilde expansion, good"
  3381. (tramp-set-connection-property
  3382. vec "remote-shell"
  3383. (tramp-get-method-parameter
  3384. (tramp-file-name-method vec) 'tramp-remote-shell)))))))))
  3385. ;; Utility functions.
  3386. (defun tramp-barf-if-no-shell-prompt (proc timeout &rest error-args)
  3387. "Wait for shell prompt and barf if none appears.
  3388. Looks at process PROC to see if a shell prompt appears in TIMEOUT
  3389. seconds. If not, it produces an error message with the given ERROR-ARGS."
  3390. (unless
  3391. (tramp-wait-for-regexp
  3392. proc timeout
  3393. (format
  3394. "\\(%s\\|%s\\)\\'" shell-prompt-pattern tramp-shell-prompt-pattern))
  3395. (apply 'tramp-error-with-buffer nil proc 'file-error error-args)))
  3396. (defun tramp-open-connection-setup-interactive-shell (proc vec)
  3397. "Set up an interactive shell.
  3398. Mainly sets the prompt and the echo correctly. PROC is the shell
  3399. process to set up. VEC specifies the connection."
  3400. (let ((tramp-end-of-output tramp-initial-end-of-output))
  3401. ;; It is useful to set the prompt in the following command because
  3402. ;; some people have a setting for $PS1 which /bin/sh doesn't know
  3403. ;; about and thus /bin/sh will display a strange prompt. For
  3404. ;; example, if $PS1 has "${CWD}" in the value, then ksh will
  3405. ;; display the current working directory but /bin/sh will display
  3406. ;; a dollar sign. The following command line sets $PS1 to a sane
  3407. ;; value, and works under Bourne-ish shells as well as csh-like
  3408. ;; shells. Daniel Pittman reports that the unusual positioning of
  3409. ;; the single quotes makes it work under `rc', too. We also unset
  3410. ;; the variable $ENV because that is read by some sh
  3411. ;; implementations (eg, bash when called as sh) on startup; this
  3412. ;; way, we avoid the startup file clobbering $PS1. $PROMPT_COMMAND
  3413. ;; is another way to set the prompt in /bin/bash, it must be
  3414. ;; discarded as well.
  3415. (tramp-open-shell
  3416. vec
  3417. (tramp-get-method-parameter
  3418. (tramp-file-name-method vec) 'tramp-remote-shell))
  3419. ;; Disable echo.
  3420. (tramp-message vec 5 "Setting up remote shell environment")
  3421. (tramp-send-command vec "stty -inlcr -echo kill '^U' erase '^H'" t)
  3422. ;; Check whether the echo has really been disabled. Some
  3423. ;; implementations, like busybox of embedded GNU/Linux, don't
  3424. ;; support disabling.
  3425. (tramp-send-command vec "echo foo" t)
  3426. (with-current-buffer (process-buffer proc)
  3427. (goto-char (point-min))
  3428. (when (looking-at "echo foo")
  3429. (tramp-set-connection-property proc "remote-echo" t)
  3430. (tramp-message vec 5 "Remote echo still on. Ok.")
  3431. ;; Make sure backspaces and their echo are enabled and no line
  3432. ;; width magic interferes with them.
  3433. (tramp-send-command vec "stty icanon erase ^H cols 32767" t))))
  3434. (tramp-message vec 5 "Setting shell prompt")
  3435. (tramp-send-command
  3436. vec (format "PS1=%s" (tramp-shell-quote-argument tramp-end-of-output)) t)
  3437. (tramp-send-command vec "PS2=''" t)
  3438. (tramp-send-command vec "PS3=''" t)
  3439. (tramp-send-command vec "PROMPT_COMMAND=''" t)
  3440. ;; Try to set up the coding system correctly.
  3441. ;; CCC this can't be the right way to do it. Hm.
  3442. (tramp-message vec 5 "Determining coding system")
  3443. (tramp-send-command vec "echo foo ; echo bar" t)
  3444. (with-current-buffer (process-buffer proc)
  3445. (goto-char (point-min))
  3446. (if (featurep 'mule)
  3447. ;; Use MULE to select the right EOL convention for communicating
  3448. ;; with the process.
  3449. (let* ((cs (or (tramp-compat-funcall 'process-coding-system proc)
  3450. (cons 'undecided 'undecided)))
  3451. cs-decode cs-encode)
  3452. (when (symbolp cs) (setq cs (cons cs cs)))
  3453. (setq cs-decode (car cs))
  3454. (setq cs-encode (cdr cs))
  3455. (unless cs-decode (setq cs-decode 'undecided))
  3456. (unless cs-encode (setq cs-encode 'undecided))
  3457. (setq cs-encode (tramp-compat-coding-system-change-eol-conversion
  3458. cs-encode 'unix))
  3459. (when (search-forward "\r" nil t)
  3460. (setq cs-decode (tramp-compat-coding-system-change-eol-conversion
  3461. cs-decode 'dos)))
  3462. (tramp-compat-funcall
  3463. 'set-buffer-process-coding-system cs-decode cs-encode)
  3464. (tramp-message
  3465. vec 5 "Setting coding system to `%s' and `%s'" cs-decode cs-encode))
  3466. ;; Look for ^M and do something useful if found.
  3467. (when (search-forward "\r" nil t)
  3468. ;; We have found a ^M but cannot frob the process coding system
  3469. ;; because we're running on a non-MULE Emacs. Let's try
  3470. ;; stty, instead.
  3471. (tramp-send-command vec "stty -onlcr" t))))
  3472. (tramp-send-command vec "set +o vi +o emacs" t)
  3473. ;; Check whether the output of "uname -sr" has been changed. If
  3474. ;; yes, this is a strong indication that we must expire all
  3475. ;; connection properties. We start again with
  3476. ;; `tramp-maybe-open-connection', it will be caught there.
  3477. (tramp-message vec 5 "Checking system information")
  3478. (let ((old-uname (tramp-get-connection-property vec "uname" nil))
  3479. (new-uname
  3480. (tramp-set-connection-property
  3481. vec "uname"
  3482. (tramp-send-command-and-read vec "echo \\\"`uname -sr`\\\""))))
  3483. (when (and (stringp old-uname) (not (string-equal old-uname new-uname)))
  3484. (with-current-buffer (tramp-get-debug-buffer vec)
  3485. ;; Keep the debug buffer.
  3486. (rename-buffer
  3487. (generate-new-buffer-name tramp-temp-buffer-name) 'unique)
  3488. (tramp-cleanup-connection vec)
  3489. (if (= (point-min) (point-max))
  3490. (kill-buffer nil)
  3491. (rename-buffer (tramp-debug-buffer-name vec) 'unique))
  3492. ;; We call `tramp-get-buffer' in order to keep the debug buffer.
  3493. (tramp-get-buffer vec)
  3494. (tramp-message
  3495. vec 3
  3496. "Connection reset, because remote host changed from `%s' to `%s'"
  3497. old-uname new-uname)
  3498. (throw 'uname-changed (tramp-maybe-open-connection vec)))))
  3499. ;; Check whether the remote host suffers from buggy
  3500. ;; `send-process-string'. This is known for FreeBSD (see comment in
  3501. ;; `send_process', file process.c). I've tested sending 624 bytes
  3502. ;; successfully, sending 625 bytes failed. Emacs makes a hack when
  3503. ;; this host type is detected locally. It cannot handle remote
  3504. ;; hosts, though.
  3505. (with-connection-property proc "chunksize"
  3506. (cond
  3507. ((and (integerp tramp-chunksize) (> tramp-chunksize 0))
  3508. tramp-chunksize)
  3509. (t
  3510. (tramp-message
  3511. vec 5 "Checking remote host type for `send-process-string' bug")
  3512. (if (string-match
  3513. "^FreeBSD" (tramp-get-connection-property vec "uname" ""))
  3514. 500 0))))
  3515. ;; Set remote PATH variable.
  3516. (tramp-set-remote-path vec)
  3517. ;; Search for a good shell before searching for a command which
  3518. ;; checks if a file exists. This is done because Tramp wants to use
  3519. ;; "test foo; echo $?" to check if various conditions hold, and
  3520. ;; there are buggy /bin/sh implementations which don't execute the
  3521. ;; "echo $?" part if the "test" part has an error. In particular,
  3522. ;; the OpenSolaris /bin/sh is a problem. There are also other
  3523. ;; problems with /bin/sh of OpenSolaris, like redirection of stderr
  3524. ;; in function declarations, or changing HISTFILE in place.
  3525. ;; Therefore, OpenSolaris' /bin/sh is replaced by bash, when
  3526. ;; detected.
  3527. (tramp-find-shell vec)
  3528. ;; Disable unexpected output.
  3529. (tramp-send-command vec "mesg n; biff n" t)
  3530. ;; Busyboxes tend to behave strange. We check for the existence.
  3531. (with-connection-property vec "busybox"
  3532. (tramp-send-command
  3533. vec
  3534. (format
  3535. "%s --version" (tramp-get-connection-property vec "remote-shell" "echo"))
  3536. t)
  3537. (with-current-buffer (process-buffer proc)
  3538. (let ((case-fold-search t))
  3539. (and (string-match "busybox" (buffer-string)) t))))
  3540. ;; IRIX64 bash expands "!" even when in single quotes. This
  3541. ;; destroys our shell functions, we must disable it. See
  3542. ;; <http://stackoverflow.com/questions/3291692/irix-bash-shell-expands-expression-in-single-quotes-yet-shouldnt>.
  3543. (when (string-match "^IRIX64" (tramp-get-connection-property vec "uname" ""))
  3544. (tramp-send-command vec "set +H" t))
  3545. ;; On BSD-like systems, ?\t is expanded to spaces. Suppress this.
  3546. (when (string-match "BSD\\|Darwin"
  3547. (tramp-get-connection-property vec "uname" ""))
  3548. (tramp-send-command vec "stty -oxtabs" t))
  3549. ;; Set `remote-tty' process property.
  3550. (let ((tty (tramp-send-command-and-read vec "echo \\\"`tty`\\\"" 'noerror)))
  3551. (unless (zerop (length tty))
  3552. (tramp-compat-process-put proc 'remote-tty tty)))
  3553. ;; Dump stty settings in the traces.
  3554. (when (>= tramp-verbose 9)
  3555. (tramp-send-command vec "stty -a" t))
  3556. ;; Set the environment.
  3557. (tramp-message vec 5 "Setting default environment")
  3558. (let ((env (copy-sequence tramp-remote-process-environment))
  3559. unset item)
  3560. (while env
  3561. (setq item (tramp-compat-split-string (car env) "="))
  3562. (setcdr item (mapconcat 'identity (cdr item) "="))
  3563. (if (and (stringp (cdr item)) (not (string-equal (cdr item) "")))
  3564. (tramp-send-command
  3565. vec (format "%s=%s; export %s" (car item) (cdr item) (car item)) t)
  3566. (push (car item) unset))
  3567. (setq env (cdr env)))
  3568. (when unset
  3569. (tramp-send-command
  3570. vec (format "unset %s" (mapconcat 'identity unset " ")) t))))
  3571. ;; CCC: We should either implement a Perl version of base64 encoding
  3572. ;; and decoding. Then we just use that in the last item. The other
  3573. ;; alternative is to use the Perl version of UU encoding. But then
  3574. ;; we need a Lisp version of uuencode.
  3575. ;;
  3576. ;; Old text from documentation of tramp-methods:
  3577. ;; Using a uuencode/uudecode inline method is discouraged, please use one
  3578. ;; of the base64 methods instead since base64 encoding is much more
  3579. ;; reliable and the commands are more standardized between the different
  3580. ;; Unix versions. But if you can't use base64 for some reason, please
  3581. ;; note that the default uudecode command does not work well for some
  3582. ;; Unices, in particular AIX and Irix. For AIX, you might want to use
  3583. ;; the following command for uudecode:
  3584. ;;
  3585. ;; sed '/^begin/d;/^[` ]$/d;/^end/d' | iconv -f uucode -t ISO8859-1
  3586. ;;
  3587. ;; For Irix, no solution is known yet.
  3588. (autoload 'uudecode-decode-region "uudecode")
  3589. (defconst tramp-local-coding-commands
  3590. '((b64 base64-encode-region base64-decode-region)
  3591. (uu tramp-uuencode-region uudecode-decode-region)
  3592. (pack
  3593. "perl -e 'binmode STDIN; binmode STDOUT; print pack(q{u*}, join q{}, <>)'"
  3594. "perl -e 'binmode STDIN; binmode STDOUT; print unpack(q{u*}, join q{}, <>)'"))
  3595. "List of local coding commands for inline transfer.
  3596. Each item is a list that looks like this:
  3597. \(FORMAT ENCODING DECODING\)
  3598. FORMAT is symbol describing the encoding/decoding format. It can be
  3599. `b64' for base64 encoding, `uu' for uu encoding, or `pack' for simple packing.
  3600. ENCODING and DECODING can be strings, giving commands, or symbols,
  3601. giving functions. If they are strings, then they can contain
  3602. the \"%s\" format specifier. If that specifier is present, the input
  3603. filename will be put into the command line at that spot. If the
  3604. specifier is not present, the input should be read from standard
  3605. input.
  3606. If they are functions, they will be called with two arguments, start
  3607. and end of region, and are expected to replace the region contents
  3608. with the encoded or decoded results, respectively.")
  3609. (defconst tramp-remote-coding-commands
  3610. '((b64 "base64" "base64 -d -i")
  3611. ;; "-i" is more robust with older base64 from GNU coreutils.
  3612. ;; However, I don't know whether all base64 versions do supports
  3613. ;; this option.
  3614. (b64 "base64" "base64 -d")
  3615. (b64 "mimencode -b" "mimencode -u -b")
  3616. (b64 "mmencode -b" "mmencode -u -b")
  3617. (b64 "recode data..base64" "recode base64..data")
  3618. (b64 tramp-perl-encode-with-module tramp-perl-decode-with-module)
  3619. (b64 tramp-perl-encode tramp-perl-decode)
  3620. (uu "uuencode xxx" "uudecode -o /dev/stdout")
  3621. (uu "uuencode xxx" "uudecode -o -")
  3622. (uu "uuencode xxx" "uudecode -p")
  3623. (uu "uuencode xxx" tramp-uudecode)
  3624. (pack
  3625. "perl -e 'binmode STDIN; binmode STDOUT; print pack(q{u*}, join q{}, <>)'"
  3626. "perl -e 'binmode STDIN; binmode STDOUT; print unpack(q{u*}, join q{}, <>)'"))
  3627. "List of remote coding commands for inline transfer.
  3628. Each item is a list that looks like this:
  3629. \(FORMAT ENCODING DECODING\)
  3630. FORMAT is symbol describing the encoding/decoding format. It can be
  3631. `b64' for base64 encoding, `uu' for uu encoding, or `pack' for simple packing.
  3632. ENCODING and DECODING can be strings, giving commands, or symbols,
  3633. giving variables. If they are strings, then they can contain
  3634. the \"%s\" format specifier. If that specifier is present, the input
  3635. filename will be put into the command line at that spot. If the
  3636. specifier is not present, the input should be read from standard
  3637. input.
  3638. If they are variables, this variable is a string containing a Perl
  3639. implementation for this functionality. This Perl program will be transferred
  3640. to the remote host, and it is available as shell function with the same name.")
  3641. (defun tramp-find-inline-encoding (vec)
  3642. "Find an inline transfer encoding that works.
  3643. Goes through the list `tramp-local-coding-commands' and
  3644. `tramp-remote-coding-commands'."
  3645. (save-excursion
  3646. (let ((local-commands tramp-local-coding-commands)
  3647. (magic "xyzzy")
  3648. loc-enc loc-dec rem-enc rem-dec litem ritem found)
  3649. (while (and local-commands (not found))
  3650. (setq litem (pop local-commands))
  3651. (catch 'wont-work-local
  3652. (let ((format (nth 0 litem))
  3653. (remote-commands tramp-remote-coding-commands))
  3654. (setq loc-enc (nth 1 litem))
  3655. (setq loc-dec (nth 2 litem))
  3656. ;; If the local encoder or decoder is a string, the
  3657. ;; corresponding command has to work locally.
  3658. (if (not (stringp loc-enc))
  3659. (tramp-message
  3660. vec 5 "Checking local encoding function `%s'" loc-enc)
  3661. (tramp-message
  3662. vec 5 "Checking local encoding command `%s' for sanity" loc-enc)
  3663. (unless (zerop (tramp-call-local-coding-command
  3664. loc-enc nil nil))
  3665. (throw 'wont-work-local nil)))
  3666. (if (not (stringp loc-dec))
  3667. (tramp-message
  3668. vec 5 "Checking local decoding function `%s'" loc-dec)
  3669. (tramp-message
  3670. vec 5 "Checking local decoding command `%s' for sanity" loc-dec)
  3671. (unless (zerop (tramp-call-local-coding-command
  3672. loc-dec nil nil))
  3673. (throw 'wont-work-local nil)))
  3674. ;; Search for remote coding commands with the same format
  3675. (while (and remote-commands (not found))
  3676. (setq ritem (pop remote-commands))
  3677. (catch 'wont-work-remote
  3678. (when (equal format (nth 0 ritem))
  3679. (setq rem-enc (nth 1 ritem))
  3680. (setq rem-dec (nth 2 ritem))
  3681. ;; Check if remote encoding and decoding commands can be
  3682. ;; called remotely with null input and output. This makes
  3683. ;; sure there are no syntax errors and the command is really
  3684. ;; found. Note that we do not redirect stdout to /dev/null,
  3685. ;; for two reasons: when checking the decoding command, we
  3686. ;; actually check the output it gives. And also, when
  3687. ;; redirecting "mimencode" output to /dev/null, then as root
  3688. ;; it might change the permissions of /dev/null!
  3689. (when (not (stringp rem-enc))
  3690. (let ((name (symbol-name rem-enc)))
  3691. (while (string-match (regexp-quote "-") name)
  3692. (setq name (replace-match "_" nil t name)))
  3693. (tramp-maybe-send-script vec (symbol-value rem-enc) name)
  3694. (setq rem-enc name)))
  3695. (tramp-message
  3696. vec 5
  3697. "Checking remote encoding command `%s' for sanity" rem-enc)
  3698. (unless (tramp-send-command-and-check
  3699. vec (format "%s </dev/null" rem-enc) t)
  3700. (throw 'wont-work-remote nil))
  3701. (when (not (stringp rem-dec))
  3702. (let ((name (symbol-name rem-dec)))
  3703. (while (string-match (regexp-quote "-") name)
  3704. (setq name (replace-match "_" nil t name)))
  3705. (tramp-maybe-send-script vec (symbol-value rem-dec) name)
  3706. (setq rem-dec name)))
  3707. (tramp-message
  3708. vec 5
  3709. "Checking remote decoding command `%s' for sanity" rem-dec)
  3710. (unless (tramp-send-command-and-check
  3711. vec
  3712. (format "echo %s | %s | %s" magic rem-enc rem-dec)
  3713. t)
  3714. (throw 'wont-work-remote nil))
  3715. (with-current-buffer (tramp-get-buffer vec)
  3716. (goto-char (point-min))
  3717. (unless (looking-at (regexp-quote magic))
  3718. (throw 'wont-work-remote nil)))
  3719. ;; `rem-enc' and `rem-dec' could be a string meanwhile.
  3720. (setq rem-enc (nth 1 ritem))
  3721. (setq rem-dec (nth 2 ritem))
  3722. (setq found t)))))))
  3723. ;; Did we find something?
  3724. (unless found
  3725. (tramp-error
  3726. vec 'file-error "Couldn't find an inline transfer encoding"))
  3727. ;; Set connection properties.
  3728. (tramp-message vec 5 "Using local encoding `%s'" loc-enc)
  3729. (tramp-set-connection-property vec "local-encoding" loc-enc)
  3730. (tramp-message vec 5 "Using local decoding `%s'" loc-dec)
  3731. (tramp-set-connection-property vec "local-decoding" loc-dec)
  3732. (tramp-message vec 5 "Using remote encoding `%s'" rem-enc)
  3733. (tramp-set-connection-property vec "remote-encoding" rem-enc)
  3734. (tramp-message vec 5 "Using remote decoding `%s'" rem-dec)
  3735. (tramp-set-connection-property vec "remote-decoding" rem-dec))))
  3736. (defun tramp-call-local-coding-command (cmd input output)
  3737. "Call the local encoding or decoding command.
  3738. If CMD contains \"%s\", provide input file INPUT there in command.
  3739. Otherwise, INPUT is passed via standard input.
  3740. INPUT can also be nil which means `/dev/null'.
  3741. OUTPUT can be a string (which specifies a filename), or t (which
  3742. means standard output and thus the current buffer), or nil (which
  3743. means discard it)."
  3744. (tramp-compat-call-process
  3745. tramp-encoding-shell
  3746. (when (and input (not (string-match "%s" cmd))) input)
  3747. (if (eq output t) t nil)
  3748. nil
  3749. tramp-encoding-command-switch
  3750. (concat
  3751. (if (string-match "%s" cmd) (format cmd input) cmd)
  3752. (if (stringp output) (concat "> " output) ""))))
  3753. (defconst tramp-inline-compress-commands
  3754. '(("gzip" "gzip -d")
  3755. ("bzip2" "bzip2 -d")
  3756. ("xz" "xz -d")
  3757. ("compress" "compress -d"))
  3758. "List of compress and decompress commands for inline transfer.
  3759. Each item is a list that looks like this:
  3760. \(COMPRESS DECOMPRESS\)
  3761. COMPRESS or DECOMPRESS are strings with the respective commands.")
  3762. (defun tramp-find-inline-compress (vec)
  3763. "Find an inline transfer compress command that works.
  3764. Goes through the list `tramp-inline-compress-commands'."
  3765. (save-excursion
  3766. (let ((commands tramp-inline-compress-commands)
  3767. (magic "xyzzy")
  3768. item compress decompress
  3769. found)
  3770. (while (and commands (not found))
  3771. (catch 'next
  3772. (setq item (pop commands)
  3773. compress (nth 0 item)
  3774. decompress (nth 1 item))
  3775. (tramp-message
  3776. vec 5
  3777. "Checking local compress command `%s', `%s' for sanity"
  3778. compress decompress)
  3779. (unless
  3780. (zerop
  3781. (tramp-call-local-coding-command
  3782. (format
  3783. ;; Windows shells need the program file name after
  3784. ;; the pipe symbol be quoted if they use forward
  3785. ;; slashes as directory separators.
  3786. (if (memq system-type '(windows-nt))
  3787. "echo %s | \"%s\" | \"%s\""
  3788. "echo %s | %s | %s")
  3789. magic compress decompress) nil nil))
  3790. (throw 'next nil))
  3791. (tramp-message
  3792. vec 5
  3793. "Checking remote compress command `%s', `%s' for sanity"
  3794. compress decompress)
  3795. (unless (tramp-send-command-and-check
  3796. vec (format "echo %s | %s | %s" magic compress decompress) t)
  3797. (throw 'next nil))
  3798. (setq found t)))
  3799. ;; Did we find something?
  3800. (if found
  3801. (progn
  3802. ;; Set connection properties.
  3803. (tramp-message
  3804. vec 5 "Using inline transfer compress command `%s'" compress)
  3805. (tramp-set-connection-property vec "inline-compress" compress)
  3806. (tramp-message
  3807. vec 5 "Using inline transfer decompress command `%s'" decompress)
  3808. (tramp-set-connection-property vec "inline-decompress" decompress))
  3809. (tramp-set-connection-property vec "inline-compress" nil)
  3810. (tramp-set-connection-property vec "inline-decompress" nil)
  3811. (tramp-message
  3812. vec 2 "Couldn't find an inline transfer compress command")))))
  3813. (defun tramp-compute-multi-hops (vec)
  3814. "Expands VEC according to `tramp-default-proxies-alist'.
  3815. Gateway hops are already opened."
  3816. (let ((target-alist `(,vec))
  3817. (choices tramp-default-proxies-alist)
  3818. item proxy)
  3819. ;; Look for proxy hosts to be passed.
  3820. (while choices
  3821. (setq item (pop choices)
  3822. proxy (eval (nth 2 item)))
  3823. (when (and
  3824. ;; host
  3825. (string-match (or (eval (nth 0 item)) "")
  3826. (or (tramp-file-name-host (car target-alist)) ""))
  3827. ;; user
  3828. (string-match (or (eval (nth 1 item)) "")
  3829. (or (tramp-file-name-user (car target-alist)) "")))
  3830. (if (null proxy)
  3831. ;; No more hops needed.
  3832. (setq choices nil)
  3833. ;; Replace placeholders.
  3834. (setq proxy
  3835. (format-spec
  3836. proxy
  3837. (format-spec-make
  3838. ?u (or (tramp-file-name-user (car target-alist)) "")
  3839. ?h (or (tramp-file-name-host (car target-alist)) ""))))
  3840. (with-parsed-tramp-file-name proxy l
  3841. ;; Add the hop.
  3842. (add-to-list 'target-alist l)
  3843. ;; Start next search.
  3844. (setq choices tramp-default-proxies-alist)))))
  3845. ;; Handle gateways.
  3846. (when (string-match
  3847. (format
  3848. "^\\(%s\\|%s\\)$" tramp-gw-tunnel-method tramp-gw-socks-method)
  3849. (tramp-file-name-method (car target-alist)))
  3850. (let ((gw (pop target-alist))
  3851. (hop (pop target-alist)))
  3852. ;; Is the method prepared for gateways?
  3853. (unless (tramp-file-name-port hop)
  3854. (tramp-error
  3855. vec 'file-error
  3856. "Connection `%s' is not supported for gateway access." hop))
  3857. ;; Open the gateway connection.
  3858. (add-to-list
  3859. 'target-alist
  3860. (vector
  3861. (tramp-file-name-method hop) (tramp-file-name-user hop)
  3862. (tramp-compat-funcall 'tramp-gw-open-connection vec gw hop) nil))
  3863. ;; For the password prompt, we need the correct values.
  3864. ;; Therefore, we must remember the gateway vector. But we
  3865. ;; cannot do it as connection property, because it shouldn't
  3866. ;; be persistent. And we have no started process yet either.
  3867. (tramp-set-file-property (car target-alist) "" "gateway" hop)))
  3868. ;; Foreign and out-of-band methods are not supported for multi-hops.
  3869. (when (cdr target-alist)
  3870. (setq choices target-alist)
  3871. (while choices
  3872. (setq item (pop choices))
  3873. (when
  3874. (or
  3875. (not
  3876. (tramp-get-method-parameter
  3877. (tramp-file-name-method item) 'tramp-login-program))
  3878. (tramp-get-method-parameter
  3879. (tramp-file-name-method item) 'tramp-copy-program))
  3880. (tramp-error
  3881. vec 'file-error
  3882. "Method `%s' is not supported for multi-hops."
  3883. (tramp-file-name-method item)))))
  3884. ;; In case the host name is not used for the remote shell
  3885. ;; command, the user could be misguided by applying a random
  3886. ;; hostname.
  3887. (let* ((v (car target-alist))
  3888. (method (tramp-file-name-method v))
  3889. (host (tramp-file-name-host v)))
  3890. (unless
  3891. (or
  3892. ;; There are multi-hops.
  3893. (cdr target-alist)
  3894. ;; The host name is used for the remote shell command.
  3895. (member
  3896. '("%h") (tramp-get-method-parameter method 'tramp-login-args))
  3897. ;; The host is local. We cannot use `tramp-local-host-p'
  3898. ;; here, because it opens a connection as well.
  3899. (string-match tramp-local-host-regexp host))
  3900. (tramp-error
  3901. v 'file-error
  3902. "Host `%s' looks like a remote host, `%s' can only use the local host"
  3903. host method)))
  3904. ;; Result.
  3905. target-alist))
  3906. (defun tramp-maybe-open-connection (vec)
  3907. "Maybe open a connection VEC.
  3908. Does not do anything if a connection is already open, but re-opens the
  3909. connection if a previous connection has died for some reason."
  3910. (catch 'uname-changed
  3911. (let ((p (tramp-get-connection-process vec))
  3912. (process-name (tramp-get-connection-property vec "process-name" nil))
  3913. (process-environment (copy-sequence process-environment))
  3914. (pos (with-current-buffer (tramp-get-connection-buffer vec) (point))))
  3915. ;; If too much time has passed since last command was sent, look
  3916. ;; whether process is still alive. If it isn't, kill it. When
  3917. ;; using ssh, it can sometimes happen that the remote end has
  3918. ;; hung up but the local ssh client doesn't recognize this until
  3919. ;; it tries to send some data to the remote end. So that's why
  3920. ;; we try to send a command from time to time, then look again
  3921. ;; whether the process is really alive.
  3922. (condition-case nil
  3923. (when (and (> (tramp-time-diff
  3924. (current-time)
  3925. (tramp-get-connection-property
  3926. p "last-cmd-time" '(0 0 0)))
  3927. 60)
  3928. p (processp p) (memq (process-status p) '(run open)))
  3929. (tramp-send-command vec "echo are you awake" t t)
  3930. (unless (and (memq (process-status p) '(run open))
  3931. (tramp-wait-for-output p 10))
  3932. ;; The error will be caught locally.
  3933. (tramp-error vec 'file-error "Awake did fail")))
  3934. (file-error
  3935. (tramp-flush-connection-property vec)
  3936. (tramp-flush-connection-property p)
  3937. (delete-process p)
  3938. (setq p nil)))
  3939. ;; New connection must be opened.
  3940. (condition-case err
  3941. (unless (and p (processp p) (memq (process-status p) '(run open)))
  3942. ;; We call `tramp-get-buffer' in order to get a debug
  3943. ;; buffer for messages from the beginning.
  3944. (tramp-get-buffer vec)
  3945. (tramp-with-progress-reporter
  3946. vec 3
  3947. (if (zerop (length (tramp-file-name-user vec)))
  3948. (format "Opening connection for %s using %s"
  3949. (tramp-file-name-host vec)
  3950. (tramp-file-name-method vec))
  3951. (format "Opening connection for %s@%s using %s"
  3952. (tramp-file-name-user vec)
  3953. (tramp-file-name-host vec)
  3954. (tramp-file-name-method vec)))
  3955. ;; Start new process.
  3956. (when (and p (processp p))
  3957. (delete-process p))
  3958. (setenv "TERM" tramp-terminal-type)
  3959. (setenv "LC_ALL" "C")
  3960. (setenv "PROMPT_COMMAND")
  3961. (setenv "PS1" tramp-initial-end-of-output)
  3962. (let* ((target-alist (tramp-compute-multi-hops vec))
  3963. (process-connection-type tramp-process-connection-type)
  3964. (process-adaptive-read-buffering nil)
  3965. (coding-system-for-read nil)
  3966. ;; This must be done in order to avoid our file
  3967. ;; name handler.
  3968. (p (let ((default-directory
  3969. (tramp-compat-temporary-file-directory)))
  3970. (apply
  3971. 'start-process
  3972. (tramp-get-connection-name vec)
  3973. (tramp-get-connection-buffer vec)
  3974. (if tramp-encoding-command-interactive
  3975. (list tramp-encoding-shell
  3976. tramp-encoding-command-interactive)
  3977. (list tramp-encoding-shell))))))
  3978. ;; Set sentinel and query flag.
  3979. (tramp-set-connection-property p "vector" vec)
  3980. (set-process-sentinel p 'tramp-process-sentinel)
  3981. (tramp-compat-set-process-query-on-exit-flag p nil)
  3982. (tramp-message
  3983. vec 6 "%s" (mapconcat 'identity (process-command p) " "))
  3984. ;; Check whether process is alive.
  3985. (tramp-barf-if-no-shell-prompt
  3986. p 60
  3987. "Couldn't find local shell prompt %s" tramp-encoding-shell)
  3988. ;; Now do all the connections as specified.
  3989. (while target-alist
  3990. (let* ((hop (car target-alist))
  3991. (l-method (tramp-file-name-method hop))
  3992. (l-user (tramp-file-name-user hop))
  3993. (l-host (tramp-file-name-host hop))
  3994. (l-port nil)
  3995. (login-program
  3996. (tramp-get-method-parameter
  3997. l-method 'tramp-login-program))
  3998. (login-args
  3999. (tramp-get-method-parameter
  4000. l-method 'tramp-login-args))
  4001. (async-args
  4002. (tramp-get-method-parameter
  4003. l-method 'tramp-async-args))
  4004. (gw-args
  4005. (tramp-get-method-parameter l-method 'tramp-gw-args))
  4006. (gw (tramp-get-file-property hop "" "gateway" nil))
  4007. (g-method (and gw (tramp-file-name-method gw)))
  4008. (g-user (and gw (tramp-file-name-user gw)))
  4009. (g-host (and gw (tramp-file-name-real-host gw)))
  4010. (command login-program)
  4011. ;; We don't create the temporary file. In
  4012. ;; fact, it is just a prefix for the
  4013. ;; ControlPath option of ssh; the real
  4014. ;; temporary file has another name, and it is
  4015. ;; created and protected by ssh. It is also
  4016. ;; removed by ssh when the connection is
  4017. ;; closed.
  4018. (tmpfile
  4019. (tramp-set-connection-property
  4020. p "temp-file"
  4021. (make-temp-name
  4022. (expand-file-name
  4023. tramp-temp-name-prefix
  4024. (tramp-compat-temporary-file-directory)))))
  4025. spec)
  4026. ;; Add arguments for asynchronous processes.
  4027. (when (and process-name async-args)
  4028. (setq login-args (append async-args login-args)))
  4029. ;; Add gateway arguments if necessary.
  4030. (when (and gw gw-args)
  4031. (setq login-args (append gw-args login-args)))
  4032. ;; Check for port number. Until now, there's no
  4033. ;; need for handling like method, user, host.
  4034. (when (string-match tramp-host-with-port-regexp l-host)
  4035. (setq l-port (match-string 2 l-host)
  4036. l-host (match-string 1 l-host)))
  4037. ;; Set variables for computing the prompt for
  4038. ;; reading password. They can also be derived
  4039. ;; from a gateway.
  4040. (setq tramp-current-method (or g-method l-method)
  4041. tramp-current-user (or g-user l-user)
  4042. tramp-current-host (or g-host l-host))
  4043. ;; Replace login-args place holders.
  4044. (setq
  4045. l-host (or l-host "")
  4046. l-user (or l-user "")
  4047. l-port (or l-port "")
  4048. spec (format-spec-make
  4049. ?h l-host ?u l-user ?p l-port ?t tmpfile)
  4050. command
  4051. (concat
  4052. ;; We do not want to see the trailing local
  4053. ;; prompt in `start-file-process'.
  4054. (unless (memq system-type '(windows-nt)) "exec ")
  4055. command " "
  4056. (mapconcat
  4057. (lambda (x)
  4058. (setq x (mapcar (lambda (y) (format-spec y spec)) x))
  4059. (unless (member "" x) (mapconcat 'identity x " ")))
  4060. login-args " ")
  4061. ;; Local shell could be a Windows COMSPEC. It
  4062. ;; doesn't know the ";" syntax, but we must exit
  4063. ;; always for `start-file-process'. "exec" does
  4064. ;; not work either.
  4065. (if (memq system-type '(windows-nt)) " && exit || exit")))
  4066. ;; Send the command.
  4067. (tramp-message vec 3 "Sending command `%s'" command)
  4068. (tramp-send-command vec command t t)
  4069. (tramp-process-actions
  4070. p vec pos tramp-actions-before-shell 60)
  4071. (tramp-message
  4072. vec 3 "Found remote shell prompt on `%s'" l-host))
  4073. ;; Next hop.
  4074. (setq target-alist (cdr target-alist)))
  4075. ;; Make initial shell settings.
  4076. (tramp-open-connection-setup-interactive-shell p vec))))
  4077. ;; When the user did interrupt, we must cleanup.
  4078. (quit
  4079. (let ((p (tramp-get-connection-process vec)))
  4080. (when (and p (processp p))
  4081. (tramp-flush-connection-property vec)
  4082. (tramp-flush-connection-property p)
  4083. (delete-process p)))
  4084. ;; Propagate the quit signal.
  4085. (signal (car err) (cdr err)))))))
  4086. (defun tramp-send-command (vec command &optional neveropen nooutput)
  4087. "Send the COMMAND to connection VEC.
  4088. Erases temporary buffer before sending the command. If optional
  4089. arg NEVEROPEN is non-nil, never try to open the connection. This
  4090. is meant to be used from `tramp-maybe-open-connection' only. The
  4091. function waits for output unless NOOUTPUT is set."
  4092. (unless neveropen (tramp-maybe-open-connection vec))
  4093. (let ((p (tramp-get-connection-process vec)))
  4094. (when (tramp-get-connection-property p "remote-echo" nil)
  4095. ;; We mark the command string that it can be erased in the output buffer.
  4096. (tramp-set-connection-property p "check-remote-echo" t)
  4097. (setq command (format "%s%s%s" tramp-echo-mark command tramp-echo-mark)))
  4098. (when (and (string-match "<<'EOF'" command)
  4099. (not (tramp-get-connection-property vec "busybox" nil)))
  4100. ;; Unset $PS1 when using here documents, in order to avoid
  4101. ;; multiple prompts.
  4102. (setq command (concat "(PS1= ; " command "\n)")))
  4103. ;; Send the command.
  4104. (tramp-message vec 6 "%s" command)
  4105. (tramp-send-string vec command)
  4106. (unless nooutput (tramp-wait-for-output p))))
  4107. (defun tramp-wait-for-output (proc &optional timeout)
  4108. "Wait for output from remote command."
  4109. (unless (buffer-live-p (process-buffer proc))
  4110. (delete-process proc)
  4111. (tramp-error proc 'file-error "Process `%s' not available, try again" proc))
  4112. (with-current-buffer (process-buffer proc)
  4113. (let* (;; Initially, `tramp-end-of-output' is "#$ ". There might
  4114. ;; be leading escape sequences, which must be ignored.
  4115. (regexp (format "[^#$\n]*%s\r?$" (regexp-quote tramp-end-of-output)))
  4116. ;; Sometimes, the commands do not return a newline but a
  4117. ;; null byte before the shell prompt, for example "git
  4118. ;; ls-files -c -z ...".
  4119. (regexp1 (format "\\(^\\|\000\\)%s" regexp))
  4120. (found (tramp-wait-for-regexp proc timeout regexp1)))
  4121. (if found
  4122. (let (buffer-read-only)
  4123. ;; A simple-minded busybox has sent " ^H" sequences.
  4124. ;; Delete them.
  4125. (goto-char (point-min))
  4126. (when (re-search-forward "^\\(.\b\\)+$" (point-at-eol) t)
  4127. (forward-line 1)
  4128. (delete-region (point-min) (point)))
  4129. ;; Delete the prompt.
  4130. (goto-char (point-max))
  4131. (re-search-backward regexp nil t)
  4132. (delete-region (point) (point-max)))
  4133. (if timeout
  4134. (tramp-error
  4135. proc 'file-error
  4136. "[[Remote prompt `%s' not found in %d secs]]"
  4137. tramp-end-of-output timeout)
  4138. (tramp-error
  4139. proc 'file-error
  4140. "[[Remote prompt `%s' not found]]" tramp-end-of-output)))
  4141. ;; Return value is whether end-of-output sentinel was found.
  4142. found)))
  4143. (defun tramp-send-command-and-check
  4144. (vec command &optional subshell dont-suppress-err)
  4145. "Run COMMAND and check its exit status.
  4146. Sends `echo $?' along with the COMMAND for checking the exit status. If
  4147. COMMAND is nil, just sends `echo $?'. Returns the exit status found.
  4148. If the optional argument SUBSHELL is non-nil, the command is
  4149. executed in a subshell, ie surrounded by parentheses. If
  4150. DONT-SUPPRESS-ERR is non-nil, stderr won't be sent to /dev/null."
  4151. (tramp-send-command
  4152. vec
  4153. (concat (if subshell "( " "")
  4154. command
  4155. (if command (if dont-suppress-err "; " " 2>/dev/null; ") "")
  4156. "echo tramp_exit_status $?"
  4157. (if subshell " )" "")))
  4158. (with-current-buffer (tramp-get-connection-buffer vec)
  4159. (goto-char (point-max))
  4160. (unless (re-search-backward "tramp_exit_status [0-9]+" nil t)
  4161. (tramp-error
  4162. vec 'file-error "Couldn't find exit status of `%s'" command))
  4163. (skip-chars-forward "^ ")
  4164. (prog1
  4165. (zerop (read (current-buffer)))
  4166. (let (buffer-read-only)
  4167. (delete-region (match-beginning 0) (point-max))))))
  4168. (defun tramp-barf-unless-okay (vec command fmt &rest args)
  4169. "Run COMMAND, check exit status, throw error if exit status not okay.
  4170. Similar to `tramp-send-command-and-check' but accepts two more arguments
  4171. FMT and ARGS which are passed to `error'."
  4172. (or (tramp-send-command-and-check vec command)
  4173. (apply 'tramp-error vec 'file-error fmt args)))
  4174. (defun tramp-send-command-and-read (vec command &optional noerror)
  4175. "Run COMMAND and return the output, which must be a Lisp expression.
  4176. In case there is no valid Lisp expression and NOERROR is nil, it
  4177. raises an error."
  4178. (when (if noerror
  4179. (tramp-send-command-and-check vec command)
  4180. (tramp-barf-unless-okay
  4181. vec command "`%s' returns with error" command))
  4182. (with-current-buffer (tramp-get-connection-buffer vec)
  4183. ;; Read the expression.
  4184. (goto-char (point-min))
  4185. (condition-case nil
  4186. (prog1 (read (current-buffer))
  4187. ;; Error handling.
  4188. (when (re-search-forward "\\S-" (point-at-eol) t)
  4189. (error nil)))
  4190. (error (unless noerror
  4191. (tramp-error
  4192. vec 'file-error
  4193. "`%s' does not return a valid Lisp expression: `%s'"
  4194. command (buffer-string))))))))
  4195. (defun tramp-convert-file-attributes (vec attr)
  4196. "Convert file-attributes ATTR generated by perl script, stat or ls.
  4197. Convert file mode bits to string and set virtual device number.
  4198. Return ATTR."
  4199. (when attr
  4200. ;; Remove color escape sequences from symlink.
  4201. (when (stringp (car attr))
  4202. (while (string-match tramp-color-escape-sequence-regexp (car attr))
  4203. (setcar attr (replace-match "" nil nil (car attr)))))
  4204. ;; Convert last access time.
  4205. (unless (listp (nth 4 attr))
  4206. (setcar (nthcdr 4 attr)
  4207. (list (floor (nth 4 attr) 65536)
  4208. (floor (mod (nth 4 attr) 65536)))))
  4209. ;; Convert last modification time.
  4210. (unless (listp (nth 5 attr))
  4211. (setcar (nthcdr 5 attr)
  4212. (list (floor (nth 5 attr) 65536)
  4213. (floor (mod (nth 5 attr) 65536)))))
  4214. ;; Convert last status change time.
  4215. (unless (listp (nth 6 attr))
  4216. (setcar (nthcdr 6 attr)
  4217. (list (floor (nth 6 attr) 65536)
  4218. (floor (mod (nth 6 attr) 65536)))))
  4219. ;; Convert file size.
  4220. (when (< (nth 7 attr) 0)
  4221. (setcar (nthcdr 7 attr) -1))
  4222. (when (and (floatp (nth 7 attr))
  4223. (<= (nth 7 attr) (tramp-compat-most-positive-fixnum)))
  4224. (setcar (nthcdr 7 attr) (round (nth 7 attr))))
  4225. ;; Convert file mode bits to string.
  4226. (unless (stringp (nth 8 attr))
  4227. (setcar (nthcdr 8 attr) (tramp-file-mode-from-int (nth 8 attr)))
  4228. (when (stringp (car attr))
  4229. (aset (nth 8 attr) 0 ?l)))
  4230. ;; Convert directory indication bit.
  4231. (when (string-match "^d" (nth 8 attr))
  4232. (setcar attr t))
  4233. ;; Convert symlink from `tramp-do-file-attributes-with-stat'.
  4234. (when (consp (car attr))
  4235. (if (and (stringp (caar attr))
  4236. (string-match ".+ -> .\\(.+\\)." (caar attr)))
  4237. (setcar attr (match-string 1 (caar attr)))
  4238. (setcar attr nil)))
  4239. ;; Set file's gid change bit.
  4240. (setcar (nthcdr 9 attr)
  4241. (if (numberp (nth 3 attr))
  4242. (not (= (nth 3 attr)
  4243. (tramp-get-remote-gid vec 'integer)))
  4244. (not (string-equal
  4245. (nth 3 attr)
  4246. (tramp-get-remote-gid vec 'string)))))
  4247. ;; Convert inode.
  4248. (unless (listp (nth 10 attr))
  4249. (setcar (nthcdr 10 attr)
  4250. (condition-case nil
  4251. (cons (floor (nth 10 attr) 65536)
  4252. (floor (mod (nth 10 attr) 65536)))
  4253. ;; Inodes can be incredible huge. We must hide this.
  4254. (error (tramp-get-inode vec)))))
  4255. ;; Set virtual device number.
  4256. (setcar (nthcdr 11 attr)
  4257. (tramp-get-device vec))
  4258. attr))
  4259. (defun tramp-check-cached-permissions (vec access)
  4260. "Check `file-attributes' caches for VEC.
  4261. Return t if according to the cache access type ACCESS is known to
  4262. be granted."
  4263. (let ((result nil)
  4264. (offset (cond
  4265. ((eq ?r access) 1)
  4266. ((eq ?w access) 2)
  4267. ((eq ?x access) 3))))
  4268. (dolist (suffix '("string" "integer") result)
  4269. (setq
  4270. result
  4271. (or
  4272. result
  4273. (let ((file-attr
  4274. (tramp-get-file-property
  4275. vec (tramp-file-name-localname vec)
  4276. (concat "file-attributes-" suffix) nil))
  4277. (remote-uid
  4278. (tramp-get-connection-property
  4279. vec (concat "uid-" suffix) nil))
  4280. (remote-gid
  4281. (tramp-get-connection-property
  4282. vec (concat "gid-" suffix) nil)))
  4283. (and
  4284. file-attr
  4285. (or
  4286. ;; Not a symlink
  4287. (eq t (car file-attr))
  4288. (null (car file-attr)))
  4289. (or
  4290. ;; World accessible.
  4291. (eq access (aref (nth 8 file-attr) (+ offset 6)))
  4292. ;; User accessible and owned by user.
  4293. (and
  4294. (eq access (aref (nth 8 file-attr) offset))
  4295. (equal remote-uid (nth 2 file-attr)))
  4296. ;; Group accessible and owned by user's
  4297. ;; principal group.
  4298. (and
  4299. (eq access (aref (nth 8 file-attr) (+ offset 3)))
  4300. (equal remote-gid (nth 3 file-attr)))))))))))
  4301. (defun tramp-file-mode-from-int (mode)
  4302. "Turn an integer representing a file mode into an ls(1)-like string."
  4303. (let ((type (cdr
  4304. (assoc (logand (lsh mode -12) 15) tramp-file-mode-type-map)))
  4305. (user (logand (lsh mode -6) 7))
  4306. (group (logand (lsh mode -3) 7))
  4307. (other (logand (lsh mode -0) 7))
  4308. (suid (> (logand (lsh mode -9) 4) 0))
  4309. (sgid (> (logand (lsh mode -9) 2) 0))
  4310. (sticky (> (logand (lsh mode -9) 1) 0)))
  4311. (setq user (tramp-file-mode-permissions user suid "s"))
  4312. (setq group (tramp-file-mode-permissions group sgid "s"))
  4313. (setq other (tramp-file-mode-permissions other sticky "t"))
  4314. (concat type user group other)))
  4315. (defun tramp-file-mode-permissions (perm suid suid-text)
  4316. "Convert a permission bitset into a string.
  4317. This is used internally by `tramp-file-mode-from-int'."
  4318. (let ((r (> (logand perm 4) 0))
  4319. (w (> (logand perm 2) 0))
  4320. (x (> (logand perm 1) 0)))
  4321. (concat (or (and r "r") "-")
  4322. (or (and w "w") "-")
  4323. (or (and suid x suid-text) ; suid, execute
  4324. (and suid (upcase suid-text)) ; suid, !execute
  4325. (and x "x") "-")))) ; !suid
  4326. (defun tramp-shell-case-fold (string)
  4327. "Converts STRING to shell glob pattern which ignores case."
  4328. (mapconcat
  4329. (lambda (c)
  4330. (if (equal (downcase c) (upcase c))
  4331. (vector c)
  4332. (format "[%c%c]" (downcase c) (upcase c))))
  4333. string
  4334. ""))
  4335. (defun tramp-make-copy-program-file-name (vec)
  4336. "Create a file name suitable to be passed to `rcp' and workalikes."
  4337. (let ((user (tramp-file-name-user vec))
  4338. (host (tramp-file-name-real-host vec))
  4339. (localname (tramp-shell-quote-argument
  4340. (tramp-file-name-localname vec))))
  4341. (if (not (zerop (length user)))
  4342. (format "%s@%s:%s" user host localname)
  4343. (format "%s:%s" host localname))))
  4344. (defun tramp-method-out-of-band-p (vec size)
  4345. "Return t if this is an out-of-band method, nil otherwise."
  4346. (and
  4347. ;; It shall be an out-of-band method.
  4348. (tramp-get-method-parameter (tramp-file-name-method vec) 'tramp-copy-program)
  4349. ;; There must be a size, otherwise the file doesn't exist.
  4350. (numberp size)
  4351. ;; Either the file size is large enough, or (in rare cases) there
  4352. ;; does not exist a remote encoding.
  4353. (or (null tramp-copy-size-limit)
  4354. (> size tramp-copy-size-limit)
  4355. (null (tramp-get-inline-coding vec "remote-encoding" size)))))
  4356. ;; Variables local to connection.
  4357. (defun tramp-get-remote-path (vec)
  4358. (with-connection-property
  4359. ;; When `tramp-own-remote-path' is in `tramp-remote-path', we
  4360. ;; cache the result for the session only. Otherwise, the result
  4361. ;; is cached persistently.
  4362. (if (memq 'tramp-own-remote-path tramp-remote-path)
  4363. (tramp-get-connection-process vec)
  4364. vec)
  4365. "remote-path"
  4366. (let* ((remote-path (copy-tree tramp-remote-path))
  4367. (elt1 (memq 'tramp-default-remote-path remote-path))
  4368. (elt2 (memq 'tramp-own-remote-path remote-path))
  4369. (default-remote-path
  4370. (when elt1
  4371. (or
  4372. (tramp-send-command-and-read
  4373. vec "echo \\\"`getconf PATH 2>/dev/null`\\\"" 'noerror)
  4374. ;; Default if "getconf" is not available.
  4375. (progn
  4376. (tramp-message
  4377. vec 3
  4378. "`getconf PATH' not successful, using default value \"%s\"."
  4379. "/bin:/usr/bin")
  4380. "/bin:/usr/bin"))))
  4381. (own-remote-path
  4382. (when elt2
  4383. (condition-case nil
  4384. (tramp-send-command-and-read vec "echo \\\"$PATH\\\"")
  4385. (error
  4386. (tramp-message
  4387. vec 3 "$PATH not set, ignoring `tramp-own-remote-path'.")
  4388. nil)))))
  4389. ;; Replace place holder `tramp-default-remote-path'.
  4390. (when elt1
  4391. (setcdr elt1
  4392. (append
  4393. (tramp-compat-split-string default-remote-path ":")
  4394. (cdr elt1)))
  4395. (setq remote-path (delq 'tramp-default-remote-path remote-path)))
  4396. ;; Replace place holder `tramp-own-remote-path'.
  4397. (when elt2
  4398. (setcdr elt2
  4399. (append
  4400. (tramp-compat-split-string own-remote-path ":")
  4401. (cdr elt2)))
  4402. (setq remote-path (delq 'tramp-own-remote-path remote-path)))
  4403. ;; Remove double entries.
  4404. (setq elt1 remote-path)
  4405. (while (consp elt1)
  4406. (while (and (car elt1) (setq elt2 (member (car elt1) (cdr elt1))))
  4407. (setcar elt2 nil))
  4408. (setq elt1 (cdr elt1)))
  4409. ;; Remove non-existing directories.
  4410. (delq
  4411. nil
  4412. (mapcar
  4413. (lambda (x)
  4414. (and
  4415. (stringp x)
  4416. (file-directory-p
  4417. (tramp-make-tramp-file-name
  4418. (tramp-file-name-method vec)
  4419. (tramp-file-name-user vec)
  4420. (tramp-file-name-host vec)
  4421. x))
  4422. x))
  4423. remote-path)))))
  4424. (defun tramp-get-ls-command (vec)
  4425. (with-connection-property vec "ls"
  4426. (tramp-message vec 5 "Finding a suitable `ls' command")
  4427. (or
  4428. (catch 'ls-found
  4429. (dolist (cmd '("ls" "gnuls" "gls"))
  4430. (let ((dl (tramp-get-remote-path vec))
  4431. result)
  4432. (while (and dl (setq result (tramp-find-executable vec cmd dl t t)))
  4433. ;; Check parameters. On busybox, "ls" output coloring is
  4434. ;; enabled by default sometimes. So we try to disable it
  4435. ;; when possible. $LS_COLORING is not supported there.
  4436. ;; Some "ls" versions are sensible wrt the order of
  4437. ;; arguments, they fail when "-al" is after the
  4438. ;; "--color=never" argument (for example on FreeBSD).
  4439. (when (tramp-send-command-and-check
  4440. vec (format "%s -lnd /" result))
  4441. (when (tramp-send-command-and-check
  4442. vec (format
  4443. "%s --color=never -al /dev/null" result))
  4444. (setq result (concat result " --color=never")))
  4445. (throw 'ls-found result))
  4446. (setq dl (cdr dl))))))
  4447. (tramp-error vec 'file-error "Couldn't find a proper `ls' command"))))
  4448. (defun tramp-get-ls-command-with-dired (vec)
  4449. (save-match-data
  4450. (with-connection-property vec "ls-dired"
  4451. (tramp-message vec 5 "Checking, whether `ls --dired' works")
  4452. ;; Some "ls" versions are sensible wrt the order of arguments,
  4453. ;; they fail when "-al" is after the "--dired" argument (for
  4454. ;; example on FreeBSD).
  4455. (tramp-send-command-and-check
  4456. vec (format "%s --dired -al /dev/null" (tramp-get-ls-command vec))))))
  4457. (defun tramp-get-test-command (vec)
  4458. (with-connection-property vec "test"
  4459. (tramp-message vec 5 "Finding a suitable `test' command")
  4460. (if (tramp-send-command-and-check vec "test 0")
  4461. "test"
  4462. (tramp-find-executable vec "test" (tramp-get-remote-path vec)))))
  4463. (defun tramp-get-test-nt-command (vec)
  4464. ;; Does `test A -nt B' work? Use abominable `find' construct if it
  4465. ;; doesn't. BSD/OS 4.0 wants the parentheses around the command,
  4466. ;; for otherwise the shell crashes.
  4467. (with-connection-property vec "test-nt"
  4468. (or
  4469. (progn
  4470. (tramp-send-command
  4471. vec (format "( %s / -nt / )" (tramp-get-test-command vec)))
  4472. (with-current-buffer (tramp-get-buffer vec)
  4473. (goto-char (point-min))
  4474. (when (looking-at (regexp-quote tramp-end-of-output))
  4475. (format "%s %%s -nt %%s" (tramp-get-test-command vec)))))
  4476. (progn
  4477. (tramp-send-command
  4478. vec
  4479. (format
  4480. "tramp_test_nt () {\n%s -n \"`find $1 -prune -newer $2 -print`\"\n}"
  4481. (tramp-get-test-command vec)))
  4482. "tramp_test_nt %s %s"))))
  4483. (defun tramp-get-file-exists-command (vec)
  4484. (with-connection-property vec "file-exists"
  4485. (tramp-message vec 5 "Finding command to check if file exists")
  4486. (tramp-find-file-exists-command vec)))
  4487. (defun tramp-get-remote-ln (vec)
  4488. (with-connection-property vec "ln"
  4489. (tramp-message vec 5 "Finding a suitable `ln' command")
  4490. (tramp-find-executable vec "ln" (tramp-get-remote-path vec))))
  4491. (defun tramp-get-remote-perl (vec)
  4492. (with-connection-property vec "perl"
  4493. (tramp-message vec 5 "Finding a suitable `perl' command")
  4494. (let ((result
  4495. (or (tramp-find-executable vec "perl5" (tramp-get-remote-path vec))
  4496. (tramp-find-executable
  4497. vec "perl" (tramp-get-remote-path vec)))))
  4498. ;; We must check also for some Perl modules.
  4499. (when result
  4500. (with-connection-property vec "perl-file-spec"
  4501. (tramp-send-command-and-check
  4502. vec (format "%s -e 'use File::Spec;'" result)))
  4503. (with-connection-property vec "perl-cwd-realpath"
  4504. (tramp-send-command-and-check
  4505. vec (format "%s -e 'use Cwd \"realpath\";'" result))))
  4506. result)))
  4507. (defun tramp-get-remote-stat (vec)
  4508. (with-connection-property vec "stat"
  4509. (tramp-message vec 5 "Finding a suitable `stat' command")
  4510. (let ((result (tramp-find-executable
  4511. vec "stat" (tramp-get-remote-path vec)))
  4512. tmp)
  4513. ;; Check whether stat(1) returns usable syntax. "%s" does not
  4514. ;; work on older AIX systems.
  4515. (when result
  4516. (setq tmp
  4517. (tramp-send-command-and-read
  4518. vec (format "%s -c '(\"%%N\" %%s)' /" result) 'noerror))
  4519. (unless (and (listp tmp) (stringp (car tmp))
  4520. (string-match "^./.$" (car tmp))
  4521. (integerp (cadr tmp)))
  4522. (setq result nil)))
  4523. result)))
  4524. (defun tramp-get-remote-readlink (vec)
  4525. (with-connection-property vec "readlink"
  4526. (tramp-message vec 5 "Finding a suitable `readlink' command")
  4527. (let ((result (tramp-find-executable
  4528. vec "readlink" (tramp-get-remote-path vec))))
  4529. (when (and result
  4530. (tramp-send-command-and-check
  4531. vec (format "%s --canonicalize-missing /" result)))
  4532. result))))
  4533. (defun tramp-get-remote-trash (vec)
  4534. (with-connection-property vec "trash"
  4535. (tramp-message vec 5 "Finding a suitable `trash' command")
  4536. (tramp-find-executable vec "trash" (tramp-get-remote-path vec))))
  4537. (defun tramp-get-remote-id (vec)
  4538. (with-connection-property vec "id"
  4539. (tramp-message vec 5 "Finding POSIX `id' command")
  4540. (or
  4541. (catch 'id-found
  4542. (let ((dl (tramp-get-remote-path vec))
  4543. result)
  4544. (while (and dl (setq result (tramp-find-executable vec "id" dl t t)))
  4545. ;; Check POSIX parameter.
  4546. (when (tramp-send-command-and-check vec (format "%s -u" result))
  4547. (throw 'id-found result))
  4548. (setq dl (cdr dl)))))
  4549. (tramp-error vec 'file-error "Couldn't find a POSIX `id' command"))))
  4550. (defun tramp-get-remote-uid (vec id-format)
  4551. (with-connection-property vec (format "uid-%s" id-format)
  4552. (let ((res (tramp-send-command-and-read
  4553. vec
  4554. (format "%s -u%s %s"
  4555. (tramp-get-remote-id vec)
  4556. (if (equal id-format 'integer) "" "n")
  4557. (if (equal id-format 'integer)
  4558. "" "| sed -e s/^/\\\"/ -e s/\$/\\\"/")))))
  4559. ;; The command might not always return a number.
  4560. (if (and (equal id-format 'integer) (not (integerp res))) -1 res))))
  4561. (defun tramp-get-remote-gid (vec id-format)
  4562. (with-connection-property vec (format "gid-%s" id-format)
  4563. (let ((res (tramp-send-command-and-read
  4564. vec
  4565. (format "%s -g%s %s"
  4566. (tramp-get-remote-id vec)
  4567. (if (equal id-format 'integer) "" "n")
  4568. (if (equal id-format 'integer)
  4569. "" "| sed -e s/^/\\\"/ -e s/\$/\\\"/")))))
  4570. ;; The command might not always return a number.
  4571. (if (and (equal id-format 'integer) (not (integerp res))) -1 res))))
  4572. (defun tramp-get-local-uid (id-format)
  4573. (if (equal id-format 'integer) (user-uid) (user-login-name)))
  4574. (defun tramp-get-local-gid (id-format)
  4575. (nth 3 (tramp-compat-file-attributes "~/" id-format)))
  4576. ;; Some predefined connection properties.
  4577. (defun tramp-get-inline-compress (vec prop size)
  4578. "Return the compress command related to PROP.
  4579. PROP is either `inline-compress' or `inline-decompress'. SIZE is
  4580. the length of the file to be compressed.
  4581. If no corresponding command is found, nil is returned."
  4582. (when (and (integerp tramp-inline-compress-start-size)
  4583. (> size tramp-inline-compress-start-size))
  4584. (with-connection-property vec prop
  4585. (tramp-find-inline-compress vec)
  4586. (tramp-get-connection-property vec prop nil))))
  4587. (defun tramp-get-inline-coding (vec prop size)
  4588. "Return the coding command related to PROP.
  4589. PROP is either `remote-encoding', `remote-decoding',
  4590. `local-encoding' or `local-decoding'.
  4591. SIZE is the length of the file to be coded. Depending on SIZE,
  4592. compression might be applied.
  4593. If no corresponding command is found, nil is returned.
  4594. Otherwise, either a string is returned which contains a `%s' mark
  4595. to be used for the respective input or output file; or a Lisp
  4596. function cell is returned to be applied on a buffer."
  4597. ;; We must catch the errors, because we want to return `nil', when
  4598. ;; no inline coding is found.
  4599. (ignore-errors
  4600. (let ((coding
  4601. (with-connection-property vec prop
  4602. (tramp-find-inline-encoding vec)
  4603. (tramp-get-connection-property vec prop nil)))
  4604. (prop1 (if (string-match "encoding" prop)
  4605. "inline-compress" "inline-decompress"))
  4606. compress)
  4607. ;; The connection property might have been cached. So we must
  4608. ;; send the script to the remote side - maybe.
  4609. (when (and coding (symbolp coding) (string-match "remote" prop))
  4610. (let ((name (symbol-name coding)))
  4611. (while (string-match (regexp-quote "-") name)
  4612. (setq name (replace-match "_" nil t name)))
  4613. (tramp-maybe-send-script vec (symbol-value coding) name)
  4614. (setq coding name)))
  4615. (when coding
  4616. ;; Check for the `compress' command.
  4617. (setq compress (tramp-get-inline-compress vec prop1 size))
  4618. ;; Return the value.
  4619. (cond
  4620. ((and compress (symbolp coding))
  4621. (if (string-match "decompress" prop1)
  4622. `(lambda (beg end)
  4623. (,coding beg end)
  4624. (let ((coding-system-for-write 'binary)
  4625. (coding-system-for-read 'binary))
  4626. (apply
  4627. 'call-process-region (point-min) (point-max)
  4628. (car (split-string ,compress)) t t nil
  4629. (cdr (split-string ,compress)))))
  4630. `(lambda (beg end)
  4631. (let ((coding-system-for-write 'binary)
  4632. (coding-system-for-read 'binary))
  4633. (apply
  4634. 'call-process-region beg end
  4635. (car (split-string ,compress)) t t nil
  4636. (cdr (split-string ,compress))))
  4637. (,coding (point-min) (point-max)))))
  4638. ((symbolp coding)
  4639. coding)
  4640. ((and compress (string-match "decoding" prop))
  4641. (format
  4642. ;; Windows shells need the program file name after
  4643. ;; the pipe symbol be quoted if they use forward
  4644. ;; slashes as directory separators.
  4645. (if (and (string-match "local" prop)
  4646. (memq system-type '(windows-nt)))
  4647. "(%s | \"%s\" >%%s)"
  4648. "(%s | %s >%%s)")
  4649. coding compress))
  4650. (compress
  4651. (format
  4652. ;; Windows shells need the program file name after
  4653. ;; the pipe symbol be quoted if they use forward
  4654. ;; slashes as directory separators.
  4655. (if (and (string-match "local" prop)
  4656. (memq system-type '(windows-nt)))
  4657. "(%s <%%s | \"%s\")"
  4658. "(%s <%%s | %s)")
  4659. compress coding))
  4660. ((string-match "decoding" prop)
  4661. (format "%s >%%s" coding))
  4662. (t
  4663. (format "%s <%%s" coding)))))))
  4664. ;;; Integration of eshell.el:
  4665. (eval-when-compile
  4666. (defvar eshell-path-env))
  4667. ;; eshell.el keeps the path in `eshell-path-env'. We must change it
  4668. ;; when `default-directory' points to another host.
  4669. (defun tramp-eshell-directory-change ()
  4670. "Set `eshell-path-env' to $PATH of the host related to `default-directory'."
  4671. (setq eshell-path-env
  4672. (if (file-remote-p default-directory)
  4673. (with-parsed-tramp-file-name default-directory nil
  4674. (mapconcat
  4675. 'identity
  4676. (tramp-get-remote-path v)
  4677. ":"))
  4678. (getenv "PATH"))))
  4679. (eval-after-load "esh-util"
  4680. '(progn
  4681. (tramp-eshell-directory-change)
  4682. (add-hook 'eshell-directory-change-hook
  4683. 'tramp-eshell-directory-change)
  4684. (add-hook 'tramp-unload-hook
  4685. (lambda ()
  4686. (remove-hook 'eshell-directory-change-hook
  4687. 'tramp-eshell-directory-change)))))
  4688. (add-hook 'tramp-unload-hook
  4689. (lambda ()
  4690. (unload-feature 'tramp-sh 'force)))
  4691. (provide 'tramp-sh)
  4692. ;;; TODO:
  4693. ;; * Don't use globbing for directories with many files, as this is
  4694. ;; likely to produce long command lines, and some shells choke on
  4695. ;; long command lines.
  4696. ;; * Make it work for different encodings, and for different file name
  4697. ;; encodings, too. (Daniel Pittman)
  4698. ;; * Don't search for perl5 and perl. Instead, only search for perl and
  4699. ;; then look if it's the right version (with `perl -v').
  4700. ;; * When editing a remote CVS controlled file as a different user, VC
  4701. ;; gets confused about the file locking status. Try to find out why
  4702. ;; the workaround doesn't work.
  4703. ;; * Allow out-of-band methods as _last_ multi-hop. Open a connection
  4704. ;; until the last but one hop via `start-file-process'. Apply it
  4705. ;; also for ftp and smb.
  4706. ;; * WIBNI if we had a command "trampclient"? If I was editing in
  4707. ;; some shell with root privileges, it would be nice if I could
  4708. ;; just call
  4709. ;; trampclient filename.c
  4710. ;; as an editor, and the _current_ shell would connect to an Emacs
  4711. ;; server and would be used in an existing non-privileged Emacs
  4712. ;; session for doing the editing in question.
  4713. ;; That way, I need not tell Emacs my password again and be afraid
  4714. ;; that it makes it into core dumps or other ugly stuff (I had Emacs
  4715. ;; once display a just typed password in the context of a keyboard
  4716. ;; sequence prompt for a question immediately following in a shell
  4717. ;; script run within Emacs -- nasty).
  4718. ;; And if I have some ssh session running to a different computer,
  4719. ;; having the possibility of passing a local file there to a local
  4720. ;; Emacs session (in case I can arrange for a connection back) would
  4721. ;; be nice.
  4722. ;; Likely the corresponding Tramp server should not allow the
  4723. ;; equivalent of the emacsclient -eval option in order to make this
  4724. ;; reasonably unproblematic. And maybe trampclient should have some
  4725. ;; way of passing credentials, like by using an SSL socket or
  4726. ;; something. (David Kastrup)
  4727. ;; * Reconnect directly to a compliant shell without first going
  4728. ;; through the user's default shell. (Pete Forman)
  4729. ;; * How can I interrupt the remote process with a signal
  4730. ;; (interrupt-process seems not to work)? (Markus Triska)
  4731. ;; * Avoid the local shell entirely for starting remote processes. If
  4732. ;; so, I think even a signal, when delivered directly to the local
  4733. ;; SSH instance, would correctly be propagated to the remote process
  4734. ;; automatically; possibly SSH would have to be started with
  4735. ;; "-t". (Markus Triska)
  4736. ;; * It makes me wonder if tramp couldn't fall back to ssh when scp
  4737. ;; isn't on the remote host. (Mark A. Hershberger)
  4738. ;; * Use lsh instead of ssh. (Alfred M. Szmidt)
  4739. ;; * Optimize out-of-band copying when both methods are scp-like (not
  4740. ;; rsync).
  4741. ;; * Keep a second connection open for out-of-band methods like scp or
  4742. ;; rsync.
  4743. ;; * Try telnet+curl as new method. It might be useful for busybox,
  4744. ;; without built-in uuencode/uudecode.
  4745. ;;; tramp-sh.el ends here